re base code
Change-Id: I12a5ca14a6d8a87e9316b9ff362eb131105f98a5
Issue-ID: SDC-1566
Signed-off-by: Michael Lando <ml636r@att.com>
diff --git a/catalog-ui/src/app/app.ts b/catalog-ui/src/app/app.ts
index 723f244..67cf665 100644
--- a/catalog-ui/src/app/app.ts
+++ b/catalog-ui/src/app/app.ts
@@ -30,6 +30,7 @@
import './modules/directive-module.ts';
import './modules/service-module';
import './modules/view-model-module.ts';
+import {SdcUiComponentsNg1Module} from 'sdc-ui/lib/angular';
import {
DataTypesService,
@@ -45,14 +46,13 @@
import { UserService } from "./ng2/services/user.service";
import {forwardRef} from '@angular/core';
import {UpgradeAdapter} from '@angular/upgrade';
-import {CHANGE_COMPONENT_CSAR_VERSION_FLAG, States} from "./utils";
+import {CHANGE_COMPONENT_CSAR_VERSION_FLAG, States, PREVIOUS_CSAR_COMPONENT} from "./utils";
import {IAppConfigurtaion, IAppMenu, IMainCategory, Resource, IHostedApplication} from "./models";
import {ComponentFactory} from "./utils/component-factory";
import {ModalsHandler} from "./utils/modals-handler";
import {downgradeComponent} from "@angular/upgrade/static";
import {AppModule} from './ng2/app.module';
-import {PropertiesAssignmentComponent} from "./ng2/pages/properties-assignment/properties-assignment.page.component";
import {Component} from "./models/components/component";
import {ComponentServiceNg2} from "./ng2/services/component-services/component.service";
import {ComponentMetadata} from "./models/component-metadata";
@@ -100,6 +100,7 @@
'angular-clipboard',
'angularResizable',
'infinite-scroll',
+ SdcUiComponentsNg1Module.name,
viewModelsModuleName,
directivesModuleName,
servicesModuleName,
@@ -185,7 +186,7 @@
$stateProvider.state(
'dashboard', {
- url: '/dashboard?show&folder',
+ url: '/dashboard?show&folder&filter.term&filter.status&filter.distributed',
templateUrl: "./view-models/dashboard/dashboard-view.html",
controller: viewModelsModuleName + '.DashboardViewModel',
}
@@ -200,25 +201,60 @@
);
let componentsParam:Array<any> = ['$stateParams', 'Sdc.Services.EntityService', 'Sdc.Services.CacheService', ($stateParams:any, EntityService:EntityService, cacheService:CacheService) => {
- if (cacheService.get('breadcrumbsComponents')) {
- return cacheService.get('breadcrumbsComponents');
+ if (cacheService.get('breadcrumbsComponentsState') === $stateParams.previousState) {
+ const breadcrumbsComponents = cacheService.get('breadcrumbsComponents');
+ if (breadcrumbsComponents) {
+ return breadcrumbsComponents;
+ }
} else {
- return EntityService.getCatalog();
+ let breadcrumbsComponentsPromise;
+ if ($stateParams.previousState === 'dashboard') {
+ breadcrumbsComponentsPromise = EntityService.getAllComponents(true);
+ } else if ($stateParams.previousState === 'catalog') {
+ breadcrumbsComponentsPromise = EntityService.getCatalog();
+ } else {
+ cacheService.remove('breadcrumbsComponentsState');
+ cacheService.remove('breadcrumbsComponents');
+ return [];
+ }
+ breadcrumbsComponentsPromise.then((components) => {
+ cacheService.set('breadcrumbsComponentsState', $stateParams.previousState);
+ cacheService.set('breadcrumbsComponents', components);
+ });
+ return breadcrumbsComponentsPromise;
}
}];
+ const oldWorkspaceController:Array<any> = ['$location', ($location:ng.ILocationService) => {
+ // redirect old /workspace/* urls to /catalog/workspace/* url
+ const newUrl = '/catalog' + $location.url();
+ console.log('old workspace path - redirecting to:', newUrl);
+ $location.url(newUrl);
+ }];
+
+ $stateProvider.state(
+ 'workspace-old', {
+ url: '/workspace/:id/:type/*workspaceInnerPath',
+ controller: oldWorkspaceController
+ }
+ );
+
$stateProvider.state(
'workspace', {
- url: '/workspace/:id/:type/',
+ url: '/:previousState/workspace/:id/:type/',
params: {'importedFile': null, 'componentCsar': null, 'resourceType': null, 'disableButtons': null},
templateUrl: './view-models/workspace/workspace-view.html',
controller: viewModelsModuleName + '.WorkspaceViewModel',
resolve: {
- injectComponent: ['$stateParams', 'ComponentFactory', 'ComponentServiceNg2', function ($stateParams, ComponentFactory:ComponentFactory, ComponentServiceNg2:ComponentServiceNg2) {
- if ($stateParams.id) {
+ injectComponent: ['$stateParams', 'ComponentFactory', 'Sdc.Services.CacheService', 'ComponentServiceNg2', function ($stateParams, ComponentFactory:ComponentFactory, cacheService:CacheService, ComponentServiceNg2:ComponentServiceNg2) {
+
+ if ($stateParams.id && $stateParams.id.length) { //need to check length in case ID is an empty string
return ComponentFactory.getComponentWithMetadataFromServer($stateParams.type.toUpperCase(), $stateParams.id).then(
(component:Component)=> {
- if ($stateParams.componentCsar){
+ if ($stateParams.componentCsar && component.isResource()){
+ if((<Resource>component).csarVersion != $stateParams.componentCsar.csarVersion) {
+ cacheService.set(PREVIOUS_CSAR_COMPONENT, angular.copy(component));
+ }
component = ComponentFactory.updateComponentFromCsar($stateParams.componentCsar, <Resource>component);
}
return component;
@@ -258,7 +294,6 @@
parent: 'workspace',
controller: viewModelsModuleName + '.ActivityLogViewModel',
templateUrl: './view-models/workspace/tabs/activity-log/activity-log.html',
- data: {unsavedChanges: false}
}
);
@@ -569,7 +604,7 @@
$stateProvider.state(
'catalog', {
- url: '/catalog',
+ url: '/catalog?filter.components&filter.resourceSubTypes&filter.categories&filter.statuses&filter.order&filter.term&filter.active',
templateUrl: './view-models/catalog/catalog-view.html',
controller: viewModelsModuleName + '.CatalogViewModel',
resolve: {
@@ -619,6 +654,7 @@
ng1appModule.value('VendorReleaseValidationPattern', /^[\x20-\x21\x23-\x29\x2B-\x2E\x30-\x39\x3B\x3D\x40-\x5B\x5D-\x7B\x7D-\xFF]{1,25}$/);
ng1appModule.value('VendorNameValidationPattern', /^[\x20-\x21\x23-\x29\x2B-\x2E\x30-\x39\x3B\x3D\x40-\x5B\x5D-\x7B\x7D-\xFF]{1,60}$/);
ng1appModule.value('VendorModelNumberValidationPattern', /^[\x20-\x21\x23-\x29\x2B-\x2E\x30-\x39\x3B\x3D\x40-\x5B\x5D-\x7B\x7D-\xFF]{1,65}$/);
+ng1appModule.value('ServiceTypeAndRoleValidationPattern', /^[\x20-\x21\x23-\x29\x2B-\x2E\x30-\x39\x3B\x3D\x40-\x5B\x5D-\x7B\x7D-\xFF]{1,256}$/);
ng1appModule.value('ContactIdValidationPattern', /^[\s\w-]{1,50}$/);
ng1appModule.value('UserIdValidationPattern', /^[\s\w-]{1,50}$/);
ng1appModule.value('ProjectCodeValidationPattern', /^[\s\w-]{5,50}$/);
@@ -672,6 +708,7 @@
AngularJSBridge,
$templateCache:ng.ITemplateCacheService):void => {
$templateCache.put('notification-custom-template.html', require('./view-models/shared/notification-custom-template.html'));
+ $templateCache.put('notification-custom-template.html', require('./view-models/shared/notification-custom-template.html'));
//handle cache data - version
let initAsdcVersion:Function = ():void => {
@@ -846,6 +883,9 @@
if (cacheService.contains(CHANGE_COMPONENT_CSAR_VERSION_FLAG)) {
cacheService.remove(CHANGE_COMPONENT_CSAR_VERSION_FLAG);
}
+ if (cacheService.contains(PREVIOUS_CSAR_COMPONENT)){
+ cacheService.remove(PREVIOUS_CSAR_COMPONENT);
+ }
}
//set body class
diff --git a/catalog-ui/src/app/directives/elements/checkbox/checkbox.html b/catalog-ui/src/app/directives/elements/checkbox/checkbox.html
index 1e254081..e52f810 100644
--- a/catalog-ui/src/app/directives/elements/checkbox/checkbox.html
+++ b/catalog-ui/src/app/directives/elements/checkbox/checkbox.html
@@ -5,6 +5,7 @@
type="checkbox"
checked=""
ng-disabled="disabled"
+ ng-change="sdcCheckedChange({checked})"
checklist-model="sdcChecklistModel"
checklist-value="sdcChecklistValue"
checklist-change="sdcChecklistChange()"
diff --git a/catalog-ui/src/app/directives/elements/checkbox/checkbox.ts b/catalog-ui/src/app/directives/elements/checkbox/checkbox.ts
index 43a05e7..9b752ea 100644
--- a/catalog-ui/src/app/directives/elements/checkbox/checkbox.ts
+++ b/catalog-ui/src/app/directives/elements/checkbox/checkbox.ts
@@ -25,6 +25,8 @@
text:string;
sdcChecklistModel:any;
sdcChecklistValue:string;
+ sdcChecklistChange:Function;
+ sdcCheckedChange:Function;
disabled:boolean;
}
@@ -41,9 +43,10 @@
elemId: '@',
text: '@',
disabled: '=',
- sdcChecklistModel: '=',
- sdcChecklistValue: '=',
- sdcChecklistChange: '&'
+ sdcChecklistModel: '=?',
+ sdcChecklistValue: '=?',
+ sdcChecklistChange: '&?',
+ sdcCheckedChange: '&?'
};
template = ():string => {
diff --git a/catalog-ui/src/app/directives/file-upload/file-upload.ts b/catalog-ui/src/app/directives/file-upload/file-upload.ts
index 4902741..7d6667c 100644
--- a/catalog-ui/src/app/directives/file-upload/file-upload.ts
+++ b/catalog-ui/src/app/directives/file-upload/file-upload.ts
@@ -94,13 +94,13 @@
};
scope.onFileChange = ():void => {
+ if (scope.myFileModel || scope.fileModel) {
+ scope.fileModel = scope.myFileModel;
+ scope.formElement[scope.elementName].value = scope.myFileModel;
+ }
if (scope.onFileChangedInDirective) {
scope.onFileChangedInDirective();
}
- if (scope.myFileModel) {
- scope.fileModel = scope.myFileModel;
- scope.formElement[scope.elementName].$setValidity('required', true);
- }
};
scope.setEmptyError = (element):void => {
@@ -136,9 +136,10 @@
};
scope.cancel = ():void => {
- scope.fileModel.filename = '';
+ scope.myFileModel = new FileUploadModel();
scope.formElement[scope.elementName].$pristine;
scope.formElement[scope.elementName].$setValidity('required', false);
+ scope.onFileChange();
}
};
diff --git a/catalog-ui/src/app/directives/graphs-v2/common/style/component-instances-nodes-style.ts b/catalog-ui/src/app/directives/graphs-v2/common/style/component-instances-nodes-style.ts
index 596dcec..194845c 100644
--- a/catalog-ui/src/app/directives/graphs-v2/common/style/component-instances-nodes-style.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/common/style/component-instances-nodes-style.ts
@@ -22,6 +22,7 @@
import constant = require("lodash/constant");
import {ImagesUrl} from "app/utils/constants";
import {AngularJSBridge} from "app/services/angular-js-bridge-service";
+import { CanvasHandleTypes } from "app/utils";
/**
* Created by obarda on 12/18/2016.
*/
@@ -102,8 +103,10 @@
'background-image': 'data(img)',
'background-width': GraphUIObjects.SMALL_RESOURCE_WIDTH,
'background-height': GraphUIObjects.SMALL_RESOURCE_WIDTH,
- 'width': GraphUIObjects.SMALL_RESOURCE_WIDTH,
- 'height': GraphUIObjects.SMALL_RESOURCE_WIDTH,
+ 'width': GraphUIObjects.SMALL_RESOURCE_WIDTH + GraphUIObjects.HANDLE_SIZE,
+ 'height': GraphUIObjects.SMALL_RESOURCE_WIDTH + GraphUIObjects.HANDLE_SIZE/2,
+ 'background-position-x': GraphUIObjects.HANDLE_SIZE / 2,
+ 'background-position-y': GraphUIObjects.HANDLE_SIZE / 2,
'text-valign': 'bottom',
'text-halign': 'center',
'background-opacity': 0,
@@ -120,8 +123,10 @@
'background-image': 'data(img)',
'background-width': GraphUIObjects.SMALL_RESOURCE_WIDTH,
'background-height': GraphUIObjects.SMALL_RESOURCE_WIDTH,
- 'width': GraphUIObjects.SMALL_RESOURCE_WIDTH,
- 'height': GraphUIObjects.SMALL_RESOURCE_WIDTH,
+ 'background-position-x': GraphUIObjects.HANDLE_SIZE / 2,
+ 'background-position-y': GraphUIObjects.HANDLE_SIZE / 2,
+ 'width': GraphUIObjects.SMALL_RESOURCE_WIDTH + GraphUIObjects.HANDLE_SIZE,
+ 'height': GraphUIObjects.SMALL_RESOURCE_WIDTH + GraphUIObjects.HANDLE_SIZE / 2,
'text-valign': 'bottom',
'text-halign': 'center',
'background-opacity': 0,
@@ -167,6 +172,16 @@
}
},
{
+ selector: '.archived',
+ css: {
+ 'shape': 'rectangle',
+ 'background-image': (ele:Cy.Collection) => {
+ return ele.data().setArchivedImageBgStyle(ele, GraphUIObjects.NODE_OVERLAP_MIN_SIZE); //Change name to setArchivedImageBgStyle ??
+ },
+ "border-width": 0
+ }
+ },
+ {
selector: '.vl-link',
css: {
'width': 3,
@@ -222,7 +237,7 @@
css: {
'shape': 'rectangle',
'background-image': (ele:Cy.Collection) => {
- return ele.data().initUncertifiedImage(ele, GraphUIObjects.NODE_OVERLAP_MIN_SIZE)
+ return ele.data().setUncertifiedImageBgStyle(ele, GraphUIObjects.NODE_OVERLAP_MIN_SIZE);//Change name to setUncertifiedImageBgStyle??
},
"border-width": 0
}
@@ -256,8 +271,10 @@
'background-image': 'data(img)',
'background-width': GraphUIObjects.SMALL_RESOURCE_WIDTH,
'background-height': GraphUIObjects.SMALL_RESOURCE_WIDTH,
- 'width': GraphUIObjects.SMALL_RESOURCE_WIDTH,
- 'height': GraphUIObjects.SMALL_RESOURCE_WIDTH,
+ 'background-position-x': GraphUIObjects.HANDLE_SIZE / 2,
+ 'background-position-y': GraphUIObjects.HANDLE_SIZE / 2,
+ 'width': GraphUIObjects.SMALL_RESOURCE_WIDTH + GraphUIObjects.HANDLE_SIZE,
+ 'height': GraphUIObjects.SMALL_RESOURCE_WIDTH + GraphUIObjects.HANDLE_SIZE/2,
'text-valign': 'bottom',
'text-halign': 'center',
'background-opacity': 0,
@@ -268,52 +285,57 @@
]
}
- public static getBasicNodeHanlde = () => {
+ public static getAddEdgeHandle = () => {
return {
- positionX: "right",
- positionY: "top",
- offsetX: 15,
- offsetY: -20,
- color: "#27a337",
- type: "default",
+
single: false,
- nodeTypeNames: ["basic-node"],
+ type: CanvasHandleTypes.ADD_EDGE,
imageUrl: AngularJSBridge.getAngularConfig().imagesPath + ImagesUrl.CANVAS_PLUS_ICON,
+ lineColor: '#27a337',
lineWidth: 2,
lineStyle: 'dashed'
}
}
- public static getBasicSmallNodeHandle = () => {
+ public static getTagHandle = () => {
return {
- positionX: "right",
- positionY: "top",
- offsetX: 3,
- offsetY: -25,
- color: "#27a337",
- type: "default",
single: false,
- nodeTypeNames: ["basic-small-node"],
- imageUrl: AngularJSBridge.getAngularConfig().imagesPath + ImagesUrl.CANVAS_PLUS_ICON,
- lineWidth: 2,
- lineStyle: 'dashed'
- }
+ type: CanvasHandleTypes.TAG_AVAILABLE,
+ imageUrl: AngularJSBridge.getAngularConfig().imagesPath + ImagesUrl.CANVAS_TAG_ICON,
+ }
}
- public static getUcpeCpNodeHandle = () => {
+ public static getTaggedPolicyHandle = () => {
return {
- positionX: "center",
- positionY: "center",
- offsetX: -8,
- offsetY: -10,
- color: "#27a337",
- type: "default",
single: false,
- nodeTypeNames: ["ucpe-cp-node"],
- imageUrl: AngularJSBridge.getAngularConfig().imagesPath + ImagesUrl.CANVAS_PLUS_ICON,
- lineWidth: 2,
- lineStyle: 'dashed'
- }
+ type: CanvasHandleTypes.TAGGED_POLICY,
+ imageUrl: AngularJSBridge.getAngularConfig().imagesPath + ImagesUrl.CANVAS_POLICY_TAGGED_ICON,
+ }
}
+
+ public static getTaggedGroupHandle = () => {
+ return {
+ single: false,
+ type: CanvasHandleTypes.TAGGED_GROUP,
+ imageUrl: AngularJSBridge.getAngularConfig().imagesPath + ImagesUrl.CANVAS_GROUP_TAGGED_ICON,
+ }
+ }
+
+
+ // public static getUcpeCpNodeHandle = () => {
+ // return {
+ // positionX: "center",
+ // positionY: "center",
+ // offsetX: -8,
+ // offsetY: -10,
+ // color: "#27a337",
+ // type: "default",
+ // single: false,
+ // nodeTypeNames: ["ucpe-cp-node"],
+ // imageUrl: AngularJSBridge.getAngularConfig().imagesPath + ImagesUrl.CANVAS_PLUS_ICON,
+ // lineWidth: 2,
+ // lineStyle: 'dashed'
+ // }
+ // }
}
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.directive.ts b/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.directive.ts
index 2144ecf..e40792d 100644
--- a/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.directive.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.directive.ts
@@ -24,10 +24,7 @@
LinkMenu,
ComponentInstance,
LeftPaletteComponent,
- Capability,
- Requirement,
Relationship,
- PropertyModel,
Component,
Service,
ConnectRelationModel,
@@ -35,8 +32,7 @@
CompositionCiNodeVl,
ModalModel,
ButtonModel,
- NodesFactory/*,
- AssetPopoverObj*/,
+ NodesFactory,
Point
} from "app/models";
import {ComponentInstanceFactory, ComponentFactory, GRAPH_EVENTS, GraphColors} from "app/utils";
@@ -52,7 +48,6 @@
import {ComponentServiceNg2} from "../../../ng2/services/component-services/component.service";
import {ComponentGenericResponse} from "../../../ng2/services/responses/component-generic-response";
import {ModalService} from "../../../ng2/services/modal.service";
-
import {ConnectionWizardService} from "../../../ng2/pages/connection-wizard/connection-wizard.service";
import {StepModel} from "../../../models/wizard-step";
import {FromNodeStepComponent} from "app/ng2/pages/connection-wizard/from-node-step/from-node-step.component";
@@ -63,31 +58,40 @@
import {ComponentInstanceServiceNg2} from "../../../ng2/services/component-instance-services/component-instance.service";
import {EVENTS} from "../../../utils/constants";
import {PropertyBEModel} from "../../../models/properties-inputs/property-be-model";
-import {ComponentType} from "app/utils";
import {ForwardingPath} from "app/models/forwarding-path";
import {ServicePathGraphUtils} from "./utils/composition-graph-service-path-utils";
import {CompositionCiServicePathLink} from "app/models/graph/graph-links/composition-graph-links/composition-ci-service-path-link";
-import { ZoneConfig, ZoneInstanceConfig, ZoneInstanceMode } from "app/models/graph/zones/zone-child";
-import { PoliciesService } from "app/ng2/services/policies.service";
-import { PaletteAnimationComponent } from "app/ng2/components/ui/palette-animation/palette-animation.component";
-import { CompositionGraphZoneUtils } from "./utils/composition-graph-zone-utils";
-import {LeftPaletteMetadataTypes} from "../../../models/components/displayComponent";
+import {
+ ZoneInstance, ZoneInstanceMode, ZoneInstanceType,
+ ZoneInstanceAssignmentType
+} from "app/models/graph/zones/zone-instance";
+
+import {Zone} from "app/models/graph/zones/zone";
+import {CompositionGraphZoneUtils} from "./utils/composition-graph-zone-utils";
+import {UIZoneInstanceObject} from "../../../models/ui-models/ui-zone-instance-object";
+import {GroupInstance} from "../../../models/graph/zones/group-instance";
+import {PolicyInstance} from "../../../models/graph/zones/policy-instance";
export interface ICompositionGraphScope extends ng.IScope {
component:Component;
- isLoading: boolean;
- isViewOnly: boolean;
- withSidebar: boolean;
+ isLoading:boolean;
+ isViewOnly:boolean;
+ withSidebar:boolean;
//zones
newZoneInstance;
zoneTagMode:string;
- activeZoneInstance:ZoneInstanceConfig;
- zones:any;
- zoneInstanceModeChanged(newMode:ZoneInstanceMode, instance:ZoneInstanceConfig, zoneId:string);
+ activeZoneInstance:ZoneInstance;
+ zones:Array<Zone>;
+ zoneMinimizeToggle(zoneType:ZoneInstanceType):void;
+ zoneInstanceTagged(taggedInstance:ZoneInstance):void;
+ zoneInstanceModeChanged(newMode:ZoneInstanceMode, instance:ZoneInstance, zoneId:ZoneInstanceType);
+ unsetActiveZoneInstance():void;
clickOutsideZoneInstance():void;
+ zoneAssignmentSaveStart():void;
+ zoneAssignmentSaveComplete(success:boolean):void;
// Link menu - create link menu
relationMenuDirectiveObj:ConnectRelationModel;
@@ -98,7 +102,7 @@
//modify link menu - for now only delete menu
relationMenuTimeout:ng.IPromise<any>;
linkMenuObject:LinkMenu;
- isOnDrag: boolean;
+ isOnDrag:boolean;
//left palette functions callbacks
dropCallback(event:JQueryEventObject, ui:any):void;
@@ -111,24 +115,24 @@
hideRelationMenu();
//search,zoom in/out/all
- componentInstanceNames: Array<string>; //id, name
- zoom(zoomIn: boolean): void;
- zoomAll(nodes?:Cy.CollectionNodes): void;
- getAutoCompleteValues(searchTerm: string):void;
- highlightSearchMatches(searchTerm: string): void;
+ componentInstanceNames:Array<string>; //id, name
+ zoom(zoomIn:boolean):void;
+ zoomAllWithoutSidebar():void;
+ getAutoCompleteValues(searchTerm:string):void;
+ highlightSearchMatches(searchTerm:string):void;
canvasMenuProps:any;
- createOrUpdateServicePath(data: any):void;
+ createOrUpdateServicePath(data:any):void;
deletePathsOnCy():void;
- drawPathOnCy(data: ForwardingPath):void;
- selectedPathId: string;
+ drawPathOnCy(data:ForwardingPath):void;
+ selectedPathId:string;
/*//asset popover menu
- assetPopoverObj:AssetPopoverObj;
- assetPopoverOpen:boolean;
- hideAssetPopover():void;
- deleteNode(nodeId:string):void;*/
+ assetPopoverObj:AssetPopoverObj;
+ assetPopoverOpen:boolean;
+ hideAssetPopover():void;
+ deleteNode(nodeId:string):void;*/
}
export class CompositionGraph implements ng.IDirective {
@@ -153,12 +157,11 @@
private matchCapabilitiesRequirementsUtils:MatchCapabilitiesRequirementsUtils,
private CompositionGraphPaletteUtils:CompositionGraphPaletteUtils,
private compositionGraphZoneUtils:CompositionGraphZoneUtils,
- private ComponentServiceNg2: ComponentServiceNg2,
- private ModalServiceNg2: ModalService,
- private ConnectionWizardServiceNg2: ConnectionWizardService,
- private ComponentInstanceServiceNg2: ComponentInstanceServiceNg2,
- private servicePathGraphUtils: ServicePathGraphUtils,
- private policiesService:PoliciesService) {
+ private ComponentServiceNg2:ComponentServiceNg2,
+ private ModalServiceNg2:ModalService,
+ private ConnectionWizardServiceNg2:ConnectionWizardService,
+ private ComponentInstanceServiceNg2:ComponentInstanceServiceNg2,
+ private servicePathGraphUtils:ServicePathGraphUtils) {
}
@@ -173,14 +176,15 @@
link = (scope:ICompositionGraphScope, el:JQuery) => {
this.loadGraph(scope, el);
- if(scope.component.componentInstances && scope.component.componentInstancesRelations) {
- this.loadGraphData(scope);
- } else {
- //when we don't have the data we register to on graph load event
+ if (!scope.component.groupInstances || !scope.component.policies) {
this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_COMPOSITION_GRAPH_DATA_LOADED, () => {
this.loadGraphData(scope);
});
+ } else {
+ this.loadGraphData(scope);
}
+
+
scope.$on('$destroy', () => {
this._cy.destroy();
_.forEach(GRAPH_EVENTS, (event) => {
@@ -196,7 +200,10 @@
this.initGraphNodes(scope.component.componentInstances, scope.isViewOnly);
this.commonGraphUtils.initGraphLinks(this._cy, scope.component.componentInstancesRelations, scope.component.getRelationRequirementCapability.bind(scope.component));
this.commonGraphUtils.initUcpeChildren(this._cy);
- this.compositionGraphZoneUtils.initPolicyInstances(scope.zones.policy, scope.component.policies);
+ this.compositionGraphZoneUtils.initZoneInstances(scope.zones, scope.component);
+ setTimeout(() => {//Need settimeout so that angular canvas changes will take effect before resize & center
+ this.GeneralGraphUtils.zoomAllWithMax(this._cy, 1);
+ });
}
private loadGraph = (scope:ICompositionGraphScope, el:JQuery) => {
@@ -207,7 +214,6 @@
this.registerCytoscapeGraphEvents(scope);
this.registerCustomEvents(scope, el);
this.initViewMode(scope.isViewOnly);
-
};
private initGraph(graphEl:JQuery, isViewOnly:boolean) {
@@ -234,16 +240,26 @@
this._cy.off('drag');
this._cy.off('handlemouseout');
this._cy.off('handlemouseover');
+ this._cy.off('canvasredraw');
+ this._cy.off('handletagclick')
this._cy.edges().unselectify();
}
};
private registerCustomEvents(scope:ICompositionGraphScope, el:JQuery) {
+ this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_GROUP_INSTANCE_UPDATE, (groupInstance:GroupInstance) => {
+ this.compositionGraphZoneUtils.findAndUpdateZoneInstanceData(scope.zones, groupInstance);
+ this.GeneralGraphUtils.showGroupUpdateSuccess();
+ });
+
+ this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_POLICY_INSTANCE_UPDATE, (policyInstance: PolicyInstance) => {
+ this.compositionGraphZoneUtils.findAndUpdateZoneInstanceData(scope.zones, policyInstance);
+ this.GeneralGraphUtils.showPolicyUpdateSuccess();
+ });
+
this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_IN, (leftPaletteComponent:LeftPaletteComponent) => {
- if(scope.isOnDrag ||
- leftPaletteComponent.categoryType === LeftPaletteMetadataTypes.Group ||
- leftPaletteComponent.categoryType === LeftPaletteMetadataTypes.Policy) {
+ if (scope.isOnDrag) {
return;
}
@@ -264,47 +280,33 @@
//----------------------- ORIT TO FIX------------------------//
- this.ComponentServiceNg2.getCapabilitiesAndRequirements(leftPaletteComponent.componentType, leftPaletteComponent.uniqueId).subscribe((response: ComponentGenericResponse) => {
+ this.ComponentServiceNg2.getCapabilitiesAndRequirements(leftPaletteComponent.componentType, leftPaletteComponent.uniqueId).subscribe((response:ComponentGenericResponse) => {
- let component = this.ComponentFactory.createEmptyComponent(leftPaletteComponent.componentType);
- component.uniqueId = component.uniqueId;
- component.capabilities = response.capabilities;
- component.requirements = response.requirements;
- this.GeneralGraphUtils.componentRequirementsAndCapabilitiesCaching.setValue(leftPaletteComponent.uniqueId, component);
- let filteredNodesData = this.matchCapabilitiesRequirementsUtils.findMatchingNodes(component, nodesData, nodesLinks);
- this.matchCapabilitiesRequirementsUtils.fadeNonMachingComponents(filteredNodesData, nodesData, this._cy);
- this.matchCapabilitiesRequirementsUtils.highlightMatchingComponents(filteredNodesData, this._cy)
- });
+ let component = this.ComponentFactory.createEmptyComponent(leftPaletteComponent.componentType);
+ component.uniqueId = component.uniqueId;
+ component.capabilities = response.capabilities;
+ component.requirements = response.requirements;
+ this.GeneralGraphUtils.componentRequirementsAndCapabilitiesCaching.setValue(leftPaletteComponent.uniqueId, component);
+ });
});
- this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_ADD_COMPONENT_INSTANCE_ZONE_START, (component:Component, paletteComponent:LeftPaletteComponent, startPosition:Point) => {
+ this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_ADD_ZONE_INSTANCE_FROM_PALETTE, (component:Component, paletteComponent:LeftPaletteComponent, startPosition:Point) => {
+
+ let zoneType:ZoneInstanceType = this.compositionGraphZoneUtils.getZoneTypeForPaletteComponent(paletteComponent.categoryType);
+ this.compositionGraphZoneUtils.showZone(scope.zones[zoneType]);
+
this.LoaderService.showLoader('composition-graph');
-
- let zoneType:string = LeftPaletteMetadataTypes[paletteComponent.categoryType].toLowerCase();
- scope.zones[zoneType].showZone = true;
- if(scope.minifyZone) scope.minifyZone = false;
-
- this.policiesService.createPolicyInstance(component.componentType, component.uniqueId, paletteComponent.type).subscribe((newInstance)=>{
-
+ this.compositionGraphZoneUtils.createZoneInstanceFromLeftPalette(zoneType, component, paletteComponent.type).subscribe((zoneInstance:ZoneInstance) => {
this.LoaderService.hideLoader('composition-graph');
- scope.newZoneInstance = newInstance;
- this.compositionGraphZoneUtils.showAnimationToZone(startPosition, zoneType);
- }, (error) => {
+ this.compositionGraphZoneUtils.addInstanceToZone(scope.zones[zoneInstance.type], zoneInstance, true);
+ this.compositionGraphZoneUtils.createPaletteToZoneAnimation(startPosition, zoneType, zoneInstance);
+ }, (error)=> {
this.LoaderService.hideLoader('composition-graph');
});
});
- this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_FINISH_ANIMATION_ZONE, () => {
- if(scope.newZoneInstance){
- this.compositionGraphZoneUtils.addInstanceToZone(scope.zones['policy'], scope.newZoneInstance);
- }
- })
-
- this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_ZONE_SIZE_CHANGE, () => {
- scope.minifyZone = true;
- })
-
this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_OUT, () => {
+
this._cy.emit('hidehandles');
this.matchCapabilitiesRequirementsUtils.resetFadedNodes(this._cy);
});
@@ -334,14 +336,35 @@
this.NodesGraphUtils.deleteNode(this._cy, scope.component, nodeToDelete);
});
- this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_DELETE_MULTIPLE_COMPONENTS, () => {
+ this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_DELETE_ZONE_INSTANCE, (deletedInstance:UIZoneInstanceObject) => {
- this._cy.$('node:selected').each((i:number, node:Cy.CollectionNodes) => {
- this.NodesGraphUtils.deleteNode(this._cy, scope.component, node);
- });
-
+ if(deletedInstance.type === ZoneInstanceType.POLICY){
+ scope.component.policies = scope.component.policies.filter(policy => policy.uniqueId !== deletedInstance.uniqueId);
+ } else if (deletedInstance.type === ZoneInstanceType.GROUP) {
+ scope.component.groupInstances = scope.component.groupInstances.filter(group => group.uniqueId !== deletedInstance.uniqueId);
+ }
+ //remove it from zones
+ scope.zones[deletedInstance.type].removeInstance(deletedInstance.uniqueId);
+ if (deletedInstance.type === ZoneInstanceType.GROUP && !_.isEmpty(scope.zones[ZoneInstanceType.POLICY])) {
+ this.compositionGraphZoneUtils.updateTargetsOrMembersOnCanvasDelete(deletedInstance.uniqueId, [scope.zones[ZoneInstanceType.POLICY]], ZoneInstanceAssignmentType.GROUPS);
+ }
+ this.eventListenerService.notifyObservers(EVENTS.UPDATE_PANEL);
});
+ this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_DELETE_COMPONENT_INSTANCE_SUCCESS, (componentInstanceId:string)=> {
+ if (!_.isEmpty(scope.zones)) {
+ this.compositionGraphZoneUtils.updateTargetsOrMembersOnCanvasDelete(componentInstanceId, scope.zones, ZoneInstanceAssignmentType.COMPONENT_INSTANCES);
+ }
+ });
+ // not in use; commenting out
+ // this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_DELETE_MULTIPLE_COMPONENTS, () => {
+
+ // this._cy.$('node:selected').each((i:number, node:Cy.CollectionNodes) => {
+ // this.NodesGraphUtils.deleteNode(this._cy, scope.component, node);
+ // });
+
+ // });
+
this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_DELETE_EDGE, (releaseLoading:boolean, linksToDelete:Cy.CollectionEdges) => {
this.CompositionGraphLinkUtils.deleteLink(this._cy, scope.component, releaseLoading, linksToDelete);
});
@@ -375,8 +398,9 @@
this.loadGraphData(scope);
});
- scope.zoom = (zoomIn: boolean):void => {
- let currentZoom: number = this._cy.zoom();
+
+ scope.zoom = (zoomIn:boolean):void => {
+ let currentZoom:number = this._cy.zoom();
if (zoomIn) {
this.GeneralGraphUtils.zoomGraphTo(this._cy, currentZoom + .1);
} else {
@@ -384,37 +408,32 @@
}
}
- //Zooms to fit all of the nodes in the collection passed in. If no nodes are passed in, will zoom to fit all nodes on graph
- scope.zoomAll = (nodes?:Cy.CollectionNodes) => {
- if (!nodes || !nodes.length) {
- nodes = this._cy.nodes();
- }
-
+
+ scope.zoomAllWithoutSidebar = () => {
scope.withSidebar = false;
- this._cy.animate({
- fit: { eles: nodes, padding: 20 },
- center: { eles: nodes }
- }, { duration: 400 });
+ setTimeout(() => { //wait for sidebar changes to take effect before zooming
+ this.GeneralGraphUtils.zoomAll(this._cy);
+ });
};
- scope.getAutoCompleteValues = (searchTerm: string) => {
+ scope.getAutoCompleteValues = (searchTerm:string) => {
if (searchTerm.length > 1) { //US requirement: only display search results after 2nd letter typed.
- let nodes: Cy.CollectionNodes = this.NodesGraphUtils.getMatchingNodesByName(this._cy, searchTerm);
+ let nodes:Cy.CollectionNodes = this.NodesGraphUtils.getMatchingNodesByName(this._cy, searchTerm);
scope.componentInstanceNames = _.map(nodes, node => node.data('name'));
} else {
scope.componentInstanceNames = [];
}
};
- scope.highlightSearchMatches = (searchTerm: string) => {
+ scope.highlightSearchMatches = (searchTerm:string) => {
this.NodesGraphUtils.highlightMatchingNodesByName(this._cy, searchTerm);
- let matchingNodes: Cy.CollectionNodes = this.NodesGraphUtils.getMatchingNodesByName(this._cy, searchTerm);
- scope.zoomAll(matchingNodes);
+ let matchingNodes:Cy.CollectionNodes = this.NodesGraphUtils.getMatchingNodesByName(this._cy, searchTerm);
+ this.GeneralGraphUtils.zoomAll(this._cy, matchingNodes);
};
scope.saveChangedCapabilityProperties = ():Promise<PropertyBEModel[]> => {
return new Promise<PropertyBEModel[]>((resolve) => {
- const capabilityPropertiesBE: PropertyBEModel[] = this.ConnectionWizardServiceNg2.changedCapabilityProperties.map((prop) => {
+ const capabilityPropertiesBE:PropertyBEModel[] = this.ConnectionWizardServiceNg2.changedCapabilityProperties.map((prop) => {
prop.value = prop.getJSONValue();
const propBE = new PropertyBEModel(prop);
propBE.parentUniqueId = this.ConnectionWizardServiceNg2.selectedMatch.relationship.relation.capabilityOwnerId;
@@ -464,7 +483,7 @@
scope.deletePathsOnCy = () => {
this.servicePathGraphUtils.deletePathsFromGraph(this._cy, <Service> scope.component);
};
- scope.drawPathOnCy = (data: ForwardingPath) => {
+ scope.drawPathOnCy = (data:ForwardingPath) => {
this.servicePathGraphUtils.drawPath(this._cy, data, <Service> scope.component);
};
@@ -486,10 +505,14 @@
this.ConnectionWizardServiceNg2.selectedMatch.relationship = relationship;
const title = `Connection Properties`;
- const saveButton: ButtonModel = new ButtonModel('Save', 'blue', () => {
- scope.saveChangedCapabilityProperties().then(() => { this.ModalServiceNg2.closeCurrentModal(); })
+ const saveButton:ButtonModel = new ButtonModel('Save', 'blue', () => {
+ scope.saveChangedCapabilityProperties().then(() => {
+ this.ModalServiceNg2.closeCurrentModal();
+ })
});
- const cancelButton: ButtonModel = new ButtonModel('Cancel', 'white', () => { this.ModalServiceNg2.closeCurrentModal(); });
+ const cancelButton:ButtonModel = new ButtonModel('Cancel', 'white', () => {
+ this.ModalServiceNg2.closeCurrentModal();
+ });
const modal = new ModalModel('xl', title, '', [saveButton, cancelButton]);
const modalInstance = this.ModalServiceNg2.createCustomModal(modal);
this.ModalServiceNg2.addDynamicContentToModal(modalInstance, ConnectionPropertiesViewComponent);
@@ -500,7 +523,8 @@
this.ComponentInstanceServiceNg2.getInstanceCapabilityProperties(scope.component, linkData.target, capability)
.subscribe(() => {
resolve();
- }, (error) => {});
+ }, (error) => {
+ });
} else {
resolve();
}
@@ -508,7 +532,8 @@
this.ModalServiceNg2.addDynamicContentToModal(modalInstance, ConnectionPropertiesViewComponent);
})
- }, (error) => {});
+ }, (error) => {
+ });
};
scope.deleteRelation = (link:Cy.CollectionEdges) => {
@@ -523,20 +548,20 @@
};
/*
- scope.hideAssetPopover = ():void => {
+ scope.hideAssetPopover = ():void => {
- this.commonGraphUtils.safeApply(scope, () => {
- scope.assetPopoverOpen = false;
- scope.assetPopoverObj = null;
- });
- };
+ this.commonGraphUtils.safeApply(scope, () => {
+ scope.assetPopoverOpen = false;
+ scope.assetPopoverObj = null;
+ });
+ };
- scope.deleteNode = (nodeId:string):void => {
- if (!scope.isViewOnly) {
- this.NodesGraphUtils.confirmDeleteNode(nodeId, this._cy, scope.component);
- //scope.hideAssetPopover();
- }
- };*/
+ scope.deleteNode = (nodeId:string):void => {
+ if (!scope.isViewOnly) {
+ this.NodesGraphUtils.confirmDeleteNode(nodeId, this._cy, scope.component);
+ //scope.hideAssetPopover();
+ }
+ };*/
}
private registerCytoscapeGraphEvents(scope:ICompositionGraphScope) {
@@ -599,22 +624,30 @@
}
});
- /* this._cy.on('mouseover', 'node', (event:Cy.EventObject) => {
- if (!this._cy.scratch('_edge_editation_highlights')) {
- this.commonGraphUtils.safeApply(scope, () => {
- this.showNodePopoverMenu(scope, event.cyTarget[0]);
- });
- }
- });
+ /* this._cy.on('mouseover', 'node', (event:Cy.EventObject) => {
+ if (!this._cy.scratch('_edge_editation_highlights')) {
+ this.commonGraphUtils.safeApply(scope, () => {
+ this.showNodePopoverMenu(scope, event.cyTarget[0]);
+ });
+ }
+ });
- this._cy.on('mouseout', 'node', (event:Cy.EventObject) => {
- scope.hideAssetPopover();
- });*/
+ this._cy.on('mouseout', 'node', (event:Cy.EventObject) => {
+ scope.hideAssetPopover();
+ });*/
+
+
this._cy.on('handlemouseover', (event, payload) => {
if (payload.node.grabbed() || this._cy.scratch('_edge_editation_highlights') === true) { //no need to add opacity while we are dragging and hovering othe nodes- or if opacity was already calculated for these nodes
return;
}
+
+ if (scope.zoneTagMode) {
+ scope.zoneTagMode = scope.zones[scope.activeZoneInstance.type].getHoverTagModeId();
+ return;
+ }
+
let nodesData = this.NodesGraphUtils.getAllNodesData(this._cy.nodes());
let nodesLinks = this.GeneralGraphUtils.getAllCompositionCiLinks(this._cy);
@@ -622,12 +655,16 @@
let filteredNodesData = this.matchCapabilitiesRequirementsUtils.findMatchingNodes(payload.node.data().componentInstance, linkableNodes, nodesLinks);
this.matchCapabilitiesRequirementsUtils.highlightMatchingComponents(filteredNodesData, this._cy);
this.matchCapabilitiesRequirementsUtils.fadeNonMachingComponents(filteredNodesData, nodesData, this._cy, payload.node.data());
-
+
this._cy.scratch()._edge_editation_highlights = true;
/*scope.hideAssetPopover();*/
});
this._cy.on('handlemouseout', () => {
+ if (scope.zoneTagMode) {
+ scope.zoneTagMode = scope.zones[scope.activeZoneInstance.type].getTagModeId();
+ return;
+ }
if (this._cy.scratch('_edge_editation_highlights') === true) {
this._cy.removeScratch('_edge_editation_highlights');
this._cy.emit('hidehandles');
@@ -638,15 +675,20 @@
this._cy.on('tapend', (event:Cy.EventObject) => {
scope.isOnDrag = false;
+ if (scope.zoneTagMode) {
+ return;
+ }
if (event.cyTarget === this._cy) { //On Background clicked
if (this._cy.$('node:selected').length === 0) { //if the background click but not dragged
+ if (scope.activeZoneInstance) {
+ scope.unsetActiveZoneInstance();
+ }
this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED);
}
scope.hideRelationMenu();
}
else if (event.cyTarget.isEdge()) { //On Edge clicked
- if (scope.isViewOnly) return;
this.CompositionGraphLinkUtils.handleLinkClick(this._cy, event);
if (event.cyTarget.data().type === CompositionCiServicePathLink.LINK_TYPE) {
return;
@@ -655,6 +697,7 @@
}
else { //On Node clicked
+
this._cy.nodes(':grabbed').style({'overlay-opacity': 0});
let isUcpe:boolean = event.cyTarget.data().isUcpe;
@@ -668,6 +711,9 @@
this.NodesGraphUtils.onNodesPositionChanged(this._cy, scope.component, nodesMoved);
} else {
this.$log.debug('composition-graph::onNodeSelectedEvent:: fired');
+ if (scope.activeZoneInstance) {
+ scope.unsetActiveZoneInstance();
+ }
scope.$apply(() => {
this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_NODE_SELECTED, event.cyTarget.data().componentInstance);
//open node popover menu
@@ -684,8 +730,21 @@
});
this._cy.on('boxselect', 'node', (event:Cy.EventObject) => {
+ scope.unsetActiveZoneInstance();
this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_NODE_SELECTED, event.cyTarget.data().componentInstance);
});
+
+ this._cy.on('canvasredraw', (event:Cy.EventObject) => {
+ if (scope.zoneTagMode) {
+ this.compositionGraphZoneUtils.showZoneTagIndications(this._cy, scope.activeZoneInstance);
+ }
+ });
+
+ this._cy.on('handletagclick', (event:Cy.EventObject, eventData:any) => {
+ this.compositionGraphZoneUtils.handleTagClick(this._cy, scope.activeZoneInstance, eventData.nodeId);
+
+
+ });
}
private openModifyLinkMenu = (scope:ICompositionGraphScope, linkMenuObject:LinkMenu, timeOutInMilliseconds?:number) => {
@@ -710,14 +769,15 @@
}
});
}
- scope.canvasMenuProps.items.push({
- contents: 'Delete',
- styleClass: 'w-sdc-canvas-menu-item-delete',
- action: () => {
- scope.deleteRelation(<Cy.CollectionEdges>linkMenuObject.link);
- }
- });
-
+ if(!scope.isViewOnly){
+ scope.canvasMenuProps.items.push({
+ contents: 'Delete',
+ styleClass: 'w-sdc-canvas-menu-item-delete',
+ action: () => {
+ scope.deleteRelation(<Cy.CollectionEdges>linkMenuObject.link);
+ }
+ });
+ }
scope.relationMenuTimeout = this.$timeout(() => {
scope.hideRelationMenu();
}, timeOutInMilliseconds ? timeOutInMilliseconds : 6000);
@@ -726,15 +786,19 @@
private initGraphNodes(componentInstances:ComponentInstance[], isViewOnly:boolean) {
- if (!isViewOnly) { //Init nodes handle extension - enable dynamic links
- setTimeout(()=> {
- let handles = new CytoscapeEdgeEditation;
- handles.init(this._cy, 18);
- handles.registerHandle(ComponentInstanceNodesStyle.getBasicNodeHanlde());
- handles.registerHandle(ComponentInstanceNodesStyle.getBasicSmallNodeHandle());
- handles.registerHandle(ComponentInstanceNodesStyle.getUcpeCpNodeHandle());
- }, 0);
- }
+
+ setTimeout(()=> {
+ let handles = new CytoscapeEdgeEditation;
+ handles.init(this._cy);
+ if (!isViewOnly) { //Init nodes handle extension - enable dynamic links
+ handles.initNodeEvents();
+ handles.registerHandle(ComponentInstanceNodesStyle.getAddEdgeHandle());
+ }
+ handles.registerHandle(ComponentInstanceNodesStyle.getTagHandle());
+ handles.registerHandle(ComponentInstanceNodesStyle.getTaggedPolicyHandle());
+ handles.registerHandle(ComponentInstanceNodesStyle.getTaggedGroupHandle());
+ }, 0);
+
_.each(componentInstances, (instance) => {
let compositionGraphNode:CompositionCiNodeBase = this.NodesFactory.createNode(instance);
@@ -755,7 +819,7 @@
scope.verifyDrop = (event:JQueryEventObject) => {
- if (this.dragElement.hasClass('red')) {
+ if (!this.dragElement || this.dragElement.hasClass('red')) {
return false;
}
return true;
@@ -777,45 +841,87 @@
private initZones = (scope:ICompositionGraphScope):void => {
scope.zones = this.compositionGraphZoneUtils.createCompositionZones();
- scope.zoneInstanceModeChanged = (newMode:ZoneInstanceMode, instance:ZoneInstanceConfig, zoneId:string):void => {
- if(scope.zoneTagMode) { //we're in tag mode.
- if(instance == scope.activeZoneInstance && newMode == ZoneInstanceMode.TAG){ //we want to toggle tag mode off.
- scope.unsetActiveZoneInstance();
+
+ scope.zoneMinimizeToggle = (zoneType:ZoneInstanceType):void => {
+ scope.zones[zoneType].minimized = !scope.zones[zoneType].minimized;
+ };
+
+ scope.zoneInstanceModeChanged = (newMode:ZoneInstanceMode, instance:ZoneInstance, zoneId:ZoneInstanceType):void => {
+ if (scope.zoneTagMode) { //we're in tag mode.
+ if (instance == scope.activeZoneInstance && newMode == ZoneInstanceMode.NONE) { //we want to turn tag mode off.
+ scope.zoneTagMode = null;
+ scope.activeZoneInstance.mode = ZoneInstanceMode.SELECTED;
+ this.compositionGraphZoneUtils.endCyTagMode(this._cy);
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_CANVAS_TAG_END, instance);
+
}
} else {
- scope.setZoneInstanceMode(newMode, instance, zoneId);
+ if (instance != scope.activeZoneInstance || (instance == scope.activeZoneInstance && newMode > ZoneInstanceMode.HOVER)) { //when active zone instance gets hover/none,dont actually change mode, just show/hide indications
+ instance.mode = newMode;
+ }
+
+ if (newMode == ZoneInstanceMode.NONE) {
+ this.compositionGraphZoneUtils.hideZoneTagIndications(this._cy);
+ if (scope.zones[ZoneInstanceType.GROUP]) {
+ this.compositionGraphZoneUtils.hideGroupZoneIndications(scope.zones[ZoneInstanceType.GROUP].instances);
+ }
+ }
+ if (newMode >= ZoneInstanceMode.HOVER) {
+ this.compositionGraphZoneUtils.showZoneTagIndications(this._cy, instance);
+ if (instance.type == ZoneInstanceType.POLICY && scope.zones[ZoneInstanceType.GROUP]) {
+ this.compositionGraphZoneUtils.showGroupZoneIndications(scope.zones[ZoneInstanceType.GROUP].instances, instance);
+ }
+ }
+ if (newMode >= ZoneInstanceMode.SELECTED) {
+ this._cy.$('node:selected').unselect();
+ if (scope.activeZoneInstance && scope.activeZoneInstance != instance && newMode >= ZoneInstanceMode.SELECTED) {
+ scope.activeZoneInstance.mode = ZoneInstanceMode.NONE;
+ }
+ scope.activeZoneInstance = instance;
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_ZONE_INSTANCE_SELECTED, instance);
+ }
+ if (newMode == ZoneInstanceMode.TAG) {
+ this.compositionGraphZoneUtils.startCyTagMode(this._cy);
+ scope.zoneTagMode = scope.zones[zoneId].getTagModeId();
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_CANVAS_TAG_START, zoneId);
+ }
}
};
- scope.setZoneInstanceMode = (newMode:ZoneInstanceMode, instance:ZoneInstanceConfig, zoneId:string):void => {
- instance.mode = newMode;
- switch(newMode){
- case ZoneInstanceMode.TAG: {
- scope.zoneTagMode = zoneId + "-tagging";
- }
- case ZoneInstanceMode.SELECTED: { //case TAG flows into here as well
- scope.activeZoneInstance = instance;
- break;
- }
+ scope.zoneInstanceTagged = (taggedInstance:ZoneInstance) => {
+ scope.activeZoneInstance.addOrRemoveAssignment(taggedInstance.instanceData.uniqueId, ZoneInstanceAssignmentType.GROUPS);
+ let newHandle:string = this.compositionGraphZoneUtils.getCorrectHandleForNode(taggedInstance.instanceData.uniqueId, scope.activeZoneInstance);
+ taggedInstance.showHandle(newHandle);
+ }
+
+ scope.zoneBackgroundClicked = ():void => {
+ if (!scope.zoneTagMode && scope.activeZoneInstance) {
+ scope.unsetActiveZoneInstance();
+ }
+ };
+
+ scope.zoneAssignmentSaveStart = () => {
+ this.LoaderService.showLoader('composition-graph');
+ }
+
+ scope.zoneAssignmentSaveComplete = (success:boolean) => {
+ this.LoaderService.hideLoader('composition-graph');
+ if (!success) {
+ this.GeneralGraphUtils.showUpdateFailure();
}
};
scope.unsetActiveZoneInstance = ():void => {
- scope.activeZoneInstance.mode = ZoneInstanceMode.NONE;
- scope.activeZoneInstance = null;
- scope.zoneTagMode = null;
+ if(scope.activeZoneInstance){
+ scope.activeZoneInstance.mode = ZoneInstanceMode.NONE;
+ scope.activeZoneInstance = null;
+ scope.zoneTagMode = null;
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED);
+ }
};
-
- scope.clickOutsideZoneInstance = ():void => {
- if(!scope.zoneTagMode)
- scope.unsetActiveZoneInstance();
- };
-
};
-
-
public static factory = ($q,
$log,
$timeout,
@@ -835,8 +941,7 @@
ModalService,
ConnectionWizardService,
ComponentInstanceServiceNg2,
- ServicePathGraphUtils,
- PoliciesService) => {
+ ServicePathGraphUtils) => {
return new CompositionGraph(
$q,
$log,
@@ -857,8 +962,7 @@
ModalService,
ConnectionWizardService,
ComponentInstanceServiceNg2,
- ServicePathGraphUtils,
- PoliciesService);
+ ServicePathGraphUtils);
}
}
@@ -882,6 +986,5 @@
'ModalServiceNg2',
'ConnectionWizardServiceNg2',
'ComponentInstanceServiceNg2',
- 'ServicePathGraphUtils',
- 'PoliciesServiceNg2'
+ 'ServicePathGraphUtils'
];
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.html b/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.html
index 487e4cb..2d8145f 100644
--- a/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.html
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.html
@@ -1,12 +1,12 @@
<loader display="isLoading" loader-type="composition-graph"></loader>
-<div class="sdc-composition-graph-wrapper {{zoneTagMode}}" ng-class="{'view-only':isViewOnly}"
- data-drop="true"
+<div class="sdc-composition-graph-wrapper {{zoneTagMode}}" ng-class="{'with-sidebar': withSidebar, 'view-only':isViewOnly}"
+ data-drop="!zoneTagMode"
data-jqyoui-options="{accept: verifyDrop}"
data-jqyoui-droppable="{onDrop:'dropCallback', beforeDrop: 'beforeDropCallback'}">
</div>
-<relation-menu relation-menu-directive-obj="relationMenuDirectiveObj" is-link-menu-open="isLinkMenuOpen"
- create-relation="createLinkFromMenu" cancel="cancelRelationMenu()"></relation-menu>
+<!-- <relation-menu relation-menu-directive-obj="relationMenuDirectiveObj" is-link-menu-open="isLinkMenuOpen"
+ create-relation="createLinkFromMenu" cancel="cancelRelationMenu()"></relation-menu> -->
<menu-list-ng2 [props]="canvasMenuProps"></menu-list-ng2>
@@ -19,10 +19,11 @@
[delete-paths]="deletePathsOnCy"
[selected-path-id]="selectedPathId">
</ng2-service-path-selector>
- <ng2-service-path
+ <ng2-service-path
ng-if="component.isService()"
[service]="component"
- [on-create]="createOrUpdateServicePath">
+ [on-create]="createOrUpdateServicePath"
+ [is-view-only]="isViewOnly">
</ng2-service-path>
<ng2-search-with-autocomplete
[search-placeholder]="'Type to search'"
@@ -31,17 +32,19 @@
(search-button-clicked)="highlightSearchMatches($event)"
[search-bar-class]="'composition-search'">
</ng2-search-with-autocomplete>
- <div class="zoom-icons sprite-new canvas-fit-all" data-ng-click="zoomAll()"></div>
+ <div class="zoom-icons sprite-new canvas-fit-all" data-ng-click="zoomAllWithoutSidebar()"></div>
<div class="zoom-icons sprite-new zoom-plus" data-ng-click="zoom(true)"></div>
<div class="zoom-icons sprite-new zoom-minus" data-ng-click="zoom(false)"></div>
</div>
<!--<asset-popover ng-if="assetPopoverOpen" asset-popover-obj="assetPopoverObj" delete-asset="deleteNode(assetPopoverObj.nodeId)"></asset-popover>-->
<div class="sdc-canvas-zones__wrapper {{zoneTagMode}}" data-ng-class="{'with-sidebar': withSidebar}">
- <ng2-zone-container data-ng-repeat="zoneConfig in zones" [title]="zoneConfig.title" [class]="zoneConfig.type" [count]="zoneConfig.instances.length" [show-zone] = "zoneConfig.showZone" [minify-zone] = "minifyZone">
+ <ng2-zone-container data-ng-repeat="zone in zones" [title]="zone.title" [type]="zone.type" [count]="zone.instances.length"
+ [visible]="zone.visible" [minimized]="zone.minimized" (minimize)="zoneMinimizeToggle(zone.type)" (background-click)="zoneBackgroundClicked()">
<ng2-zone-instance
- data-ng-repeat="instance in zoneConfig.instances" clicked-outside="{onClickedOutside: 'clickOutsideZoneInstance()', clickedOutsideEnable: 'activeZoneInstance == instance'}"
- [config]="instance" [default-icon-text]="zoneConfig.defaultIconText" [is-active]="activeZoneInstance == instance" [active-instance-mode]="activeZoneInstance && activeZoneInstance.mode"
- (mode-change)="zoneInstanceModeChanged($event.newMode, $event.instance, zoneConfig.type)">
+ data-ng-repeat="instance in zone.instances" [hidden]="instance.hidden"
+ [zone-instance]="instance" [default-icon-text]="zone.defaultIconText" [is-active]="activeZoneInstance == instance" [active-instance-mode]="activeZoneInstance && activeZoneInstance.mode"
+ [is-view-only]="isViewOnly" [force-save]="instance.forceSave" (mode-change)="zoneInstanceModeChanged($event.newMode, $event.instance, zone.type)" (tag-handle-click)="zoneInstanceTagged($event)"
+ (assignment-save-start)="zoneAssignmentSaveStart()" (assignment-save-complete)="zoneAssignmentSaveComplete($event)">
</ng2-zone-instance>
</ng2-zone-container>
-</div>
+</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.less b/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.less
index 5a6a104..7124a4b 100644
--- a/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.less
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.less
@@ -6,6 +6,10 @@
.sdc-composition-graph-wrapper{
height:100%;
width: 100%;
+
+ &.with-sidebar {
+ width: calc(~'100% - 300px');
+ }
}
.view-only{
@@ -29,10 +33,18 @@
}
}
+
.group-tagging {
- cursor: url("/assets/styles/images/canvas-tagging-icons/adding_group.svg"), pointer;
+ cursor: url("../../../../assets/styles/images/canvas-tagging-icons/group_1.svg"), pointer;
+ }
+ .group-tagging-hover {
+ cursor: url("../../../../assets/styles/images/canvas-tagging-icons/group_2.svg"), pointer;
}
.policy-tagging {
- cursor: url("/assets/styles/images/canvas-tagging-icons/adding_policy.svg"), pointer;
+ cursor: url("../../../../assets/styles/images/canvas-tagging-icons/policy_1.svg"), pointer;
}
+ .policy-tagging-hover {
+ cursor: url("../../../../assets/styles/images/canvas-tagging-icons/policy_2.svg"), pointer;
+ }
+
}
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts
index 73e03e9..329af56 100644
--- a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts
@@ -34,7 +34,8 @@
constructor(private $q:ng.IQService,
private LoaderService:LoaderService,
private commonGraphUtils:CommonGraphUtils,
- private matchCapabilitiesRequirementsUtils:MatchCapabilitiesRequirementsUtils) {
+ private matchCapabilitiesRequirementsUtils:MatchCapabilitiesRequirementsUtils,
+ private Notification:any) {
CompositionGraphGeneralUtils.graphUtilsUpdateQueue = new QueueUtils(this.$q);
}
@@ -73,6 +74,34 @@
renderedPosition: { x: zx, y: zy }
});
}
+
+
+ //saves the current zoom, and then sets a temporary maximum zoom for zoomAll, and then reverts to old value
+ public zoomAllWithMax = (cy:Cy.Instance, maxZoom:number):void => {
+
+ let oldMaxZoom:number = cy.maxZoom();
+
+ cy.maxZoom(maxZoom);
+ this.zoomAll(cy);
+ cy.maxZoom(oldMaxZoom);
+
+ };
+
+
+ //Zooms to fit all of the nodes in the collection passed in. If no nodes are passed in, will zoom to fit all nodes on graph
+ public zoomAll = (cy:Cy.Instance, nodes?:Cy.CollectionNodes):void => {
+
+ if (!nodes || !nodes.length) {
+ nodes = cy.nodes();
+ }
+
+ cy.resize();
+ cy.animate({
+ fit: { eles: nodes, padding: 20 },
+ center: { eles: nodes }
+ }, { duration: 400 });
+ };
+
/**
* will return true/false if two nodes overlapping
*
@@ -223,6 +252,27 @@
};
+ public showPolicyUpdateSuccess = () => {
+ this.Notification.success({
+ message: "Policy Updated",
+ title: "Success"
+ });
+ }
+
+ public showGroupUpdateSuccess = () => {
+ this.Notification.success({
+ message: "Group Updated",
+ title: "Success"
+ });
+ }
+
+ public showUpdateFailure = () => {
+ this.Notification.error({
+ message: "Update Failed",
+ title: "Error"
+ });
+ };
+
/**
* Get Graph Utils server queue
* @returns {QueueUtils}
@@ -270,4 +320,4 @@
};
}
-CompositionGraphGeneralUtils.$inject = ['$q', 'LoaderService', 'CommonGraphUtils', 'MatchCapabilitiesRequirementsUtils'];
+CompositionGraphGeneralUtils.$inject = ['$q', 'LoaderService', 'CommonGraphUtils', 'MatchCapabilitiesRequirementsUtils', 'Notification'];
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-nodes-utils.ts b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-nodes-utils.ts
index fb1e665..cfec492 100644
--- a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-nodes-utils.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-nodes-utils.ts
@@ -105,6 +105,8 @@
(<Service>component).forwardingPaths = response.forwardingPaths;
});
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_DELETE_COMPONENT_INSTANCE_SUCCESS, nodeId);
+
//update UI
cy.remove(nodeToDelete);
};
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-service-path-utils.ts b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-service-path-utils.ts
index ef047d7..1a34891 100644
--- a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-service-path-utils.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-service-path-utils.ts
@@ -47,8 +47,14 @@
_.forEach(pathElements, (link: ForwardingPathLink) => {
let data:CompositionCiServicePathLink = new CompositionCiServicePathLink(link);
- data.source = data.forwardingPathLink.fromNode;
- data.target = data.forwardingPathLink.toNode;
+ data.source = _.find(
+ service.componentInstances,
+ instance => instance.name === data.forwardingPathLink.fromNode
+ ).uniqueId;
+ data.target = _.find(
+ service.componentInstances,
+ instance => instance.name === data.forwardingPathLink.toNode
+ ).uniqueId;
data.pathId = forwardingPath.uniqueId;
data.pathName = forwardingPath.name;
this.commonGraphUtils.insertServicePathLinkToGraph(cy, data);
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-zone-utils.ts b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-zone-utils.ts
index 28f2dc8..bcf0cb7 100644
--- a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-zone-utils.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-zone-utils.ts
@@ -1,55 +1,195 @@
-import { PolicyInstance } from "app/models/graph/zones/policy-instance";
-import { ZoneConfig, ZoneInstanceConfig } from "app/models/graph/zones/zone-child";
-import { DynamicComponentService } from "app/ng2/services/dynamic-component.service";
-import { PaletteAnimationComponent } from "app/ng2/components/ui/palette-animation/palette-animation.component";
-import { Point } from "../../../../models";
+import {PolicyInstance} from "app/models/graph/zones/policy-instance";
+import {ZoneInstance, ZoneInstanceType, ZoneInstanceAssignmentType} from "app/models/graph/zones/zone-instance";
+import {Zone} from "app/models/graph/zones/zone";
+import {DynamicComponentService} from "app/ng2/services/dynamic-component.service";
+import {PaletteAnimationComponent} from "app/ng2/components/ui/palette-animation/palette-animation.component";
+import {Point, LeftPaletteMetadataTypes, Component} from "../../../../models";
+import {CanvasHandleTypes} from "app/utils";
+import {PoliciesService} from "../../../../ng2/services/policies.service";
+import {Observable} from "rxjs";
+import {GroupsService} from "../../../../ng2/services/groups.service";
+import {GroupInstance} from "app/models/graph/zones/group-instance";
+
export class CompositionGraphZoneUtils {
- constructor(private dynamicComponentService: DynamicComponentService) {}
+ constructor(private dynamicComponentService:DynamicComponentService,
+ private policiesService:PoliciesService,
+ private groupsService:GroupsService) {
+ }
- public createCompositionZones(){
- let zones = {
- 'policy': new ZoneConfig('Policies', 'P', 'policy', false),
- 'group': new ZoneConfig('Groups', 'G', 'group', false)
- };
+
+ public createCompositionZones = ():Array<Zone> => {
+ let zones:Array<Zone> = [];
+
+ zones[ZoneInstanceType.POLICY] = new Zone('Policies', 'P', ZoneInstanceType.POLICY);
+ zones[ZoneInstanceType.GROUP] = new Zone('Groups', 'G', ZoneInstanceType.GROUP);
+
return zones;
}
- public initPolicyInstances(policyZone:ZoneConfig, policies:Array<PolicyInstance>) {
- if(policies && policies.length){
- policyZone.showZone = true;
+ public showZone = (zone:Zone):void => {
+ zone.visible = true;
+ zone.minimized = false;
+ }
+
+ public getZoneTypeForPaletteComponent = (componentCategory:LeftPaletteMetadataTypes) => {
+ if (componentCategory == LeftPaletteMetadataTypes.Group) {
+ return ZoneInstanceType.GROUP;
+ } else if (componentCategory == LeftPaletteMetadataTypes.Policy) {
+ return ZoneInstanceType.POLICY;
}
- _.forEach(policies, (policy:PolicyInstance) => {
- policyZone.instances.push(new ZoneInstanceConfig(policy));
+ };
+
+ public initZoneInstances(zones:Array<Zone>, component:Component) {
+ if (component.groupInstances && component.groupInstances.length) {
+ this.showZone(zones[ZoneInstanceType.GROUP]);
+ _.forEach(component.groupInstances, (group:GroupInstance) => {
+ let newInstance = new ZoneInstance(group, component);
+ this.addInstanceToZone(zones[ZoneInstanceType.GROUP], newInstance);
+ });
+ }
+
+ if (component.policies && component.policies.length) {
+ this.showZone(zones[ZoneInstanceType.POLICY]);
+ _.forEach(component.policies, (policy:PolicyInstance) => {
+ let newInstance = new ZoneInstance(policy, component);
+ this.addInstanceToZone(zones[ZoneInstanceType.POLICY], newInstance);
+
+ });
+ }
+ }
+
+ public findAndUpdateZoneInstanceData (zones: Array<Zone>, instanceData:PolicyInstance | GroupInstance) {
+ _.forEach(zones, (zone:Zone) => {
+ _.forEach(zone.instances, (zoneInstance:ZoneInstance) => {
+ if(zoneInstance.instanceData.uniqueId === instanceData.uniqueId){
+ zoneInstance.updateInstanceData(instanceData);
+ }
+ });
});
}
- public addInstanceToZone(zone:ZoneConfig, instance:PolicyInstance){
- zone.instances.push(new ZoneInstanceConfig(instance));
+ public updateTargetsOrMembersOnCanvasDelete = (canvasNodeID:string, zones:Array<Zone>, type:ZoneInstanceAssignmentType):void => {
+ _.forEach(zones, (zone) => {
+ _.forEach(zone.instances, (zoneInstance:ZoneInstance) => {
+ if (zoneInstance.isAlreadyAssigned(canvasNodeID)) {
+ zoneInstance.addOrRemoveAssignment(canvasNodeID, type);
+ //remove it from our list of BE targets and members as well (so that it will not be sent in future calls to BE).
+ zoneInstance.instanceData.setSavedAssignments(zoneInstance.assignments);
+ }
+ });
+ });
};
- private findZoneCoordinates(zoneType):Point{
- let point:Point = new Point(0,0);
+ public createZoneInstanceFromLeftPalette = (zoneType:ZoneInstanceType, component:Component, paletteComponentType:string):Observable<ZoneInstance> => {
+ if (zoneType === ZoneInstanceType.POLICY) {
+ return this.policiesService.createPolicyInstance(component.componentType, component.uniqueId, paletteComponentType).map(response => {
+ let newInstance = new PolicyInstance(response);
+ component.policies.push(newInstance);
+ return new ZoneInstance(newInstance, component);
+ });
+ } else if (zoneType === ZoneInstanceType.GROUP) {
+ return this.groupsService.createGroupInstance(component.componentType, component.uniqueId, paletteComponentType).map(response => {
+ let newInstance = new GroupInstance(response);
+ component.groupInstances.push(newInstance);
+ return new ZoneInstance(newInstance, component);
+ });
+ }
+ }
+
+ public addInstanceToZone(zone:Zone, instance:ZoneInstance, hide?:boolean) {
+ if(hide){
+ instance.hidden = true;
+ }
+ zone.instances.push(instance);
+
+ };
+
+ private findZoneCoordinates(zoneType):Point {
+ let point:Point = new Point(0, 0);
let zone = angular.element(document.querySelector('.' + zoneType + '-zone'));
- let wrapperZone = zone.offsetParent();
- point.x = zone.prop('offsetLeft') + wrapperZone.prop('offsetLeft');
- point.y = zone.prop('offsetTop') + wrapperZone.prop('offsetTop');
+ let wrapperZone = zone.offsetParent();
+ point.x = zone.prop('offsetLeft') + wrapperZone.prop('offsetLeft');
+ point.y = zone.prop('offsetTop') + wrapperZone.prop('offsetTop');
return point;
}
- public showAnimationToZone = (startPoint:Point, zoneType:string) => {
-
+ public createPaletteToZoneAnimation = (startPoint:Point, zoneType:ZoneInstanceType, newInstance:ZoneInstance) => {
+ let zoneTypeName = ZoneInstanceType[zoneType].toLowerCase();
let paletteToZoneAnimation = this.dynamicComponentService.createDynamicComponent(PaletteAnimationComponent);
paletteToZoneAnimation.instance.from = startPoint;
- paletteToZoneAnimation.instance.to = this.findZoneCoordinates(zoneType);
- paletteToZoneAnimation.instance.iconName = zoneType;
+ paletteToZoneAnimation.instance.type = zoneType;
+ paletteToZoneAnimation.instance.to = this.findZoneCoordinates(zoneTypeName);
+ paletteToZoneAnimation.instance.zoneInstance = newInstance;
+ paletteToZoneAnimation.instance.iconName = zoneTypeName;
paletteToZoneAnimation.instance.runAnimation();
}
-
+ public startCyTagMode = (cy:Cy.Instance) => {
+ cy.autolock(true);
+ cy.nodes().unselectify();
+ cy.emit('tagstart'); //dont need to show handles because they're already visible bcz of hover event
+
+ };
+
+ public endCyTagMode = (cy:Cy.Instance) => {
+ cy.emit('tagend');
+ cy.nodes().selectify();
+ cy.autolock(false);
+ };
+
+ public handleTagClick = (cy:Cy.Instance, zoneInstance:ZoneInstance, nodeId:string) => {
+ zoneInstance.addOrRemoveAssignment(nodeId, ZoneInstanceAssignmentType.COMPONENT_INSTANCES);
+ this.showZoneTagIndicationForNode(nodeId, zoneInstance, cy);
+ };
+
+ public showGroupZoneIndications = (groupInstances:Array<ZoneInstance>, policyInstance:ZoneInstance) => {
+ groupInstances.forEach((groupInstance:ZoneInstance)=> {
+ let handle:string = this.getCorrectHandleForNode(groupInstance.instanceData.uniqueId, policyInstance);
+ groupInstance.showHandle(handle);
+ })
+ };
+
+ public hideGroupZoneIndications = (instances:Array<ZoneInstance>) => {
+ instances.forEach((instance) => {
+ instance.hideHandle();
+ })
+ }
+
+ public showZoneTagIndications = (cy:Cy.Instance, zoneInstance:ZoneInstance) => {
+
+ cy.nodes().forEach(node => {
+ let handleType:string = this.getCorrectHandleForNode(node.id(), zoneInstance);
+ cy.emit('showhandle', [node, handleType]);
+ });
+ };
+
+ public showZoneTagIndicationForNode = (nodeId:string, zoneInstance:ZoneInstance, cy:Cy.Instance) => {
+ let node = cy.getElementById(nodeId);
+ let handleType:string = this.getCorrectHandleForNode(nodeId, zoneInstance);
+ cy.emit('showhandle', [node, handleType]);
+ }
+
+ public hideZoneTagIndications = (cy:Cy.Instance) => {
+ cy.emit('hidehandles');
+ };
+
+ public getCorrectHandleForNode = (nodeId:string, zoneInstance:ZoneInstance):string => {
+ if (zoneInstance.isAlreadyAssigned(nodeId)) {
+ if (zoneInstance.type == ZoneInstanceType.POLICY) {
+ return CanvasHandleTypes.TAGGED_POLICY;
+ } else {
+ return CanvasHandleTypes.TAGGED_GROUP;
+ }
+ } else {
+ return CanvasHandleTypes.TAG_AVAILABLE;
+ }
+ };
}
CompositionGraphZoneUtils.$inject = [
- 'DynamicComponentService'
+ 'DynamicComponentService',
+ 'PoliciesServiceNg2',
+ 'GroupsServiceNg2'
];
\ No newline at end of file
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/match-capability-requierment-utils.ts b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/match-capability-requierment-utils.ts
index 3a05ce9..eac907a 100644
--- a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/match-capability-requierment-utils.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/match-capability-requierment-utils.ts
@@ -74,19 +74,25 @@
}
private static isRequirementFulfilled(fromNodeId:string, requirement:any, links:Array<CompositionCiLinkBase>):boolean {
- return _.some(links, {
+ if(requirement.maxOccurrences === 'UNBOUNDED'){
+ return false;
+ }
+ let linksWithThisReq:Array<CompositionCiLinkBase> = _.filter(links, {
'relation': {
'fromNode': fromNodeId,
'relationships': [{
- 'requirementOwnerId': requirement.ownerId,
- 'requirement': requirement.name,
- 'relationship': {
- 'type': requirement.relationship
+ 'relation':{
+ 'requirementOwnerId': requirement.ownerId,
+ 'requirement': requirement.name,
+ 'relationship': {
+ 'type': requirement.capability
+ }
+
}
- }
- ]
+ }]
}
});
+ return linksWithThisReq.length == requirement.maxOccurrences;
};
private static isMatch(requirement:Requirement, capability:Capability):boolean {
diff --git a/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-graph.directive.ts b/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-graph.directive.ts
index c542e9f..f335ea0 100644
--- a/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-graph.directive.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-graph.directive.ts
@@ -54,7 +54,7 @@
link = (scope: IDeploymentGraphScope, el: JQuery) => {
if (scope.component.isResource()) {
- if (scope.component.componentInstances && scope.component.componentInstancesRelations && scope.component.groups) {
+ if (scope.component.componentInstances && scope.component.componentInstancesRelations && scope.component.modules) {
this.loadGraph(scope, el);
} else {
this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_DEPLOYMENT_GRAPH_DATA_LOADED, () => {
@@ -65,8 +65,8 @@
};
public initGraphNodes = (cy: Cy.Instance, component: Component): void => {
- if (component.groups) { // Init module nodes
- _.each(component.groups, (groupModule: Module) => {
+ if (component.modules) { // Init module nodes
+ _.each(component.modules, (groupModule: Module) => {
let moduleNode = this.NodesFactory.createModuleNode(groupModule);
this.commonGraphUtils.addNodeToGraph(cy, moduleNode);
@@ -74,7 +74,7 @@
}
_.each(component.componentInstances, (instance: ComponentInstance) => { // Init component instance nodes
let componentInstanceNode = this.NodesFactory.createNode(instance);
- componentInstanceNode.parent = this.deploymentGraphGeneralUtils.findInstanceModule(component.groups, instance.uniqueId);
+ componentInstanceNode.parent = this.deploymentGraphGeneralUtils.findInstanceModule(component.modules, instance.uniqueId);
if (componentInstanceNode.parent) { // we are not drawing instances that are not a part of a module
this.commonGraphUtils.addComponentInstanceNodeToGraph(cy, componentInstanceNode);
}
diff --git a/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-utils/deployment-graph-general-utils.ts b/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-utils/deployment-graph-general-utils.ts
index 3a90115..ebd1f5b 100644
--- a/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-utils/deployment-graph-general-utils.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-utils/deployment-graph-general-utils.ts
@@ -32,7 +32,7 @@
public findInstanceModule = (groupsArray:Array<Module>, componentInstanceId:string):string => {
let parentGroup:Module = _.find(groupsArray, (group:Module) => {
- return _.find(group.members, (member) => {
+ return _.find((<any>Object).values(group.members), (member: string) => {
return member === componentInstanceId;
});
});
diff --git a/catalog-ui/src/app/directives/graphs-v2/image-creator/image-creator.service.ts b/catalog-ui/src/app/directives/graphs-v2/image-creator/image-creator.service.ts
index 6d6291d..68c9e9a 100644
--- a/catalog-ui/src/app/directives/graphs-v2/image-creator/image-creator.service.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/image-creator/image-creator.service.ts
@@ -18,6 +18,14 @@
* ============LICENSE_END=========================================================
*/
+export interface ICanvasImage {
+ src: string;
+ width: number
+ height: number;
+ x: number;
+ y: number;
+}
+
'use strict';
export class ImageCreatorService {
static '$inject' = ['$q'];
@@ -31,36 +39,48 @@
body.appendChild(this._canvas);
}
- getImageBase64(imageBaseUri:string, imageLayerUri:string, nodeWidth:number, canvasWidth:number, handleSize:number):ng.IPromise<string> {
- let deferred = this.$q.defer();
- let imageBase = new Image();
- let imageLayer = new Image();
- let imagesLoaded = 0;
- let onImageLoaded = () => {
- imagesLoaded++;
+ /**
+ * Create an image composed of different image layers
+ * @param canvasImages
+ * @param canvasWidth
+ * @param canvasHeight
+ * returns a PROMISE
+ */
+ getMultiLayerBase64Image(canvasImages: ICanvasImage[], canvasWidth?:number, canvasHeight?:number):ng.IPromise<string> {
+ const deferred = this.$q.defer<string>();
- if (imagesLoaded < 2) {
+ if(canvasImages && canvasImages.length === 0){
+ return null;
+ }
+
+ //If only width was set, use it for height, otherwise use first canvasImage height
+ canvasHeight = canvasHeight || canvasImages[0].height;
+ canvasWidth = canvasWidth || canvasImages[0].width;
+
+ const images = [];
+ let imagesLoaded = 0;
+ const onImageLoaded = () => {
+ imagesLoaded++;
+ if(imagesLoaded < canvasImages.length){
return;
}
this._canvas.setAttribute('width', canvasWidth.toString());
- this._canvas.setAttribute('height', canvasWidth.toString());
-
- let canvasCtx = this._canvas.getContext('2d');
+ this._canvas.setAttribute('height', canvasHeight.toString());
+ const canvasCtx = this._canvas.getContext('2d');
canvasCtx.clearRect(0, 0, this._canvas.width, this._canvas.height);
-
- //Note: params below are: image, x to start drawing at, y to start drawing at, num of x pixels to draw, num of y pixels to draw
- canvasCtx.drawImage(imageBase, 0, canvasWidth - nodeWidth, nodeWidth, nodeWidth); //Draw the node: When nodeWidth == canvasWidth, we'll start at point 0,0. Otherwise, x starts at 0 (but will end before end of canvas) and y starts low enough that node img ends at bottom of canvas.
- canvasCtx.drawImage(imageLayer, canvasWidth - handleSize, 0, handleSize, handleSize); //Draw the icon: icon should be drawn in top right corner
-
+ images.forEach((image, index) => {
+ const canvasImage = canvasImages[index];
+ canvasCtx.drawImage(image, canvasImage.x, canvasImage.y, canvasImage.width, canvasImage.height);
+ });
let base64Image = this._canvas.toDataURL();
deferred.resolve(base64Image);
};
-
- imageBase.onload = onImageLoaded;
- imageLayer.onload = onImageLoaded;
- imageBase.src = imageBaseUri;
- imageLayer.src = imageLayerUri;
-
+ canvasImages.forEach(canvasImage => {
+ let image = new Image();
+ image.onload = onImageLoaded;
+ image.src = canvasImage.src;
+ images.push(image);
+ });
return deferred.promise;
}
}
diff --git a/catalog-ui/src/app/directives/graphs-v2/palette/palette.directive.ts b/catalog-ui/src/app/directives/graphs-v2/palette/palette.directive.ts
index 9b92352..ebc52c2 100644
--- a/catalog-ui/src/app/directives/graphs-v2/palette/palette.directive.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/palette/palette.directive.ts
@@ -27,9 +27,10 @@
import {Resource} from "app/models/components/resource";
import {ComponentType} from "app/utils/constants";
import {LeftPaletteMetadataTypes} from "../../../models/components/displayComponent";
+import { IDirectiveLinkFn, IScope } from "angular";
-interface IPaletteScope {
+interface IPaletteScope extends IScope{
components:Array<LeftPaletteComponent>;
currentComponent:Component;
model:any;
@@ -88,7 +89,8 @@
restrict = 'E';
template = require('./palette.html');
- link = (scope:IPaletteScope, el:JQuery) => {
+ link:IDirectiveLinkFn = (scope:IPaletteScope, el:JQuery) => {
+ this.LeftPaletteLoaderService.loadLeftPanel(scope.currentComponent);
this.nodeHtmlSubstitute = $('<div class="node-substitute"><span></span><img /></div>');
el.append(this.nodeHtmlSubstitute);
this.registerEventListenerForLeftPalette(scope);
@@ -277,7 +279,7 @@
let filteredResources = [];
angular.forEach(subcategory, function (component:LeftPaletteComponent) {
- let resourceFilterTerm:string = component.searchFilterTerms;
+ let resourceFilterTerm:string = component.searchFilterTerms.toLowerCase();
if (resourceFilterTerm.indexOf(searchText.toLowerCase()) >= 0) {
filteredResources.push(component);
}
diff --git a/catalog-ui/src/app/directives/graphs-v2/palette/palette.html b/catalog-ui/src/app/directives/graphs-v2/palette/palette.html
index a8139e3..ee0c604 100644
--- a/catalog-ui/src/app/directives/graphs-v2/palette/palette.html
+++ b/catalog-ui/src/app/directives/graphs-v2/palette/palette.html
@@ -26,7 +26,7 @@
data-ng-class="{'default-pointer': isViewOnly}"
data-ng-mouseover="!isViewOnly && onMouseOver(component, $event.currentTarget)"
data-ng-mouseleave="!isViewOnly && onMouseOut(component)"
- data-drag="!isViewOnly"
+ data-drag="!isViewOnly && component.isDraggable"
data-jqyoui-options="{revert: 'invalid', helper:setElementTemplate, appendTo:'body', cursorAt: {left:38, top: 38}, cursor:'move'}"
jqyoui-draggable="{index:{{$index}},animate:true,onStart:'dragStartCallback(component)',onStop:'dragStopCallback()', onDrag:'onDragCallback()'}"
data-ng-repeat="component in components | orderBy: 'displayName' track by $index"
diff --git a/catalog-ui/src/app/directives/graphs-v2/relation-menu/relation-menu.html b/catalog-ui/src/app/directives/graphs-v2/relation-menu/relation-menu.html
deleted file mode 100644
index e1cdf49..0000000
--- a/catalog-ui/src/app/directives/graphs-v2/relation-menu/relation-menu.html
+++ /dev/null
@@ -1,63 +0,0 @@
-<div class="link-menu-open" data-tests-id="link-menu-open" data-ng-show="isLinkMenuOpen" ng-style="{left: connectRelationModel.menuPosition.x, top: connectRelationModel.menuPosition.y}" clicked-outside="{onClickedOutside: 'hideRelationMatch()', clickedOutsideEnable: 'isLinkMenuOpen'}" >
- <h4 sdc-smart-tooltip>{{relationMenuDirectiveObj.leftSideLink.componentInstance.name | resourceName}}</h4>
- <h4 sdc-smart-tooltip>{{relationMenuDirectiveObj.rightSideLink.componentInstance.name | resourceName}}</h4>
-
- <p>Select one of the options below to connect</p>
-
- <perfect-scrollbar scroll-y-margin-offset="0" include-padding="true" class="scrollbar-container">
- <div class="inner-title" data-ng-show="hasMatchesToShow(connectRelationModel.leftSideLink.requirements, connectRelationModel.rightSideLink.selectedMatch)">Requirements</div>
- <div class="link-item" data-tests-id="link-item-requirements" data-ng-repeat="(req ,matchArr) in connectRelationModel.leftSideLink.requirements"
- data-ng-click="connectRelationModel.leftSideLink.selectMatchArr(matchArr); updateSelectionText()"
- data-ng-show="showMatch(connectRelationModel.rightSideLink.selectedMatch, matchArr)"
- data-ng-class="{ 'selected': connectRelationModel.leftSideLink.selectedMatch === matchArr}">
- <div sdc-smart-tooltip>{{matchArr[0].requirement.getFullTitle()}}</div>
- </div>
-
- <div class="inner-title" data-ng-show="hasMatchesToShow(connectRelationModel.leftSideLink.capabilities, connectRelationModel.rightSideLink.selectedMatch)">Capabilities</div>
- <div class="link-item" data-tests-id="link-item-capabilities" data-ng-repeat="(cap, matchArr) in connectRelationModel.leftSideLink.capabilities"
- data-ng-click="connectRelationModel.leftSideLink.selectMatchArr(matchArr); updateSelectionText()"
- data-ng-show="showMatch(connectRelationModel.rightSideLink.selectedMatch, matchArr)"
- data-ng-class="{ 'selected': connectRelationModel.leftSideLink.selectedMatch === matchArr}">
- <div sdc-smart-tooltip>{{matchArr[0].capability.getFullTitle()}}</div>
- </div>
- </perfect-scrollbar>
-
- <perfect-scrollbar scroll-y-margin-offset="0" include-padding="true" class="scrollbar-container">
- <div class="inner-title" data-ng-show="hasMatchesToShow(connectRelationModel.rightSideLink.requirements, connectRelationModel.leftSideLink.selectedMatch)">Requirements</div>
- <div class="link-item" data-tests-id="link-item-requirements" data-ng-repeat="(req, matchArr) in connectRelationModel.rightSideLink.requirements"
- data-ng-click="connectRelationModel.rightSideLink.selectMatchArr(matchArr); updateSelectionText()"
- data-ng-show="showMatch(connectRelationModel.leftSideLink.selectedMatch, matchArr)"
- data-ng-class="{ 'selected': connectRelationModel.rightSideLink.selectedMatch === matchArr}">
- <div sdc-smart-tooltip>{{matchArr[0].secondRequirement ? matchArr[0].secondRequirement.getFullTitle() : matchArr[0].requirement.getFullTitle()}}</div>
- </div>
-
- <div class="inner-title" data-ng-show="hasMatchesToShow(connectRelationModel.rightSideLink.capabilities, connectRelationModel.leftSideLink.selectedMatch)">Capabilities</div>
- <div class="link-item" data-tests-id="link-item-capabilities" data-ng-repeat="(cap, matchArr) in connectRelationModel.rightSideLink.capabilities"
- data-ng-click="connectRelationModel.rightSideLink.selectMatchArr(matchArr); updateSelectionText()"
- data-ng-show="showMatch(connectRelationModel.leftSideLink.selectedMatch, matchArr)"
- data-ng-class="{ 'selected': connectRelationModel.rightSideLink.selectedMatch === matchArr}">
- <div sdc-smart-tooltip>{{matchArr[0].capability.getFullTitle()}}</div>
- </div>
- </perfect-scrollbar>
-
- <div class="vl-type" data-ng-class="{'disabled': !connectRelationModel.leftSideLink.selectedMatch[0].secondRequirement || !connectRelationModel.rightSideLink.selectedMatch[0].secondRequirement}">
- <sdc-radio-button sdc-model="relationMenuDirectiveObj.vlType" value="ptp"
- disabled="!relationMenuDirectiveObj.leftSideLink.selectedMatch[0].secondRequirement || !relationMenuDirectiveObj.rightSideLink.selectedMatch[0].secondRequirement || !relationMenuDirectiveObj.p2pVL"
- text="Point to point" elem-id="radioPTP" elem-name="vlType"></sdc-radio-button>
-
- <sdc-radio-button sdc-model="relationMenuDirectiveObj.vlType" value="mptmp"
- disabled="!relationMenuDirectiveObj.leftSideLink.selectedMatch[0].secondRequirement || !relationMenuDirectiveObj.rightSideLink.selectedMatch[0].secondRequirement || !relationMenuDirectiveObj.mp2mpVL"
- text="Multi point" elem-id="radioMPTMP" elem-name="vlType"></sdc-radio-button>
-
- <span class="sprite-new info-icon" tooltips tooltip-content="You are required to choose the type of the Virtual Link."></span>
- </div>
-
- <div class="result" sdc-smart-tooltip>​{{relationMenuDirectiveObj.selectionText}}
-
- </div>
-
- <button class="tlv-btn grey" data-tests-id="link-menu-button-cancel" data-ng-click="hideRelationMatch()">Cancel</button>
- <button class="tlv-btn blue" data-tests-id="link-menu-button-connect" data-ng-disabled="!connectRelationModel.leftSideLink.selectedMatch || !connectRelationModel.rightSideLink.selectedMatch ||
- (connectRelationModel.leftSideLink.selectedMatch[0].secondRequirement && !connectRelationModel.vlType)"
- data-ng-click="saveRelation()">Connect</button>
-</div>
diff --git a/catalog-ui/src/app/directives/graphs-v2/relation-menu/relation-menu.less b/catalog-ui/src/app/directives/graphs-v2/relation-menu/relation-menu.less
deleted file mode 100644
index dea814d..0000000
--- a/catalog-ui/src/app/directives/graphs-v2/relation-menu/relation-menu.less
+++ /dev/null
@@ -1,118 +0,0 @@
-.link-menu-open {
- display: block !important;
- color: @main_color_m;
- font-size: 14px;
- position: absolute;
- z-index: 99999;
- border-radius: 2px;
- background-color: #ffffff;
- box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.5);
- width: 460px;
- height: 418px;
-
- h4 {
- width: 50%;
- float: left;
- background-color: @tlv_color_u;
- font-size: 14px;
- font-weight: bold;
- line-height: 36px;
- margin: 0;
- padding: 0 15px;
-
- & + h4 {
- border-left: #d8d8d8 1px solid;
- }
- }
- p {
- clear: both;
- text-indent: 15px;
- border-bottom: #d8d8d8 1px solid;
- line-height: 34px;
- margin: 0;
- color: @func_color_s;
- }
-
- .scrollbar-container {
- height: 232px;
- width: 50%;
- float: left;
- margin-bottom: 5px;
- .perfect-scrollbar;
-
- & + .scrollbar-container {
- border-left: #d8d8d8 1px solid;
- }
-
- .inner-title {
- width: 189px;
- margin: 5px auto 3px auto;
- //text-indent: 10px;
- color: @func_color_s;
- text-transform: uppercase;
- font-weight: bold;
-
- //&:not(:first-child) {
- // margin-top: 10px;
- //}
- }
-
- .link-item {
- padding: 0 10px;
- line-height: 23px;
- height: 23px;
- text-indent: 5px;
- .hand;
-
- &.selected {
- background-color: @tlv_color_v;
- }
- }
- }
-
- .vl-type {
- height: 33px;
- border-top: #d8d8d8 solid 1px;
- clear: both;
- padding: 0 10px;
- line-height: 32px;
- color: @main_color_m;
-
- &.disabled {
- background-color: #f2f2f2;
- color: @color_m;
- }
- .info-icon {
- float:right;
- margin-top: 9px;
- }
- .tlv-radio {
- margin-right: 10px;
- }
- }
-
- .result {
- background-color: @main_color_m;
- line-height: 29px;
- color: #ffffff;
- padding: 0 15px;
- }
-
- button {
- float: right;
- margin-top: 9px;
- margin-right: 10px;
- }
-}
-.link-menu-item {
- cursor: pointer;
- line-height: 24px;
- padding: 0 10px;
- &:hover {
- color: @color_a;
- }
-}
-.link-menu::before {
- right: inherit !important;
- left: 50px;
-}
\ No newline at end of file
diff --git a/catalog-ui/src/app/directives/graphs-v2/relation-menu/relation-menu.ts b/catalog-ui/src/app/directives/graphs-v2/relation-menu/relation-menu.ts
deleted file mode 100644
index 78a269e..0000000
--- a/catalog-ui/src/app/directives/graphs-v2/relation-menu/relation-menu.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-'use strict'
-import * as _ from "lodash";
-import {Match, ConnectRelationModel} from "app/models";
-import {Component} from "../../../models/components/component";
-
-export interface IRelationMenuScope extends ng.IScope {
- relationMenuDirectiveObj:ConnectRelationModel;
- createRelation:Function;
- isLinkMenuOpen:boolean;
- hideRelationMatch:Function;
- cancel:Function;
-
- saveRelation();
- showMatch(arr1:Array<Match>, arr2:Array<Match>):boolean;
- hasMatchesToShow(matchesObj:Match, selectedMatch:Array<Match>);
- updateSelectionText():void;
-
-}
-
-
-export class RelationMenuDirective implements ng.IDirective {
-
- constructor(private $filter:ng.IFilterService) {
- }
-
- scope = {
- relationMenuDirectiveObj: '=',
- isLinkMenuOpen: '=',
- createRelation: '&',
- cancel: '&'
- };
-
- restrict = 'E';
- replace = true;
- template = ():string => {
- return require('./relation-menu.html');
- };
-
- link = (scope:IRelationMenuScope, element:JQuery, $attr:ng.IAttributes) => {
-
- scope.saveRelation = ():void=> {
- let chosenMatches:Array<any> = _.intersection(scope.relationMenuDirectiveObj.rightSideLink.selectedMatch, scope.relationMenuDirectiveObj.leftSideLink.selectedMatch);
- let chosenMatch:Match = chosenMatches[0];
- scope.createRelation()(chosenMatch);
- };
-
-
- scope.hideRelationMatch = () => {
- scope.isLinkMenuOpen = false;
- scope.cancel();
- };
-
- //to show options in link menu
- scope.showMatch = (arr1:Array<Match>, arr2:Array<Match>):boolean => {
- return !arr1 || !arr2 || _.intersection(arr1, arr2).length > 0;
- };
-
- //to show requirements/capabilities title
- scope.hasMatchesToShow = (matchesObj:Match, selectedMatch:Array<Match>):boolean => {
- let result:boolean = false;
- _.forEach(matchesObj, (matchesArr:Array<Match>) => {
- if (!result) {
- result = scope.showMatch(matchesArr, selectedMatch);
- }
- });
- return result;
- };
-
-
- scope.updateSelectionText = ():void => {
- let left:string = scope.relationMenuDirectiveObj.leftSideLink.selectedMatch ? this.$filter('resourceName')(scope.relationMenuDirectiveObj.leftSideLink.selectedMatch[0].getDisplayText('left')) : '';
- let both:string = scope.relationMenuDirectiveObj.leftSideLink.selectedMatch && scope.relationMenuDirectiveObj.rightSideLink.selectedMatch ? ' - ' +
- this.$filter('resourceName')(scope.relationMenuDirectiveObj.leftSideLink.selectedMatch[0].requirement.relationship) + ' - ' : '';
- let right:string = scope.relationMenuDirectiveObj.rightSideLink.selectedMatch ? this.$filter('resourceName')(scope.relationMenuDirectiveObj.rightSideLink.selectedMatch[0].getDisplayText('right')) : '';
- scope.relationMenuDirectiveObj.selectionText = left + both + right;
- };
-
-
- }
- public static factory = ($filter:ng.IFilterService)=> {
- return new RelationMenuDirective($filter);
- };
-}
-
-RelationMenuDirective.factory.$inject = ['$filter'];
diff --git a/catalog-ui/src/app/directives/inputs-and-properties/inputs/input-row-view.html b/catalog-ui/src/app/directives/inputs-and-properties/inputs/input-row-view.html
index 872a26b..32059c4 100644
--- a/catalog-ui/src/app/directives/inputs-and-properties/inputs/input-row-view.html
+++ b/catalog-ui/src/app/directives/inputs-and-properties/inputs/input-row-view.html
@@ -24,14 +24,14 @@
<span tooltips tooltip-content="{{input.type}}" data-tests-id="inputType_{{input.name}}">{{input.type}} </span>
</div>
</div>
- <sdc-checkbox ng-if="instanceInputsMap"
+ <ng1-checkbox ng-if="instanceInputsMap"
class="input-check-box"
disabled="input.isAlreadySelected || isViewOnly"
sdc-checklist-model="instanceInputsMap[instanceId]"
sdc-checklist-value="input"
sdc-checklist-change="onCheckboxClicked()"
data-tests-id="inputsCheckbox_{{input.name}}"
- data-ng-click=" $event.stopPropagation()"></sdc-checkbox>
+ data-ng-click=" $event.stopPropagation()"></ng1-checkbox>
<div class="delete" ng-if="showDeleteIcon">
<span class="sprite-new delete-icon remove-input-icon"
diff --git a/catalog-ui/src/app/directives/inputs-and-properties/properties/property-row-view.html b/catalog-ui/src/app/directives/inputs-and-properties/properties/property-row-view.html
index ff82a8b..95de0c4 100644
--- a/catalog-ui/src/app/directives/inputs-and-properties/properties/property-row-view.html
+++ b/catalog-ui/src/app/directives/inputs-and-properties/properties/property-row-view.html
@@ -15,12 +15,12 @@
<span tooltips tooltip-content="{{property.schema.property.type}}" data-tests-id="propertySchema">{{property.schema.property.type}} </span>
</div>
</div>
- <sdc-checkbox ng-if="instancePropertiesMap"
+ <ng1-checkbox ng-if="instancePropertiesMap"
class="property-check-box"
disabled="property.isAlreadySelected || isViewOnly"
sdc-checklist-model="instancePropertiesMap[instanceId]"
sdc-checklist-value="property"
sdc-checklist-change="onCheckboxClicked()"
data-tests-id="propertyCheckbox_{{property.name}}"
- data-ng-click=" $event.stopPropagation()"></sdc-checkbox>
+ data-ng-click=" $event.stopPropagation()"></ng1-checkbox>
</div>
diff --git a/catalog-ui/src/app/directives/loader/loader-directive.ts b/catalog-ui/src/app/directives/loader/loader-directive.ts
index 7e056c7..cb17c0b 100644
--- a/catalog-ui/src/app/directives/loader/loader-directive.ts
+++ b/catalog-ui/src/app/directives/loader/loader-directive.ts
@@ -126,11 +126,13 @@
scope.$watch("display", (newVal, oldVal) => {
element.css('display', 'none');
+ let timeout;
if (newVal === true) {
- window.setTimeout(():void => {
+ timeout = window.setTimeout(():void => {
element.css('display', 'block');
}, 500);
} else {
+ window.clearTimeout(timeout);
window.setTimeout(():void => {
element.css('display', 'none');
}, 0);
diff --git a/catalog-ui/src/app/directives/prevent-double-click/prevent-double-click.ts b/catalog-ui/src/app/directives/prevent-double-click/prevent-double-click.ts
new file mode 100644
index 0000000..fff25c4
--- /dev/null
+++ b/catalog-ui/src/app/directives/prevent-double-click/prevent-double-click.ts
@@ -0,0 +1,41 @@
+/**
+ * Created by ob0695 on 5/15/2018.
+ */
+'use strict';
+
+export class PreventDoubleClickDirective implements ng.IDirective {
+
+ constructor(private $timeout:ng.ITimeoutService) {
+ }
+
+ restrict:'A';
+
+ link = (scope, elem) => {
+
+ let delay = 600;
+ let disabled = false;
+
+ scope.onClick = (evt) => {
+ if (disabled) {
+ evt.preventDefault();
+ evt.stopImmediatePropagation();
+ } else {
+ disabled = true;
+ this.$timeout(function () {
+ disabled = false;
+ }, delay, false);
+ }
+ }
+
+ scope.$on('$destroy', function () {
+ elem.off('click', scope.onClick);
+ });
+ elem.on('click', scope.onClick);
+ };
+
+ public static factory = ($timeout:ng.ITimeoutService) => {
+ return new PreventDoubleClickDirective($timeout);
+ }
+}
+
+PreventDoubleClickDirective.factory.$inject = ['$timeout'];
\ No newline at end of file
diff --git a/catalog-ui/src/app/filters.ts b/catalog-ui/src/app/filters.ts
index 4ccf3bc..10194b5 100644
--- a/catalog-ui/src/app/filters.ts
+++ b/catalog-ui/src/app/filters.ts
@@ -21,7 +21,6 @@
/**
* Created by ob0695 on 2/26/2017.
*/
-export * from './filters/catalog-status-filter';
export * from './filters/category-type-filter';
export * from './filters/clear-whitespaces-filter';
export * from './filters/entity-filter';
diff --git a/catalog-ui/src/app/filters/resource-type-filter.ts b/catalog-ui/src/app/filters/resource-type-filter.ts
index 70abf81..51bf071 100644
--- a/catalog-ui/src/app/filters/resource-type-filter.ts
+++ b/catalog-ui/src/app/filters/resource-type-filter.ts
@@ -27,7 +27,7 @@
let filter = <ResourceTypeFilter>(resourceType:string) => {
let uiConfiguration:any = cacheService.get('UIConfiguration');
- if (uiConfiguration.resourceTypes && uiConfiguration.resourceTypes[resourceType]) {
+ if (uiConfiguration && uiConfiguration.resourceTypes && uiConfiguration.resourceTypes[resourceType]) {
return uiConfiguration.resourceTypes[resourceType];
}
return resourceType;
diff --git a/catalog-ui/src/app/models.ts b/catalog-ui/src/app/models.ts
index 3a48335..e5cc483 100644
--- a/catalog-ui/src/app/models.ts
+++ b/catalog-ui/src/app/models.ts
@@ -42,6 +42,8 @@
export * from './models/componentsInstances/resourceInstance';
export * from './models/componentsInstances/serviceInstance';
export * from './models/componentsInstances/serviceProxyInstance';
+export * from './models/graph/zones/group-instance';
+export * from './models/graph/zones/policy-instance';
export * from './models/csar-component';
//export * from './models/data-type-properties';
export * from './models/properties-inputs/property-be-model';
diff --git a/catalog-ui/src/app/models/app-config.ts b/catalog-ui/src/app/models/app-config.ts
index 54c059a..a0ebb54 100644
--- a/catalog-ui/src/app/models/app-config.ts
+++ b/catalog-ui/src/app/models/app-config.ts
@@ -128,8 +128,7 @@
}
export interface IConfigRole {
- pages:Array<string>;
- states:IConfigState;
+ changeLifecycleStateButtons:any;
}
export interface IConfigState {
@@ -222,6 +221,11 @@
email:string;
}
+export interface IComponentType {
+ RESOURCE:any;
+ SERVICE:any;
+}
+
export interface IAppMenu {
roles:IConfigRoles;
confirmationMessages:IConfirmationMessages;
diff --git a/catalog-ui/src/app/models/catalogSelector.ts b/catalog-ui/src/app/models/catalogSelector.ts
new file mode 100644
index 0000000..b3a7aa3
--- /dev/null
+++ b/catalog-ui/src/app/models/catalogSelector.ts
@@ -0,0 +1,14 @@
+/* added Michael */
+// export interface ILeftSwitchItemModel {
+export interface ICatalogSelector{
+ value: CatalogSelectorTypes;
+ title: string;
+ header: string;
+ hidden?: number;
+ disabled?: number;
+}
+
+export enum CatalogSelectorTypes {
+ Active,
+ Archive,
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/models/category.ts b/catalog-ui/src/app/models/category.ts
index e45100a..0d5c63b 100644
--- a/catalog-ui/src/app/models/category.ts
+++ b/catalog-ui/src/app/models/category.ts
@@ -22,8 +22,7 @@
-export class ICategoryBase {
-
+export interface ICategoryBase {
//server properties
name:string;
normalizedName:string;
@@ -34,32 +33,13 @@
filterTerms:string;
isDisabled:boolean;
filteredGroup:Array<IGroup>;
-
- constructor(category?:ICategoryBase) {
- if (category) {
- this.name = category.name;
- this.normalizedName = category.normalizedName;
- this.icons = category.icons;
- this.filterTerms = category.filterTerms;
- this.isDisabled = category.isDisabled;
- this.filteredGroup = category.filteredGroup;
- }
- }
}
-export class IMainCategory extends ICategoryBase {
+export interface IMainCategory extends ICategoryBase {
subcategories:Array<ISubCategory>;
-
- constructor();
- constructor(category?:IMainCategory) {
- super(category);
- if (category) {
- this.subcategories = category.subcategories;
- }
- }
}
-export class ISubCategory extends ICategoryBase {
+export interface ISubCategory extends ICategoryBase {
groupings:Array<ICategoryBase>;
}
diff --git a/catalog-ui/src/app/models/component-metadata.ts b/catalog-ui/src/app/models/component-metadata.ts
index 1545739..9f5e22c 100644
--- a/catalog-ui/src/app/models/component-metadata.ts
+++ b/catalog-ui/src/app/models/component-metadata.ts
@@ -47,6 +47,8 @@
public highestVersion:boolean;
public normalizedName:string;
public systemName:string;
+ public archived:boolean;
+ public vspArchived: boolean;
//Resource only
public resourceType: string;
@@ -66,9 +68,11 @@
public serviceType:string;
public serviceRole:string;
public environmentContext:string;
+ public instantiationType:string;
- //backend lifecycleState
+
+ //backend lifecycleState
public state:string;
deserialize (response): ComponentMetadata {
@@ -111,6 +115,9 @@
this.serviceType = response.serviceType;
this.serviceRole = response.serviceRole;
this.environmentContext = response.environmentContext;
+ this.archived = response.archived;
+ this.instantiationType = response.instantiationType;
+ this.vspArchived = response.vspArchived;
return this;
}
diff --git a/catalog-ui/src/app/models/components/component.ts b/catalog-ui/src/app/models/components/component.ts
index adcf498..8f0fa33 100644
--- a/catalog-ui/src/app/models/components/component.ts
+++ b/catalog-ui/src/app/models/components/component.ts
@@ -34,6 +34,7 @@
import {Requirement} from "../requirement";
import {Relationship} from "../graph/relationship";
import { PolicyInstance } from "app/models/graph/zones/policy-instance";
+import { GroupInstance } from "../graph/zones/group-instance";
// import {}
@@ -96,8 +97,12 @@
getModuleForDisplay(moduleId:string):ng.IPromise<DisplayModule>;
getModuleInstanceForDisplay(componentInstanceId:string, moduleId:string):ng.IPromise<DisplayModule>;
updateGroupMetadata(group:Module):ng.IPromise<Module>;
+
+
//---------------------------------------------- HELP FUNCTIONS ----------------------------------------------------//
+
+
getComponentSubType():string;
isAlreadyCertified():boolean;
isService():boolean;
@@ -158,7 +163,8 @@
public systemName:string;
public projectCode:string;
public policies:Array<PolicyInstance>;
- public groups:Array<Module>;
+ public groupInstances:Array<GroupInstance>
+ public modules:Array<Module>;
//custom properties
public componentService:IComponentService;
public filterTerm:string;
@@ -168,7 +174,8 @@
public subCategory:string;
public selectedCategory:string;
public showMenu:boolean;
-
+ public archived:boolean;
+ public vspArchived: boolean;
constructor(componentService:IComponentService, protected $q:ng.IQService, component?:Component) {
if (component) {
@@ -221,7 +228,11 @@
this.selectedInstance = component.selectedInstance;
this.iconSprite = component.iconSprite;
this.showMenu = true;
- this.groups = CommonUtils.initModules(component.groups);
+ this.modules = component.modules;
+ this.groupInstances = component.groupInstances;
+ this.policies = component.policies;
+ this.archived = component.archived;
+ this.vspArchived = component.vspArchived;
}
//custom properties
@@ -239,7 +250,7 @@
//------------------------------------------ API Calls ----------------------------------------------------------------//
public changeLifecycleState = (state:string, commentObj:AsdcComment):ng.IPromise<Component> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Component>();
let onSuccess = (componentMetadata:ComponentMetadata):void => {
this.setComponentMetadata(componentMetadata);
// this.version = componentMetadata.version;
@@ -277,7 +288,7 @@
};
public addOrUpdateArtifact = (artifact:ArtifactModel):ng.IPromise<ArtifactModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ArtifactModel>();
let onSuccess = (artifactObj:ArtifactModel):void => {
let newArtifact = new ArtifactModel(artifactObj);
let artifacts = this.getArtifactsByType(artifactObj.artifactGroupType);
@@ -309,7 +320,7 @@
public deleteArtifact = (artifactId:string, artifactLabel:string):ng.IPromise<ArtifactModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ArtifactModel>();
let onSuccess = (artifactObj:ArtifactModel):void => {
let newArtifact = new ArtifactModel(artifactObj);
let artifacts = this.getArtifactsByType(artifactObj.artifactGroupType);
@@ -327,7 +338,7 @@
public getArtifactByGroupType = (artifactGroupType:string):ng.IPromise<ArtifactGroupModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ArtifactGroupModel>();
let onSuccess = (response:ArtifactGroupModel):void => {
deferred.resolve(response);
};
@@ -340,7 +351,7 @@
public getComponentInstanceArtifactsByGroupType = (componentInstanceId:string, artifactGroupType:string):ng.IPromise<ArtifactGroupModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ArtifactGroupModel>();
let onSuccess = (response:ArtifactGroupModel):void => {
deferred.resolve(response);
};
@@ -352,7 +363,7 @@
};
public addOrUpdateProperty = (property:PropertyModel):ng.IPromise<PropertyModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<PropertyModel>();
let onError = (error:any):void => {
deferred.reject(error);
@@ -380,7 +391,7 @@
};
public addOrUpdateAttribute = (attribute:AttributeModel):ng.IPromise<AttributeModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<AttributeModel>();
let onError = (error:any):void => {
deferred.reject(error);
@@ -408,7 +419,7 @@
};
public deleteProperty = (propertyId:string):ng.IPromise<PropertyModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<PropertyModel>();
let onSuccess = ():void => {
console.log("Property deleted");
delete _.remove(this.properties, {uniqueId: propertyId})[0];
@@ -423,7 +434,7 @@
};
public deleteAttribute = (attributeId:string):ng.IPromise<AttributeModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<AttributeModel>();
let onSuccess = ():void => {
console.log("Attribute deleted");
delete _.remove(this.attributes, {uniqueId: attributeId})[0];
@@ -435,18 +446,23 @@
return deferred.promise;
};
+
+ public updateInstancePropertiesSuccess = (newProperties:PropertyModel[]):void => {
+ newProperties.forEach((newProperty) => {
+ // find exist instance property in parent component for update the new value ( find bu uniqueId & path)
+ let existProperty: PropertyModel = <PropertyModel>_.find(this.componentInstancesProperties[newProperty.resourceInstanceUniqueId], {
+ uniqueId: newProperty.uniqueId,
+ path: newProperty.path
+ });
+ let index = this.componentInstancesProperties[newProperty.resourceInstanceUniqueId].indexOf(existProperty);
+ this.componentInstancesProperties[newProperty.resourceInstanceUniqueId][index] = newProperty;
+ });
+ }
+
public updateInstanceProperties = (componentInstanceId:string, properties:PropertyModel[]):ng.IPromise<PropertyModel[]> => {
let deferred = this.$q.defer<PropertyModel[]>();
let onSuccess = (newProperties:PropertyModel[]):void => {
- newProperties.forEach((newProperty) => {
- // find exist instance property in parent component for update the new value ( find bu uniqueId & path)
- let existProperty: PropertyModel = <PropertyModel>_.find(this.componentInstancesProperties[newProperty.resourceInstanceUniqueId], {
- uniqueId: newProperty.uniqueId,
- path: newProperty.path
- });
- let index = this.componentInstancesProperties[newProperty.resourceInstanceUniqueId].indexOf(existProperty);
- this.componentInstancesProperties[newProperty.resourceInstanceUniqueId][index] = newProperty;
- });
+ this.updateInstancePropertiesSuccess(newProperties);
deferred.resolve(newProperties);
};
let onFailed = (error:any):void => {
@@ -458,7 +474,7 @@
};
public updateInstanceAttribute = (attribute:AttributeModel):ng.IPromise<AttributeModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<AttributeModel>();
let onSuccess = (newAttribute:AttributeModel):void => {
let existAttribute:AttributeModel = <AttributeModel>_.find(this.componentInstancesAttributes[newAttribute.resourceInstanceUniqueId], {uniqueId: newAttribute.uniqueId});
let index = this.componentInstancesAttributes[newAttribute.resourceInstanceUniqueId].indexOf(existAttribute);
@@ -478,7 +494,7 @@
};
public deleteInstanceArtifact = (artifactId:string, artifactLabel:string):ng.IPromise<ArtifactModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ArtifactModel>();
let onSuccess = (artifactObj:ArtifactModel):void => {
let newArtifact = new ArtifactModel(artifactObj);
let artifacts = this.selectedInstance.deploymentArtifacts;
@@ -495,7 +511,7 @@
};
public addOrUpdateInstanceArtifact = (artifact:ArtifactModel):ng.IPromise<ArtifactModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ArtifactModel>();
let onSuccess = (artifactObj:ArtifactModel):void => {
switch (artifactObj.artifactGroupType) {
case ArtifactGroupType.DEPLOYMENT:
@@ -519,7 +535,7 @@
};
public uploadInstanceEnvFile = (artifact:ArtifactModel):ng.IPromise<ArtifactModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ArtifactModel>();
let onSuccess = (artifactObj:ArtifactModel):void => {
this.selectedInstance.deploymentArtifacts[artifactObj.artifactLabel] = artifactObj;
deferred.resolve(artifactObj);
@@ -533,7 +549,7 @@
//this function will update the instance version than the function call getComponent to update the current component and return the new instance version
public changeComponentInstanceVersion = (componentUid:string):ng.IPromise<Component> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Component>();
let onFailed = (error:any):void => {
deferred.reject(error);
};
@@ -553,7 +569,7 @@
};
public createComponentInstance = (componentInstance:ComponentInstance):ng.IPromise<ComponentInstance> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ComponentInstance>();
let onSuccess = (instance:ComponentInstance):void => {
this.componentInstances.push(instance);
deferred.resolve(instance);
@@ -566,7 +582,7 @@
};
public updateComponentInstance = (componentInstance:ComponentInstance):ng.IPromise<ComponentInstance> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ComponentInstance>();
let onSuccess = (updatedInstance:ComponentInstance):void => {
let componentInstance:ComponentInstance = _.find(this.componentInstances, (instance:ComponentInstance) => {
return instance.uniqueId === updatedInstance.uniqueId;
@@ -585,7 +601,7 @@
};
public updateMultipleComponentInstances = (instances:Array<ComponentInstance>):ng.IPromise<Array<ComponentInstance>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<ComponentInstance>>();
let onSuccess = (updatedInstances:Array<ComponentInstance>):void => {
_.forEach(updatedInstances, (updatedComponentInstance) => {
let componentInstance:ComponentInstance = _.find(this.componentInstances, (instance:ComponentInstance) => {
@@ -607,13 +623,13 @@
};
public deleteComponentInstance = (componentInstanceId:string):ng.IPromise<ComponentInstance> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ComponentInstance>();
let onSuccess = ():void => {
let onSuccess = (component:Component):void => {
this.componentInstances = CommonUtils.initComponentInstances(component.componentInstances);
this.componentInstancesProperties = new PropertiesGroup(component.componentInstancesProperties);
this.componentInstancesAttributes = new AttributesGroup(component.componentInstancesAttributes);
- this.groups = component.groups;
+ this.modules = component.modules;
this.componentInstancesRelations = CommonUtils.initComponentInstanceRelations(component.componentInstancesRelations);
deferred.resolve();
};
@@ -680,7 +696,7 @@
};
public createRelation = (relation:RelationshipModel):ng.IPromise<RelationshipModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<RelationshipModel>();
let onSuccess = (relation:RelationshipModel):void => {
console.info('Link created successfully', relation);
if (!this.componentInstancesRelations) {
@@ -699,7 +715,7 @@
};
public deleteRelation = (relation:RelationshipModel):ng.IPromise<RelationshipModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<RelationshipModel>();
let onSuccess = (relation:RelationshipModel):void => {
console.log("Link Deleted In Server");
let relationToDelete = _.find(this.componentInstancesRelations, (item) => {
@@ -774,7 +790,7 @@
public getModuleForDisplay = (moduleId:string):ng.IPromise<DisplayModule> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<DisplayModule>();
let onSuccess = (response:DisplayModule):void => {
deferred.resolve(response);
};
@@ -787,7 +803,7 @@
public getModuleInstanceForDisplay = (componentInstanceId:string, moduleId:string):ng.IPromise<DisplayModule> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<DisplayModule>();
let onSuccess = (response:DisplayModule):void => {
deferred.resolve(response);
};
@@ -803,7 +819,7 @@
// get all the instances of the component (in service only VF instances)
public getComponentInstancesFilteredByInputsAndProperties = (searchText?:string):ng.IPromise<Array<ComponentInstance>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<ComponentInstance>>();
let onSuccess = (response:Array<ComponentInstance>):void => {
deferred.resolve(response);
};
@@ -818,7 +834,7 @@
// get inputs for instance - Pagination function
public getComponentInputs = ():ng.IPromise<Array<InputModel>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<InputModel>>();
let onSuccess = (inputsRes:Array<InputModel>):void => {
this.inputs = inputsRes;
deferred.resolve(inputsRes);
@@ -834,7 +850,7 @@
// get inputs instance - Pagination function
public getComponentInstanceInputs = (componentInstanceId:string, originComponentUid:string):ng.IPromise<Array<InputModel>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<InputModel>>();
let onSuccess = (response:Array<InputModel>):void => {
deferred.resolve(response);
};
@@ -848,7 +864,7 @@
// get inputs inatnce - Pagination function
public getComponentInstanceInputProperties = (componentInstanceId:string, inputId:string):ng.IPromise<Array<PropertyModel>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<PropertyModel>>();
let onSuccess = (response:Array<PropertyModel>):void => {
deferred.resolve(response);
};
@@ -862,7 +878,7 @@
// get inputs inatnce - Pagination function
public getComponentInstanceProperties = (componentInstanceId:string):ng.IPromise<Array<PropertyModel>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<PropertyModel>>();
let onSuccess = (response:Array<PropertyModel>):void => {
deferred.resolve(response);
};
@@ -876,15 +892,15 @@
public updateGroupMetadata = (module:Module):ng.IPromise<Module> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Module>();
let onSuccess = (updatedModule:Module):void => {
- let groupIndex:number = _.indexOf(this.groups, _.find(this.groups, (module:Module) => {
+ let groupIndex:number = _.indexOf(this.modules, _.find(this.modules, (module:Module) => {
return module.uniqueId === updatedModule.uniqueId;
}));
if (groupIndex !== -1) {
- this.groups[groupIndex] = updatedModule;
+ this.modules[groupIndex] = updatedModule;
}
deferred.resolve(updatedModule);
};
@@ -1022,7 +1038,8 @@
this.systemName = componentMetadata.systemName;
this.projectCode = componentMetadata.projectCode;
this.categories = componentMetadata.categories;
-
+ this.archived = componentMetadata.archived || false;
+ this.vspArchived = componentMetadata.vspArchived;
}
public toJSON = ():any => {
@@ -1036,6 +1053,9 @@
temp.showMenu = undefined;
temp.$q = undefined;
temp.selectedCategory = undefined;
+ temp.modules = undefined
+ temp.groupInstances = undefined;
+ temp.policies = undefined;
return temp;
};
}
diff --git a/catalog-ui/src/app/models/components/displayComponent.ts b/catalog-ui/src/app/models/components/displayComponent.ts
index c894903..f96e0bf 100644
--- a/catalog-ui/src/app/models/components/displayComponent.ts
+++ b/catalog-ui/src/app/models/components/displayComponent.ts
@@ -22,7 +22,6 @@
*/
'use strict';
-import * as _ from "lodash";
import {ComponentType} from "../../utils/constants";
import {ComponentMetadata} from "../component-metadata";
import {PolicyMetadata} from "../policy-metadata";
@@ -48,6 +47,7 @@
searchFilterTerms:string;
certifiedIconClass:string;
icon:string;
+ isDraggable:boolean;
isRequirmentAndCapabilitiesLoaded:boolean;
uuid:string;
@@ -64,7 +64,7 @@
categoryType:LeftPaletteMetadataTypes;
- constructor(metadataType: LeftPaletteMetadataTypes, item: ComponentMetadata | PolicyMetadata) {
+ constructor(metadataType: LeftPaletteMetadataTypes, item: ComponentMetadata | PolicyMetadata | GroupMetadata) {
if (metadataType === LeftPaletteMetadataTypes.Policy) {
this.initPolicy(item as PolicyMetadata);
return;
@@ -94,6 +94,7 @@
this.componentType = component.componentType;
this.systemName = component.systemName;
this.invariantUUID = component.invariantUUID;
+ this.isDraggable = true;
if (component.categories && component.categories[0] && component.categories[0].subcategories && component.categories[0].subcategories[0]) {
this.mainCategory = component.categories[0].name;
@@ -118,7 +119,7 @@
this.categoryType = LeftPaletteMetadataTypes.Group;
this.uniqueId = group.uniqueId;
- this.displayName = group.type;
+ this.displayName = group.name;
this.mainCategory = "Groups";
this.subCategory = "Groups";
this.iconClass = "sprite-group-icons group";
@@ -127,14 +128,15 @@
this.type = group.type;
this.componentSubType = 'GROUP';
- this.searchFilterTerms = this.displayName + ' ' + group.description + ' ' + group.version;
+ this.searchFilterTerms = this.type + ' ' + group.name + ' ' + group.version;
+ this.isDraggable = false;
}
private initPolicy(policy:PolicyMetadata): void {
this.categoryType = LeftPaletteMetadataTypes.Policy;
this.uniqueId = policy.uniqueId;
- this.displayName = policy.type;
+ this.displayName = policy.name;
this.mainCategory = "Policies";
this.subCategory = "Policies";
this.iconClass = "sprite-policy-icons policy";
@@ -143,7 +145,8 @@
this.type = policy.type;
this.componentSubType = 'POLICY';
- this.searchFilterTerms = this.displayName + ' ' + policy.description + ' ' + policy.version;
+ this.searchFilterTerms = this.type + ' ' + policy.name + ' ' + policy.version;
+ this.isDraggable = false;
}
public initDisplayName = (name:string):void => {
diff --git a/catalog-ui/src/app/models/components/resource.ts b/catalog-ui/src/app/models/components/resource.ts
index 5bd80e3..733f2ff 100644
--- a/catalog-ui/src/app/models/components/resource.ts
+++ b/catalog-ui/src/app/models/components/resource.ts
@@ -104,7 +104,7 @@
};
public createComponentOnServer = ():ng.IPromise<Component> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Component>();
let onSuccess = (component:Resource):void => {
this.payloadData = undefined;
this.payloadName = undefined;
@@ -125,7 +125,7 @@
public updateResourceGroupProperties = (module:DisplayModule, properties:Array<PropertyModel>):ng.IPromise<Array<PropertyModel>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<PropertyModel>>();
let onSuccess = (updatedProperties:Array<PropertyModel>):void => {
_.forEach(updatedProperties, (property:PropertyModel) => { // Replace all updated properties on the module we needed to update
_.extend(_.find(module.properties, {uniqueId: property.uniqueId}), property);
@@ -144,7 +144,7 @@
// For now we only implement the logic in service level
public createInputsFormInstances = (instanceInputsPropertiesMap:InstancesInputsOrPropertiesMapData):ng.IPromise<Array<InputModel>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<InputModel>>();
return deferred.promise;
};
@@ -175,6 +175,9 @@
temp.$q = undefined;
temp.selectedCategory = undefined;
temp.importedFile = undefined;
+ temp.modules = undefined;
+ temp.groupInstances = undefined;
+ temp.policies = undefined;
return temp;
};
}
diff --git a/catalog-ui/src/app/models/components/service.ts b/catalog-ui/src/app/models/components/service.ts
index 439925f..a947e81 100644
--- a/catalog-ui/src/app/models/components/service.ts
+++ b/catalog-ui/src/app/models/components/service.ts
@@ -39,6 +39,7 @@
public serviceType:string;
public serviceRole:string;
public environmentContext:string;
+ public instantiationType:string;
public forwardingPaths:{ [key:string]:ForwardingPath } = {};
constructor(componentService:IServiceService, $q:ng.IQService, component?:Service) {
@@ -51,6 +52,7 @@
this.namingPolicy = component.namingPolicy;
this.serviceType = component.serviceType;
this.serviceRole = component.serviceRole;
+ this.instantiationType = component.instantiationType;
this.environmentContext = component.environmentContext;
if (component.categories && component.categories[0]) {
this.mainCategory = component.categories[0].name;
@@ -78,7 +80,7 @@
*/
public createInputsFormInstances = (instancesInputsMap:InstancesInputsOrPropertiesMapData, instancePropertiesMap:InstancesInputsOrPropertiesMapData):ng.IPromise<Array<InputModel>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<InputModel>>();
let onSuccess = (inputsCreated:Array<InputModel>):void => {
this.inputs = inputsCreated.concat(this.inputs);
deferred.resolve(inputsCreated);
@@ -94,8 +96,8 @@
};
// we need to change the name of the input to vfInstanceName + input name before sending to server in order to create the inputs on the service
- public getServiceInputInputsAndProperties = (inputId:string):ng.IPromise<Array<InputModel>> => {
- let deferred = this.$q.defer();
+ public getServiceInputInputsAndProperties = (inputId:string):ng.IPromise<InputsAndProperties> => {
+ let deferred = this.$q.defer<InputsAndProperties>();
let onSuccess = (inputsAndProperties:InputsAndProperties):void => {
let input:InputModel = _.find(this.inputs, (input:InputModel) => {
return input.uniqueId === inputId;
@@ -112,7 +114,7 @@
};
public deleteServiceInput = (inputId:string):ng.IPromise<InputModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<InputModel>();
let onSuccess = (deletedInput:InputModel):void => {
delete _.remove(this.inputs, {uniqueId: deletedInput.uniqueId})[0];
@@ -140,7 +142,7 @@
public updateGroupInstanceProperties = (resourceInstanceId:string, group:DisplayModule, properties:Array<PropertyModel>):ng.IPromise<Array<PropertyModel>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<PropertyModel>>();
let onSuccess = (updatedProperties:Array<PropertyModel>):void => {
_.forEach(updatedProperties, (property:PropertyModel) => { // Replace all updated properties on the we needed to update
_.extend(_.find(group.properties, {uniqueId: property.uniqueId}), property);
@@ -167,6 +169,7 @@
this.serviceType = componentMetadata.serviceType;
this.serviceRole = componentMetadata.serviceRole;
this.environmentContext = componentMetadata.environmentContext;
+ this.instantiationType = componentMetadata.instantiationType;
this.setComponentDisplayData();
}
@@ -178,5 +181,21 @@
}
this.iconSprite = "sprite-services-icons";
}
+
+ public toJSON = ():any => {
+ let temp = angular.copy(this);
+ temp.componentService = undefined;
+ temp.filterTerm = undefined;
+ temp.iconSprite = undefined;
+ temp.mainCategory = undefined;
+ temp.subCategory = undefined;
+ temp.selectedInstance = undefined;
+ temp.showMenu = undefined;
+ temp.$q = undefined;
+ temp.selectedCategory = undefined;
+ temp.modules = undefined;
+ temp.groupInstances = undefined;
+ return temp;
+ };
}
diff --git a/catalog-ui/src/app/models/componentsInstances/componentInstance.ts b/catalog-ui/src/app/models/componentsInstances/componentInstance.ts
index e8444b3..fcc3298 100644
--- a/catalog-ui/src/app/models/componentsInstances/componentInstance.ts
+++ b/catalog-ui/src/app/models/componentsInstances/componentInstance.ts
@@ -60,6 +60,7 @@
public properties:Array<PropertyModel>;
public groupInstances:Array<Module>;
public invariantName:string;
+ public originArchived:boolean;
constructor(componentInstance?:ComponentInstance) {
@@ -90,6 +91,7 @@
this.sourceModelName = componentInstance.sourceModelName;
this.sourceModelUid = componentInstance.sourceModelUid;
this.sourceModelUuid = componentInstance.sourceModelUuid;
+ this.originArchived = componentInstance.originArchived;
}
}
@@ -171,4 +173,8 @@
temp.capabilities = undefined;
return temp;
};
+
+ public get iconClass() {
+ return this.iconSprite + ' ' + this.icon;
+ }
}
diff --git a/catalog-ui/src/app/models/graph/nodes/common-ci-node-base.ts b/catalog-ui/src/app/models/graph/nodes/common-ci-node-base.ts
index fb051c8..dfd39d1 100644
--- a/catalog-ui/src/app/models/graph/nodes/common-ci-node-base.ts
+++ b/catalog-ui/src/app/models/graph/nodes/common-ci-node-base.ts
@@ -22,6 +22,7 @@
export abstract class CommonCINodeBase extends CommonNodeBase {
public certified:boolean;
+ public archived:boolean;
public template:string;
public componentInstance:ComponentInstance;
public group:string;
@@ -34,6 +35,7 @@
this.img = '';
this.certified = this.isCertified(this.componentInstance.componentVersion);
this.displayName = instance.name;
+ this.archived = instance.originArchived;
}
private isCertified(version:string):boolean {
diff --git a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-base.ts b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-base.ts
index 3b634b1..a241423 100644
--- a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-base.ts
+++ b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-base.ts
@@ -20,7 +20,7 @@
import {ComponentInstance} from "../../../componentsInstances/componentInstance";
import {CommonCINodeBase} from "../common-ci-node-base";
-import {ImageCreatorService} from "app/directives/graphs-v2/image-creator/image-creator.service";
+import {ICanvasImage, ImageCreatorService} from "app/directives/graphs-v2/image-creator/image-creator.service";
import {ImagesUrl, GraphUIObjects} from "app/utils";
import {AngularJSBridge} from "app/services";
@@ -42,47 +42,72 @@
}
private init() {
-
this.displayName = this.getDisplayName();
this.isUcpe = false;
this.isGroup = false;
this.isUcpePart = false;
this.isInsideGroup = false;
}
+
+
+ public setUncertifiedImageBgStyle(node:Cy.Collection, nodeMinSize:number):string {
- public initUncertifiedImage(node:Cy.Collection, nodeMinSize:number):string {
-
let uncertifiedIconWidth:number = GraphUIObjects.HANDLE_SIZE;
let nodeWidth:number = node.data('imgWidth') || node.width();
let uncertifiedCanvasWidth: number = nodeWidth;
-
+
if (nodeWidth < nodeMinSize) { //uncertified icon will overlap too much of the node, need to expand canvas.
uncertifiedCanvasWidth = nodeWidth + uncertifiedIconWidth/2; //expand canvas so that only half of the icon overlaps with the node
}
-
+
+ const x = uncertifiedCanvasWidth - nodeWidth, y = x, width = nodeWidth, height = width;
+
+ const canvasImages:ICanvasImage[] = [
+ { src: this.imagesPath + this.componentInstance.icon + '.png', x, y, width, height},
+ { src: this.imagesPath + 'uncertified.png', x: 0, y: 0, width: uncertifiedIconWidth, height: uncertifiedIconWidth}
+ ];
- this.imageCreator.getImageBase64(this.imagesPath + this.componentInstance.icon + '.png',
- this.imagesPath + 'uncertified.png', nodeWidth, uncertifiedCanvasWidth, uncertifiedIconWidth)
- .then(imageBase64 => {
- this.img = imageBase64;
- node.style({
- 'background-image': this.img,
- 'background-width': uncertifiedCanvasWidth,
- 'background-height': uncertifiedCanvasWidth,
- 'width': uncertifiedCanvasWidth,
- 'height': uncertifiedCanvasWidth
- });
- });
+ //Create the image and update the node background styles
+ this.imageCreator.getMultiLayerBase64Image(canvasImages, uncertifiedCanvasWidth, uncertifiedCanvasWidth).then(img => this.updateNodeStyles(node,uncertifiedCanvasWidth,img));
+ return this.img; // Return the referance to the image (in Base64 format)
+ }
- return this.img;
+
+ public setArchivedImageBgStyle(node:Cy.Collection, nodeMinSize:number):string {
+ let archivedIconWidth:number = GraphUIObjects.HANDLE_SIZE;
+ let nodeWidth:number = node.data('imgWidth') || node.width();
+ let archivedCanvasWidth: number = nodeWidth;
+
+ const x = archivedCanvasWidth - nodeWidth, y = x, width = nodeWidth, height = width;
+ const archiveImage = nodeWidth < 50? 'archive_small.png':'archive_big.png';
+
+ const canvasImages = [
+ { src: this.imagesPath + this.componentInstance.icon + '.png', x, y, width, height},
+ { src: AngularJSBridge.getAngularConfig().imagesPath + ImagesUrl.RESOURCE_ICONS + archiveImage, x, y, width, height}
+ ];
+
+ //Create the image and update the node background styles
+ this.imageCreator.getMultiLayerBase64Image(canvasImages, archivedCanvasWidth, archivedCanvasWidth).then(img => this.updateNodeStyles(node, archivedCanvasWidth, img));
+ return this.img; // Return the default img
}
protected getDisplayName():string {
-
let graphResourceName = AngularJSBridge.getFilter('graphResourceName');
let resourceName = AngularJSBridge.getFilter('resourceName');
return graphResourceName(resourceName(this.componentInstance.name));
}
+ //TODO:: move to Base class ???
+ private updateNodeStyles(node,canvasWidth,imageBase64){
+ this.img = imageBase64;
+ node.style({
+ 'background-image': this.img,
+ 'background-width': canvasWidth,
+ 'background-height': canvasWidth,
+ 'background-position-x':0,
+ 'background-position-y':0
+ });
+ }
+
}
diff --git a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-configuration.ts b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-configuration.ts
index 1182f5e..78bcc17 100644
--- a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-configuration.ts
+++ b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-configuration.ts
@@ -35,5 +35,8 @@
this.imgWidth = GraphUIObjects.SMALL_RESOURCE_WIDTH;
this.type = "basic-small-node";
this.classes = 'configuration-node';
+ if(this.archived){
+ this.classes = this.classes + ' archived';
+ }
}
}
diff --git a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-cp.ts b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-cp.ts
index 3bd5769..05a6d79 100644
--- a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-cp.ts
+++ b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-cp.ts
@@ -44,9 +44,12 @@
} else {
this.classes = 'cp-node';
}
+ if(this.archived){
+ this.classes = this.classes + ' archived';
+ return;
+ }
if (!this.certified) {
this.classes = this.classes + ' not-certified';
}
-
}
}
diff --git a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-service-proxy.ts b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-service-proxy.ts
index b993490..b025221 100644
--- a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-service-proxy.ts
+++ b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-service-proxy.ts
@@ -33,7 +33,11 @@
this.imagesPath = this.imagesPath + ImagesUrl.SERVICE_PROXY_ICONS;
this.img = this.imagesPath + this.componentInstance.icon + '.png';
this.imgWidth = GraphUIObjects.DEFAULT_RESOURCE_WIDTH;
- this.classes = 'service-node'
+ this.classes = 'service-node';
+ if(this.archived){
+ this.classes = this.classes + ' archived';
+ return;
+ }
if (!this.certified) {
this.classes = this.classes + ' not-certified';
}
diff --git a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-service.ts b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-service.ts
index b4e6ac3..bf8facf 100644
--- a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-service.ts
+++ b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-service.ts
@@ -33,10 +33,13 @@
this.imagesPath = this.imagesPath + ImagesUrl.SERVICE_ICONS;
this.img = this.imagesPath + ImagesUrl.SERVICE_ICONS + this.componentInstance.icon + '.png';
this.imgWidth = GraphUIObjects.DEFAULT_RESOURCE_WIDTH;
- this.classes = 'service-node'
+ this.classes = 'service-node';
+ if(this.archived){
+ this.classes = this.classes + ' archived';
+ return;
+ }
if (!this.certified) {
this.classes = this.classes + ' not-certified';
}
-
}
}
diff --git a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-ucpe.ts b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-ucpe.ts
index 3dd6a4e..d4172c0 100644
--- a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-ucpe.ts
+++ b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-ucpe.ts
@@ -38,7 +38,10 @@
this.type = 'ucpe-node';
this.allowConnection = false;
this.imagesPath = this.imagesPath + ImagesUrl.RESOURCE_ICONS;
-
+ if(this.archived){
+ this.classes = this.classes + ' archived';
+ return;
+ }
if (!this.certified) {
this.classes = this.classes + ' not-certified-ucpe';
}
diff --git a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-vf.ts b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-vf.ts
index b5ad57a..4aff85e 100644
--- a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-vf.ts
+++ b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-vf.ts
@@ -35,6 +35,10 @@
this.img = this.imagesPath + this.componentInstance.icon + '.png';
this.imgWidth = GraphUIObjects.DEFAULT_RESOURCE_WIDTH;
this.classes = 'vf-node';
+ if(this.archived){
+ this.classes = this.classes + ' archived';
+ return;
+ }
if (!this.certified) {
this.classes = this.classes + ' not-certified';
}
diff --git a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-vl.ts b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-vl.ts
index eded75d..a440f09 100644
--- a/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-vl.ts
+++ b/catalog-ui/src/app/models/graph/nodes/composition-graph-nodes/composition-ci-node-vl.ts
@@ -52,6 +52,10 @@
this.imagesPath = this.imagesPath + ImagesUrl.RESOURCE_ICONS;
this.classes = 'vl-node';
+ if(this.archived){
+ this.classes = this.classes + ' archived';
+ return;
+ }
if (!this.certified) {
this.classes = this.classes + ' not-certified';
}
diff --git a/catalog-ui/src/app/models/graph/zones/group-instance.ts b/catalog-ui/src/app/models/graph/zones/group-instance.ts
new file mode 100644
index 0000000..92d850b
--- /dev/null
+++ b/catalog-ui/src/app/models/graph/zones/group-instance.ts
@@ -0,0 +1,85 @@
+import {PropertyModel} from "app/models";
+import {CommonUtils} from "app/utils";
+import {IZoneInstanceAssignment} from "./zone-instance";
+import {ComponentInstance} from "../../componentsInstances/componentInstance";
+import {MemberUiObject} from "../../ui-models/ui-member-object";
+import * as _ from "lodash";
+
+export class GroupInstance {
+
+ public artifacts:Array<string>;
+ public artifactsUuid:Array<string>;
+ public description:string;
+ public empty:boolean;
+ public groupUUID:string;
+ public invariantUUID:string;
+ public members:Array<string>;
+ public name:string;
+ public ownerId:string;
+ public properties:Array<PropertyModel>;
+ public propertyValueCounter:number;
+ public type:string;
+ public typeUid:string;
+ public uniqueId:string;
+ public version:string;
+ public iconSprite:string;
+ public icon:string;
+ public originArchived?:boolean;
+
+
+ constructor(group:GroupInstance) {
+
+ this.name = group.name;
+ this.groupUUID = group.groupUUID;
+ this.invariantUUID = group.invariantUUID;
+ this.propertyValueCounter = group.propertyValueCounter;
+ this.type = group.type;
+ this.typeUid = group.typeUid;
+ this.uniqueId = group.uniqueId;
+ this.version = group.version;
+ this.artifacts = group.artifacts;
+ this.artifactsUuid = group.artifactsUuid;
+ this.properties = CommonUtils.initProperties(group.properties);
+ this.members = _.values(group.members);
+ this.description = group.description;
+ this.empty = group.empty;
+ this.ownerId = group.ownerId;
+
+ this.iconSprite = '';
+ this.icon = 'icon-group';
+ }
+
+ public getMembersAsUiObject(componentInstances?:Array<ComponentInstance>):Array<MemberUiObject> {
+ let savedItems:Array<MemberUiObject> = [];
+ if (!_.isEmpty(this.members)) {
+ _.forEach(this.members, (memberId:string)=> {
+ let componentInstance:ComponentInstance;
+ if (componentInstances) {
+ componentInstance = _.find(componentInstances, function (_componentInstance:ComponentInstance) {
+ return _componentInstance.uniqueId === memberId;
+ })
+ }
+ savedItems.push(new MemberUiObject(memberId, componentInstance ? componentInstance.name : undefined));
+ });
+ }
+ return savedItems;
+ };
+
+ public setMembers = (newMembers:Array<MemberUiObject>):void => {
+ this.members = newMembers.map(member => member.uniqueId);
+ };
+
+ // This function is used for the zone
+ public getSavedAssignments = ():Array<IZoneInstanceAssignment> => {
+ return this.getMembersAsUiObject();
+ };
+
+ public setSavedAssignments = (newMembers:Array<IZoneInstanceAssignment>):void => {
+ this.setMembers(newMembers);
+ };
+
+ public get iconClass() {
+ return this.iconSprite + ' ' + this.icon;
+ }
+
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/models/graph/zones/policy-instance.ts b/catalog-ui/src/app/models/graph/zones/policy-instance.ts
index 63136e6..c0a6678 100644
--- a/catalog-ui/src/app/models/graph/zones/policy-instance.ts
+++ b/catalog-ui/src/app/models/graph/zones/policy-instance.ts
@@ -1,8 +1,48 @@
import { PropertyModel } from "app/models";
import { CommonUtils } from "app/utils";
+import {IZoneInstanceMethod, IZoneInstanceAssignment} from "./zone-instance";
+import {GroupInstance} from "./group-instance";
+import {ComponentInstance} from "../../componentsInstances/componentInstance";
+import {TargetUiObject} from "../../ui-models/ui-target-object";
+import {TargetOrMemberType} from "../../../utils/constants";
+/* The request and response should be same model, need to fix in BE */
+export class PolicyTargetsMap {
+ COMPONENT_INSTANCES:Array<string>;
+ GROUPS:Array<string>;
+}
+//TODO remove this
+export class PolicyTargetsRequest {
-export class PolicyInstance {
+ requestItems:Array<PolicyTargetsRequestItem>;
+
+ constructor(groups:Array<string>,instances:Array<string>){
+
+ this.requestItems = [];
+
+ if (instances && instances.length>0) {
+ let instancesObj:PolicyTargetsRequestItem = {
+ type: "component_Instances",
+ uniqueIds: instances
+ };
+ this.requestItems.push(instancesObj);
+ }
+ if (groups && groups.length>0) {
+ let groupsObj:PolicyTargetsRequestItem = {
+ type: "groups",
+ uniqueIds: groups
+ };
+ this.requestItems.push(groupsObj);
+ }
+ }
+}
+
+export class PolicyTargetsRequestItem {
+ type: string;
+ uniqueIds:Array<String>;
+}
+
+export class PolicyInstance implements IZoneInstanceMethod {
componentName:string;
description:string;
empty:boolean;
@@ -12,13 +52,17 @@
name:string;
normalizedName:string;
- policyTypeName:string;
+ type:string;
policyTypeUid:string;
policyUUID:string;
properties:Array<PropertyModel>;
- targets:Array<string>;
+ targets:PolicyTargetsMap;
uniqueId:string;
version:string;
+ iconSprite:string;
+ icon:string;
+ originArchived:boolean;
+
constructor(policy?:PolicyInstance) {
this.componentName = policy.componentName;
@@ -30,7 +74,7 @@
this.name = policy.name;
this.normalizedName =policy.normalizedName;
- this.policyTypeName = policy.policyTypeName;
+ this.type = policy.type;
this.policyTypeUid = policy.policyTypeUid;
this.policyUUID = policy.policyUUID;
this.properties = CommonUtils.initProperties(policy.properties);
@@ -38,6 +82,57 @@
this.uniqueId = policy.uniqueId;
this.version = policy.version;
+ this.iconSprite = '';
+ this.icon = 'icon-policy';
+ }
+
+ public getTargetsAsUiObject(componentInstances?:Array<ComponentInstance>, groupInstances?:Array<GroupInstance>):Array<TargetUiObject> {
+ let savedItems:Array<TargetUiObject> = [];
+
+ //get all targets from component instances
+ if (!_.isEmpty(this.targets.COMPONENT_INSTANCES)) {
+ this.targets.COMPONENT_INSTANCES.forEach((targetInstanceId:string)=> {
+ let componentInstance:ComponentInstance;
+ if (componentInstances) {
+ componentInstance = _.find(componentInstances, function (_componentInstance:ComponentInstance) {
+ return _componentInstance.uniqueId === targetInstanceId;
+ })
+ }
+ savedItems.push(new TargetUiObject(targetInstanceId, TargetOrMemberType.COMPONENT_INSTANCES, componentInstance ? componentInstance.name : undefined));
+ });
+ }
+
+ //get all targets from groupInstances
+ if (!_.isEmpty(this.targets.GROUPS)) {
+ this.targets.GROUPS.forEach((groupsTargetId:string)=> {
+ let groupInstance:GroupInstance;
+ if (groupInstances) {
+ groupInstance = _.find(groupInstances, function (_groupInstance:GroupInstance) {
+ return _groupInstance.uniqueId === groupsTargetId;
+ })
+ }
+ savedItems.push(new TargetUiObject(groupsTargetId, TargetOrMemberType.GROUPS, groupInstance? groupInstance.name : undefined));
+ });
+ }
+ return savedItems;
+ };
+
+ public saveTargets = (newTargets:Array<TargetUiObject>):void => {
+ this.targets.COMPONENT_INSTANCES = newTargets.filter(target => target.type === TargetOrMemberType.COMPONENT_INSTANCES).map(target => target.uniqueId);
+ this.targets.GROUPS = newTargets.filter(target => target.type === TargetOrMemberType.GROUPS).map(target => target.uniqueId);
+ }
+
+ // This function is used for the zone to get and set the assignment
+ public getSavedAssignments = ():Array<IZoneInstanceAssignment> => {
+ return this.getTargetsAsUiObject();
+ };
+
+ public setSavedAssignments = (newMembers:Array<IZoneInstanceAssignment>):void => {
+ this.saveTargets(newMembers);
+ }
+
+ public get iconClass() {
+ return this.iconSprite + ' ' + this.icon;
}
}
\ No newline at end of file
diff --git a/catalog-ui/src/app/models/graph/zones/zone-child.ts b/catalog-ui/src/app/models/graph/zones/zone-child.ts
deleted file mode 100644
index d6d7198..0000000
--- a/catalog-ui/src/app/models/graph/zones/zone-child.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { Type, Component } from "@angular/core";
-import { PolicyInstance } from "app/models/graph/zones/policy-instance";
-
-export class ZoneConfig {
- title:string;
- defaultIconText:string;
- type:string; 'policy|group';
- tagModeId:string;
- instances:Array<ZoneInstanceConfig>;
- showZone:boolean;
-
-
- constructor (title:string, defaultText:string, type:string, showZone:boolean) {
- this.title = title;
- this.defaultIconText = defaultText;
- this.type = type;
- this.tagModeId = this.type + "-tagging";
- this.instances = [];
- this.showZone = showZone;
- }
-}
-
-export class ZoneInstanceConfig {
-
- name:string;
- assignments:Array<string>; //targets or members
- instanceData:PolicyInstance; // | GroupInstance;
- mode:ZoneInstanceMode;
-
- constructor(instance:PolicyInstance) { /* | GroupInstance */
-
- this.name = instance.name;
- this.instanceData = instance;
- this.mode = ZoneInstanceMode.NONE;
-
- if(instance instanceof PolicyInstance) {
- this.assignments = instance.targets;
- }
- }
-
-}
-
-export enum ZoneInstanceMode {
- NONE,
- HOVER,
- SELECTED,
- TAG
-}
\ No newline at end of file
diff --git a/catalog-ui/src/app/models/graph/zones/zone-instance.ts b/catalog-ui/src/app/models/graph/zones/zone-instance.ts
new file mode 100644
index 0000000..fb8ec77
--- /dev/null
+++ b/catalog-ui/src/app/models/graph/zones/zone-instance.ts
@@ -0,0 +1,106 @@
+import {PolicyInstance} from "app/models/graph/zones/policy-instance";
+import {GroupInstance} from "./group-instance";
+import {Component as TopologyTemplate} from "app/models";
+import {IUiBaseObject} from "../../ui-models/ui-base-object";
+import { Subject } from "rxjs";
+
+export enum ZoneInstanceMode {
+ NONE,
+ HOVER,
+ SELECTED,
+ TAG
+}
+
+export enum ZoneInstanceType {
+ GROUP,
+ POLICY
+}
+
+export enum ZoneInstanceAssignmentType {
+ COMPONENT_INSTANCES,
+ GROUPS
+}
+
+export interface IZoneInstanceMethod {
+
+ getSavedAssignments():Array<IZoneInstanceAssignment>;
+ setSavedAssignments(newAssignments:Array<IZoneInstanceAssignment>):void;
+}
+
+export interface IZoneInstanceAssignment extends IUiBaseObject{
+ type: ZoneInstanceAssignmentType
+}
+
+export class ZoneInstance {
+
+ parentComponentType:string;
+ parentComponentID:string;
+ instanceData: PolicyInstance | GroupInstance;
+ mode:ZoneInstanceMode;
+ type:ZoneInstanceType;
+ handle:string;
+ assignments:Array<IZoneInstanceAssignment>; //temp assignments visible on the UI; not the saved values on the BE
+ hidden:boolean;
+ forceSave:Subject<Function>;
+
+ constructor(instance: PolicyInstance | GroupInstance, topologyTemplate:TopologyTemplate) {
+
+ this.instanceData = instance;
+ this.parentComponentType = topologyTemplate.componentType;
+ this.parentComponentID = topologyTemplate.uniqueId;
+
+ if (instance instanceof PolicyInstance) {
+ this.type = ZoneInstanceType.POLICY;
+ } else {
+ this.type = ZoneInstanceType.GROUP;
+ }
+
+ this.assignments = this.instanceData.getSavedAssignments();
+ this.mode = ZoneInstanceMode.NONE;
+ this.hidden = false;
+ this.forceSave = new Subject();
+ }
+
+ public isAlreadyAssigned = (nodeId:string):boolean => {
+ let matchingAssignments = this.assignments.filter((assignment) => {
+ return assignment.uniqueId == nodeId;
+ });
+ return matchingAssignments && matchingAssignments.length > 0;
+ }
+
+ public addOrRemoveAssignment = (nodeId:string, nodeType:ZoneInstanceAssignmentType)=> { //change temp assignments, unsaved but visible in UI.
+
+ if (!this.isAlreadyAssigned(nodeId)) {
+ this.assignments.push(<IZoneInstanceAssignment>{uniqueId: nodeId, type: nodeType});
+ } else {
+ this.assignments = this.assignments.filter(assignment => assignment.uniqueId != nodeId);
+ }
+ }
+
+ public isZoneAssignmentChanged(oldAssignments:Array<IZoneInstanceAssignment>, newAssignments:Array<IZoneInstanceAssignment>):boolean {
+ if (oldAssignments.length != newAssignments.length) {
+ return true;
+ }
+ let difference:Array<IZoneInstanceAssignment> = oldAssignments.filter((oldAssignment) => {
+ return !newAssignments.find(newAssignment => newAssignment.uniqueId == oldAssignment.uniqueId);
+ });
+ if (difference.length) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public updateInstanceData (instanceData: PolicyInstance | GroupInstance):void {
+ this.instanceData = instanceData;
+ this.assignments = this.instanceData.getSavedAssignments();
+ }
+
+ public showHandle = (handleId:string) => {
+ this.handle = handleId;
+ }
+
+ public hideHandle = ():void => {
+ this.handle = null;
+ }
+}
diff --git a/catalog-ui/src/app/models/graph/zones/zone.ts b/catalog-ui/src/app/models/graph/zones/zone.ts
new file mode 100644
index 0000000..eaabc62
--- /dev/null
+++ b/catalog-ui/src/app/models/graph/zones/zone.ts
@@ -0,0 +1,46 @@
+/**
+ * Created by ob0695 on 10.04.2018.
+ */
+import {ZoneInstanceType, ZoneInstance, IZoneInstanceAssignment} from "./zone-instance";
+import {Observable} from "rxjs/Rx";
+import { CANVAS_TAG_MODE } from "app/utils/constants";
+
+export class Zone {
+ title:string;
+ type:ZoneInstanceType;
+ defaultIconText:string;
+ instances:Array<ZoneInstance>;
+ visible:boolean;
+ minimized:boolean;
+
+ constructor(title:string, defaultText:string, type:ZoneInstanceType) {
+ this.title = title;
+ this.defaultIconText = defaultText;
+ this.type = type;
+ this.instances = [];
+ this.visible = false;
+ this.minimized = false;
+ }
+
+
+ public getTagModeId = () => {
+ let tagModeId = ZoneInstanceType[this.type].toUpperCase();
+ return CANVAS_TAG_MODE[tagModeId + "_TAGGING"];
+ }
+
+ public getHoverTagModeId = () => {
+ let tagModeId = ZoneInstanceType[this.type].toUpperCase();
+ return CANVAS_TAG_MODE[tagModeId + "_TAGGING_HOVER"];
+ }
+
+ public removeInstance = (instanceId:string) => {
+ this.instances = this.instances.filter(instance => instance.instanceData.uniqueId != instanceId);
+ };
+}
+
+
+export interface IZoneService {
+ updateZoneInstanceAssignments(topologyTemplateType:string, topologyTemplateId:string, zoneInstanceId:string, assignments:Array<IZoneInstanceAssignment>):Observable<any>;
+ updateName(topologyTemplateType:string, topologyTemplateId:string, zoneInstanceId:string, newName:string):Observable<any>;
+ deleteZoneInstance(topologyTemplateType:string, topologyTemplateId:string, zoneInstanceId:string):Observable<any>;
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/models/group-metadata.ts b/catalog-ui/src/app/models/group-metadata.ts
index ecd6e3e..1c137ac 100644
--- a/catalog-ui/src/app/models/group-metadata.ts
+++ b/catalog-ui/src/app/models/group-metadata.ts
@@ -1,4 +1,6 @@
export class GroupMetadata {
+ public name:string;
+ public icon:string;
public uniqueId: string;
public type: string;
public version: string;
@@ -11,6 +13,8 @@
deserialize (response): GroupMetadata {
this.uniqueId = response.uniqueId;
this.type = response.type;
+ this.name = response.name;
+ this.icon = response.icon;
this.version = response.version;
this.description = response.description;
this.creationTime = response.creationTime;
diff --git a/catalog-ui/src/app/models/instance-fe-details.ts b/catalog-ui/src/app/models/instance-fe-details.ts
new file mode 100644
index 0000000..b0a6bac
--- /dev/null
+++ b/catalog-ui/src/app/models/instance-fe-details.ts
@@ -0,0 +1,5 @@
+export class InstanceFeDetails {
+ name: string;
+ iconClass: string;
+ originArchived: boolean;
+}
diff --git a/catalog-ui/src/app/models/modules/base-module.ts b/catalog-ui/src/app/models/modules/base-module.ts
index 63f4cc7..e27065b 100644
--- a/catalog-ui/src/app/models/modules/base-module.ts
+++ b/catalog-ui/src/app/models/modules/base-module.ts
@@ -43,7 +43,7 @@
public artifacts:Array<string> | Array<ArtifactModel>;
public artifactsUuid:Array<string>;
public properties:Array<PropertyModel>;
- public members:Array<string>;
+ public members:Map<string, string>;
public customizationUUID:string;
public groupInstanceUniqueId:string; // This will only have a value if this is a group instance
diff --git a/catalog-ui/src/app/models/policy-metadata.ts b/catalog-ui/src/app/models/policy-metadata.ts
index 33e0185..3f489bb 100644
--- a/catalog-ui/src/app/models/policy-metadata.ts
+++ b/catalog-ui/src/app/models/policy-metadata.ts
@@ -1,5 +1,7 @@
export class PolicyMetadata {
public uniqueId: string;
+ public name:string;
+ public icon:string;
public type: string;
public version: string;
public description: string;
@@ -11,6 +13,8 @@
deserialize (response): PolicyMetadata {
this.uniqueId = response.uniqueId;
this.type = response.type;
+ this.name = response.name;
+ this.icon = response.icon;
this.version = response.version;
this.description = response.description;
this.creationTime = response.creationTime;
diff --git a/catalog-ui/src/app/models/properties-inputs/property-fe-map.ts b/catalog-ui/src/app/models/properties-inputs/property-fe-map.ts
index 30cfcf0..de943fc 100644
--- a/catalog-ui/src/app/models/properties-inputs/property-fe-map.ts
+++ b/catalog-ui/src/app/models/properties-inputs/property-fe-map.ts
@@ -32,10 +32,14 @@
export class InstancePropertiesAPIMap {
componentInstanceProperties: InstanceBePropertiesMap;
componentInstanceInputsMap: InstanceBePropertiesMap;
+ groupProperties: InstanceBePropertiesMap;
+ policyProperties: InstanceBePropertiesMap;
- constructor(inputsMapData: InstanceBePropertiesMap, propertiesMapData: InstanceBePropertiesMap) {
+ constructor(inputsMapData: InstanceBePropertiesMap, propertiesMapData: InstanceBePropertiesMap, groupPropertiesMapData: InstanceBePropertiesMap, policyPropertiesMapData: InstanceBePropertiesMap) {
this.componentInstanceInputsMap = inputsMapData ? inputsMapData: new InstanceBePropertiesMap();
this.componentInstanceProperties = propertiesMapData ? propertiesMapData: new InstanceBePropertiesMap();
+ this.groupProperties = groupPropertiesMapData ? groupPropertiesMapData : new InstanceBePropertiesMap();
+ this.policyProperties = policyPropertiesMapData ? policyPropertiesMapData : new InstanceBePropertiesMap();
}
}
diff --git a/catalog-ui/src/app/models/properties-inputs/property-fe-model.ts b/catalog-ui/src/app/models/properties-inputs/property-fe-model.ts
index a0c087b..c0af885 100644
--- a/catalog-ui/src/app/models/properties-inputs/property-fe-model.ts
+++ b/catalog-ui/src/app/models/properties-inputs/property-fe-model.ts
@@ -228,7 +228,7 @@
};
/* Returns array of individual parents for given prop path, with list/map UUIDs replaced with index/mapkey */
- public getParentNamesArray = (parentPropName: string, parentNames?: Array<string>): Array<string> => {
+ public getParentNamesArray = (parentPropName: string, parentNames?: Array<string>, noHashKeys:boolean = false): Array<string> => {
parentNames = parentNames || [];
if (parentPropName.indexOf("#") == -1) { return parentNames; } //finished recursing parents. return
@@ -236,7 +236,7 @@
let nameToInsert: string = parentProp.name;
if (parentProp.isChildOfListOrMap) {
- if (parentProp.derivedDataType == DerivedPropertyType.MAP) {
+ if (!noHashKeys && parentProp.derivedDataType == DerivedPropertyType.MAP) {
nameToInsert = parentProp.getActualMapKey();
} else { //LIST
let siblingProps = this.flattenedChildren.filter(prop => prop.parentName == parentProp.parentName).map(prop => prop.propertiesName);
@@ -245,7 +245,7 @@
}
parentNames.splice(0, 0, nameToInsert); //add prop name to array
- return this.getParentNamesArray(parentProp.parentName, parentNames); //continue recursing
+ return this.getParentNamesArray(parentProp.parentName, parentNames, noHashKeys); //continue recursing
}
public hasValueObjChanged() {
diff --git a/catalog-ui/src/app/models/properties.ts b/catalog-ui/src/app/models/properties.ts
index 7ff2770..a629140 100644
--- a/catalog-ui/src/app/models/properties.ts
+++ b/catalog-ui/src/app/models/properties.ts
@@ -147,9 +147,10 @@
temp.simpleType = undefined;
temp.value = temp.value === "{}" || temp.value === "[]" ? undefined : temp.value;
temp.defaultValue = temp.defaultValue === "{}" || temp.defaultValue === "[]" ? undefined : temp.defaultValue;
- temp.rules = null; //don't send rules to server until feature is fully supported
+ temp.rules = undefined; //don't send rules to server until feature is fully supported
temp.isAlreadySelected = undefined;
temp.addOn = undefined;
+ temp.filterTerm = undefined;
return temp;
};
}
diff --git a/catalog-ui/src/app/models/ui-models/ui-base-object.ts b/catalog-ui/src/app/models/ui-models/ui-base-object.ts
new file mode 100644
index 0000000..a5989e4
--- /dev/null
+++ b/catalog-ui/src/app/models/ui-models/ui-base-object.ts
@@ -0,0 +1,20 @@
+/**
+ * Created by ob0695 on 10.04.2018.
+ */
+
+export interface IUiBaseObject {
+ name:string;
+ uniqueId:string;
+ type:any;
+}
+export class UiBaseObject implements IUiBaseObject{
+ name:string;
+ uniqueId:string;
+ type:any;
+
+ constructor(uniqueId: string, type?: any, name?:string) {
+ this.uniqueId = uniqueId;
+ this.name = name;
+ this.type = type;
+ }
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/models/ui-models/ui-member-object.ts b/catalog-ui/src/app/models/ui-models/ui-member-object.ts
new file mode 100644
index 0000000..92cda1b
--- /dev/null
+++ b/catalog-ui/src/app/models/ui-models/ui-member-object.ts
@@ -0,0 +1,9 @@
+import {IZoneInstanceAssignment} from "../graph/zones/zone-instance";
+import {UiBaseObject} from "./ui-base-object";
+import {TargetOrMemberType} from "../../utils/constants";
+
+export class MemberUiObject extends UiBaseObject implements IZoneInstanceAssignment {
+ constructor(uniqueId: string, name:string) {
+ super(uniqueId, TargetOrMemberType.COMPONENT_INSTANCES, name);
+ }
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/models/ui-models/ui-target-object.ts b/catalog-ui/src/app/models/ui-models/ui-target-object.ts
new file mode 100644
index 0000000..e8a114e
--- /dev/null
+++ b/catalog-ui/src/app/models/ui-models/ui-target-object.ts
@@ -0,0 +1,9 @@
+import {IZoneInstanceAssignment} from "../graph/zones/zone-instance";
+import {UiBaseObject} from "./ui-base-object";
+import {TargetOrMemberType} from "../../utils/constants";
+
+export class TargetUiObject extends UiBaseObject implements IZoneInstanceAssignment {
+ constructor(uniqueId:string, type:TargetOrMemberType, name:string) {
+ super(uniqueId, type, name);
+ }
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/models/ui-models/ui-zone-instance-object.ts b/catalog-ui/src/app/models/ui-models/ui-zone-instance-object.ts
new file mode 100644
index 0000000..d8648f2
--- /dev/null
+++ b/catalog-ui/src/app/models/ui-models/ui-zone-instance-object.ts
@@ -0,0 +1,11 @@
+import { UiBaseObject } from "app/models/ui-models/ui-base-object";
+import { ZoneInstanceType } from "../graph/zones/zone-instance";
+
+
+export class UIZoneInstanceObject extends UiBaseObject{
+ type:ZoneInstanceType;
+
+ constructor(uniqueId: string, type?: ZoneInstanceType, name?:string) {
+ super(uniqueId, type, name);
+ }
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/modules/directive-module.ts b/catalog-ui/src/app/modules/directive-module.ts
index 3b3a716..7892d5b 100644
--- a/catalog-ui/src/app/modules/directive-module.ts
+++ b/catalog-ui/src/app/modules/directive-module.ts
@@ -64,7 +64,7 @@
import {ImageCreatorService} from "../directives/graphs-v2/image-creator/image-creator.service";
import {Palette} from "../directives/graphs-v2/palette/palette.directive";
import {CompositionGraph} from "../directives/graphs-v2/composition-graph/composition-graph.directive";
-import {RelationMenuDirective} from "../directives/graphs-v2/relation-menu/relation-menu";
+// import {RelationMenuDirective} from "../directives/graphs-v2/relation-menu/relation-menu";
import {DeploymentGraph} from "../directives/graphs-v2/deployment-graph/deployment-graph.directive";
import {CommonGraphUtils} from "../directives/graphs-v2/common/common-graph-utils";
import {CompositionGraphNodesUtils} from "../directives/graphs-v2/composition-graph/utils/composition-graph-nodes-utils";
@@ -77,7 +77,7 @@
import {CapabilitiesListDirective} from "../directives/capabilities-and-requirements/capability/capabilities-list-directive";
import {RequirementsListDirective} from "../directives/capabilities-and-requirements/requirement/requirements-list-directive";
import {ServicePathGraphUtils} from "../directives/graphs-v2/composition-graph/utils/composition-graph-service-path-utils";
-import {PaletteAnimationComponent} from './../ng2/components/ui/palette-animation/palette-animation.component';
+import {PreventDoubleClickDirective} from "../directives/prevent-double-click/prevent-double-click";
let moduleName:string = 'Sdc.Directives';
let directiveModule:ng.IModule = angular.module(moduleName, []);
@@ -91,7 +91,7 @@
directiveModule.directive('invalidCharacters', InvalidCharactersDirective.factory);
directiveModule.directive('perfectScrollbar', PerfectScrollerDirective.factory);
directiveModule.directive('expandCollapse', ExpandCollapseDirective.factory);
-directiveModule.directive('sdcModal', SdcModalDirective.factory);
+directiveModule.directive('ng1Modal', SdcModalDirective.factory);
directiveModule.directive('fileOpener', FileOpenerDirective.factory);
directiveModule.directive('fileUpload', FileUploadDirective.factory);
directiveModule.directive('structureTree', StructureTreeDirective.factory);
@@ -113,17 +113,19 @@
directiveModule.directive('selectTypeList', SelectTypeListDirective.factory);
directiveModule.directive('infoTooltip', InfoTooltipDirective.factory);
directiveModule.directive('validationOnLoad', ValidationOnLoadDirective.factory);
-directiveModule.directive('sdcTabs', SdcTabsDirective.factory);
+directiveModule.directive('ng1Tabs', SdcTabsDirective.factory);
directiveModule.directive('sdcSingleTab', SdcSingleTabDirective.factory);
directiveModule.directive('innerSdcSingleTab', InnerSdcSingleTabDirective.factory);
directiveModule.directive('jsonExportExcel', JsonExportExcelDirective.factory);
directiveModule.directive('expandCollapseListHeader', ExpandCollapseListHeaderDirective.factory);
+directiveModule.directive('preventDoubleClick', PreventDoubleClickDirective.factory);
+//
//
// // Layouts
directiveModule.directive('topProgress', TopProgressDirective.factory);
//
// // Elements
-directiveModule.directive('sdcCheckbox', CheckboxElementDirective.factory);
+directiveModule.directive('ng1Checkbox', CheckboxElementDirective.factory);
directiveModule.directive('sdcRadioButton', RadiobuttonElementDirective.factory);
//
// // Events
@@ -144,7 +146,7 @@
// //composition
directiveModule.directive('palette', Palette.factory);
directiveModule.directive('compositionGraph', CompositionGraph.factory);
-directiveModule.directive('relationMenu', RelationMenuDirective.factory);
+// directiveModule.directive('relationMenu', RelationMenuDirective.factory);
//directiveModule.directive('assetPopover', AssetPopoverDirective.factory);
//
// //deployment
@@ -178,13 +180,18 @@
import { TopNavComponent } from "../ng2/components/layout/top-nav/top-nav.component";
import { ZoneContainerComponent } from "../ng2/components/ui/canvas-zone/zone-container.component";
import { ZoneInstanceComponent } from "../ng2/components/ui/canvas-zone/zone-instance/zone-instance.component";
+import { CompositionPanelComponent } from 'app/ng2/pages/composition/panel/panel.component';
+import { CompositionPanelHeaderComponent } from 'app/ng2/pages/composition/panel/panel-header/panel-header.component';
import { PropertiesAssignmentComponent } from "../ng2/pages/properties-assignment/properties-assignment.page.component";
import { SearchWithAutoCompleteComponent } from "../ng2/components/ui/search-with-autocomplete/search-with-autocomplete.component";
import { PalettePopupPanelComponent } from "../ng2/components/ui/palette-popup-panel/palette-popup-panel.component";
import { ServicePathComponent } from '../ng2/components/logic/service-path/service-path.component';
import { ServicePathSelectorComponent } from '../ng2/components/logic/service-path-selector/service-path-selector.component';
+import { MultilineEllipsisComponent } from "../ng2/shared/multiline-ellipsis/multiline-ellipsis.component";
import { InterfaceOperationComponent } from '../ng2/pages/interface-operation/interface-operation.page.component';
import { PluginFrameComponent } from "../ng2/components/ui/plugin/plugin-frame.component";
+import { TileComponent } from "../ng2/components/ui/tile/tile.component";
+
directiveModule.directive('menuListNg2', downgradeComponent({
component: MenuListNg2Component,
@@ -193,20 +200,25 @@
directiveModule.directive('topNav', downgradeComponent({
component: TopNavComponent,
- inputs: ['version', 'menuModel', 'topLvlSelectedIndex', 'hideSearch', 'searchTerm', 'notificationIconCallback'],
+ inputs: ['version', 'menuModel', 'topLvlSelectedIndex', 'hideSearch', 'searchTerm', 'notificationIconCallback', 'unsavedChanges', 'unsavedChangesCallback'],
outputs: ['searchTermChange']
}) as ng.IDirectiveFactory);
directiveModule.directive('ng2ZoneContainer', downgradeComponent({
component: ZoneContainerComponent,
- inputs: ['title', 'count', 'class', 'showZone', 'minifyZone'],
- outputs: []
+ inputs: ['title', 'count', 'type', 'visible', 'minimized'],
+ outputs: ['minimize', 'backgroundClick']
}) as angular.IDirectiveFactory);
directiveModule.directive('ng2ZoneInstance', downgradeComponent({
- component: ZoneInstanceComponent,
- inputs: ['config', 'isActive', 'activeInstanceMode', 'defaultIconText'],
- outputs: ['modeChange']
+ component: ZoneInstanceComponent,
+ inputs: ['zoneInstance', 'isActive', 'activeInstanceMode', 'defaultIconText', 'isViewOnly', 'hidden', 'forceSave'],
+ outputs: ['modeChange', 'tagHandleClick', 'assignmentSaveStart', 'assignmentSaveComplete']
+}) as angular.IDirectiveFactory);
+
+directiveModule.directive('ng2CompositionPanel', downgradeComponent({
+ component: CompositionPanelComponent,
+ inputs: ['isViewOnly', 'isLoading', 'isCertified', 'selectedZoneInstanceId', 'selectedZoneInstanceType', 'selectedZoneInstanceName', 'topologyTemplate'],
}) as angular.IDirectiveFactory);
directiveModule.directive('propertiesAssignment', downgradeComponent({
@@ -219,12 +231,6 @@
outputs: ['searchChanged', 'searchButtonClicked']
}) as angular.IDirectiveFactory);
-directiveModule.directive('ng2PaletteAnimation', downgradeComponent({
- component: PaletteAnimationComponent,
- inputs: ['from', 'to', 'icon' ],
- outputs: []
- }) as angular.IDirectiveFactory);
-
directiveModule.directive('ng2PalettePopupPanel', downgradeComponent({
component: PalettePopupPanelComponent,
inputs: [],
@@ -233,7 +239,7 @@
directiveModule.directive('ng2ServicePath', downgradeComponent({
component: ServicePathComponent,
- inputs: ['onCreate', 'service'],
+ inputs: ['onCreate', 'service', 'isViewOnly'],
outputs: []
}) as angular.IDirectiveFactory);
@@ -249,6 +255,18 @@
outputs: []
}) as angular.IDirectiveFactory);
+directiveModule.directive('ng2MultilineEllipsis', downgradeComponent({
+ component: MultilineEllipsisComponent,
+ inputs: ['lines', 'lineHeight', 'className'],
+ outputs: ['hasEllipsisChanged']
+}) as angular.IDirectiveFactory);
+
+directiveModule.directive('ng2UiTile', downgradeComponent({
+ component: TileComponent,
+ inputs: ['component'],
+ outputs: ['onTileClick']
+}) as angular.IDirectiveFactory);
+
directiveModule.directive('pluginFrame', downgradeComponent( {
component: PluginFrameComponent,
inputs: ['plugin', 'queryParams'],
diff --git a/catalog-ui/src/app/modules/filters.ts b/catalog-ui/src/app/modules/filters.ts
index 95fe583..fdce1e3 100644
--- a/catalog-ui/src/app/modules/filters.ts
+++ b/catalog-ui/src/app/modules/filters.ts
@@ -23,7 +23,6 @@
import {ResourceTypeFilter} from "../filters/resource-type-filter";
import {StringToDateFilter} from "../filters/string-to-date-filter";
import {CategoryTypeFilter} from "../filters/category-type-filter";
-import {CatalogStatusFilter} from "../filters/catalog-status-filter";
import {TruncateFilter} from "../filters/truncate-filter";
import {EntityFilter} from "../filters/entity-filter";
import {GraphResourceNameFilter} from "../filters/graph-resource-name-filter";
@@ -37,7 +36,6 @@
filterModule.filter("graphResourceName", GraphResourceNameFilter);
filterModule.filter("entityFilter", EntityFilter);
filterModule.filter("truncate", TruncateFilter);
-filterModule.filter("catalogStatusFilter", CatalogStatusFilter);
filterModule.filter("categoryTypeFilter", CategoryTypeFilter);
filterModule.filter("stringToDateFilter", StringToDateFilter);
filterModule.filter("resourceTypeName", ResourceTypeFilter);
diff --git a/catalog-ui/src/app/modules/service-module.ts b/catalog-ui/src/app/modules/service-module.ts
index c934b63..f4350a3 100644
--- a/catalog-ui/src/app/modules/service-module.ts
+++ b/catalog-ui/src/app/modules/service-module.ts
@@ -46,22 +46,28 @@
import {CategoryResourceService} from "../services/category-resource-service";
import {downgradeInjectable} from "@angular/upgrade/static";
import {ModalService} from "../ng2/services/modal.service";
+import {SdcUiComponents} from "sdc-ui/lib/angular";
import {ComponentServiceNg2} from "../ng2/services/component-services/component.service";
import {ServiceServiceNg2} from "../ng2/services/component-services/service.service";
import {ComponentServiceFactoryNg2} from "../ng2/services/component-services/component.service.factory";
import {ConnectionWizardService} from "../ng2/pages/connection-wizard/connection-wizard.service";
import {ComponentInstanceServiceNg2} from "../ng2/services/component-instance-services/component-instance.service";
import {UserService as UserServiceNg2} from "../ng2/services/user.service";
+import {PoliciesService as PoliciesServiceNg2} from "../ng2/services/policies.service";
+import {GroupsService as GroupsServiceNg2} from "../ng2/services/groups.service";
import {PluginsService} from "../ng2/services/plugins.service";
import {EventBusService} from "../ng2/services/event-bus.service";
-import {PoliciesService as PoliciesServiceNg2} from "../ng2/services/policies.service";
import {DynamicComponentService} from "app/ng2/services/dynamic-component.service";
+import {AutomatedUpgradeService} from "../ng2/pages/automated-upgrade/automated-upgrade.service";
+import {ArchiveService as ArchiveServiceNg2} from "app/ng2/services/archive.service";
+import {ComponentFactory} from "app/utils/component-factory";
let moduleName:string = 'Sdc.Services';
let serviceModule:ng.IModule = angular.module(moduleName, []);
serviceModule.service('Sdc.Services.ConfigurationUiService', ConfigurationUiService);
serviceModule.service('Sdc.Services.CookieService', CookieService);
+serviceModule.service('Sdc.Services.ComponentFactory', ComponentFactory); // Why you need to declare it again, already done in utils.ts
serviceModule.service('Sdc.Services.EntityService', EntityService);
serviceModule.service('Sdc.Services.AvailableIconsService', AvailableIconsService);
serviceModule.service('Sdc.Services.UrlToBase64Service', UrlToBase64Service);
@@ -98,10 +104,14 @@
serviceModule.factory('ComponentServiceFactoryNg2', downgradeInjectable(ComponentServiceFactoryNg2));
serviceModule.factory('ServiceServiceNg2', downgradeInjectable(ServiceServiceNg2));
serviceModule.factory('ModalServiceNg2', downgradeInjectable(ModalService));
+serviceModule.factory('ModalServiceSdcUI', downgradeInjectable(SdcUiComponents.ModalService));
serviceModule.factory('ConnectionWizardServiceNg2', downgradeInjectable(ConnectionWizardService));
serviceModule.factory('ComponentInstanceServiceNg2', downgradeInjectable(ComponentInstanceServiceNg2));
serviceModule.factory('UserServiceNg2', downgradeInjectable(UserServiceNg2));
+serviceModule.factory('PoliciesServiceNg2', downgradeInjectable(PoliciesServiceNg2));
+serviceModule.factory('GroupsServiceNg2', downgradeInjectable(GroupsServiceNg2));
serviceModule.factory('PluginsService', downgradeInjectable(PluginsService));
serviceModule.factory('EventBusService', downgradeInjectable(EventBusService));
-serviceModule.factory('PoliciesServiceNg2', downgradeInjectable(PoliciesServiceNg2));
serviceModule.factory('DynamicComponentService', downgradeInjectable(DynamicComponentService));
+serviceModule.factory('ArchiveServiceNg2', downgradeInjectable(ArchiveServiceNg2));
+serviceModule.factory('AutomatedUpgradeService', downgradeInjectable(AutomatedUpgradeService));
diff --git a/catalog-ui/src/app/modules/view-model-module.ts b/catalog-ui/src/app/modules/view-model-module.ts
index de7d6d8..b732be7 100644
--- a/catalog-ui/src/app/modules/view-model-module.ts
+++ b/catalog-ui/src/app/modules/view-model-module.ts
@@ -67,8 +67,8 @@
import {InterfaceOperationViewModel} from "../view-models/workspace/tabs/interface-operation/interface-operation-view-model";
import {NetworkCallFlowViewModel} from "../view-models/workspace/tabs/network-call-flow/network-call-flow-view-model";
import {DeploymentViewModel} from "../view-models/workspace/tabs/deployment/deployment-view-model";
-import {ResourceInputsViewModel} from "../view-models/workspace/tabs/inputs/resource-input/resource-inputs-view-model";
-import {ServiceInputsViewModel} from "../view-models/workspace/tabs/inputs/service-input/service-inputs-view-model";
+// import {ResourceInputsViewModel} from "../view-models/workspace/tabs/inputs/resource-input/resource-inputs-view-model";
+// import {ServiceInputsViewModel} from "../view-models/workspace/tabs/inputs/service-input/service-inputs-view-model";
import {ReqAndCapabilitiesViewModel} from "../view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view-model";
import {InputFormViewModel} from "../view-models/forms/input-form/input-form-view-modal";
import {HierarchyViewModel} from "../view-models/tabs/hierarchy/hierarchy-view-model";
@@ -135,8 +135,8 @@
.controller(moduleName + '.InterfaceOperationViewModel', InterfaceOperationViewModel)
.controller(moduleName + '.NetworkCallFlowViewModel', NetworkCallFlowViewModel)
.controller(moduleName + '.DeploymentViewModel', DeploymentViewModel)
- .controller(moduleName + '.ResourceInputsViewModel', ResourceInputsViewModel)
- .controller(moduleName + '.ServiceInputsViewModel', ServiceInputsViewModel)
+ // .controller(moduleName + '.ResourceInputsViewModel', ResourceInputsViewModel)
+ // .controller(moduleName + '.ServiceInputsViewModel', ServiceInputsViewModel)
.controller(moduleName + '.ReqAndCapabilitiesViewModel', ReqAndCapabilitiesViewModel)
.controller(moduleName + '.InputFormViewModel', InputFormViewModel)
.controller(moduleName + '.PluginsTabViewModel', PluginsTabViewModel)
diff --git a/catalog-ui/src/app/ng2/app.module.ts b/catalog-ui/src/app/ng2/app.module.ts
index c3cd060..c949a73 100644
--- a/catalog-ui/src/app/ng2/app.module.ts
+++ b/catalog-ui/src/app/ng2/app.module.ts
@@ -18,51 +18,61 @@
* ============LICENSE_END=========================================================
*/
-import {BrowserModule} from '@angular/platform-browser';
-import {NgModule, APP_INITIALIZER} from '@angular/core';
-import {FormsModule} from '@angular/forms';
-import {forwardRef} from '@angular/core';
-import {AppComponent} from './app.component';
-import {UpgradeAdapter} from '@angular/upgrade';
-import {UpgradeModule} from '@angular/upgrade/static';
-import {PropertiesAssignmentModule} from './pages/properties-assignment/properties-assignment.module';
+import { BrowserModule } from '@angular/platform-browser';
+import { NgModule, APP_INITIALIZER } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+import { forwardRef } from '@angular/core';
+import { AppComponent } from './app.component';
+import { UpgradeAdapter } from '@angular/upgrade';
+import { UpgradeModule } from '@angular/upgrade/static';
+import { SdcUiComponentsModule, SdcUiComponents } from "sdc-ui/lib/angular";
+import { PropertiesAssignmentModule } from './pages/properties-assignment/properties-assignment.module';
import {
DataTypesServiceProvider, SharingServiceProvider, CookieServiceProvider, StateServiceFactory,
StateParamsServiceFactory, CacheServiceProvider, EventListenerServiceProvider, ScopeServiceFactory,
- NotificationServiceProvider
+ NotificationServiceProvider, ComponentFactoryProvider
} from "./utils/ng1-upgraded-provider";
-import {ConfigService} from "./services/config.service";
-import {HttpModule} from '@angular/http';
-import {HttpService} from './services/http.service';
-import {AuthenticationService} from './services/authentication.service';
-import {Cookie2Service} from "./services/cookie.service";
-import {ComponentServiceNg2} from "./services/component-services/component.service";
-import {ComponentServiceFactoryNg2} from "./services/component-services/component.service.factory";
-import {ServiceServiceNg2} from "./services/component-services/service.service";
-import {ComponentInstanceServiceNg2} from "./services/component-instance-services/component-instance.service";
-import {ModalService} from "./services/modal.service";
-import {UiElementsModule} from "./components/ui/ui-elements.module";
-import {ConnectionWizardModule} from "./pages/connection-wizard/connection-wizard.module";
+import { ConfigService } from "./services/config.service";
+import { HttpModule } from '@angular/http';
+import { HttpService } from './services/http.service';
+import { AuthenticationService } from './services/authentication.service';
+import { Cookie2Service } from "./services/cookie.service";
+import { ComponentServiceNg2 } from "./services/component-services/component.service";
+import { ComponentServiceFactoryNg2 } from "./services/component-services/component.service.factory";
+import { ServiceServiceNg2 } from "./services/component-services/service.service";
+import { ComponentInstanceServiceNg2 } from "./services/component-instance-services/component-instance.service";
+import { ModalService } from "./services/modal.service";
+import { UiElementsModule } from "./components/ui/ui-elements.module";
+import { ConnectionWizardModule } from "./pages/connection-wizard/connection-wizard.module";
import {InterfaceOperationModule} from "./pages/interface-operation/interface-operation.module";
import {OperationCreatorModule} from "./pages/interface-operation/operation-creator/operation-creator.module";
-import {LayoutModule} from "./components/layout/layout.module";
-import {UserService} from "./services/user.service";
-import {PoliciesService} from "./services/policies.service";
-import {DynamicComponentService} from "./services/dynamic-component.service";
-import {SdcConfig} from "./config/sdc-config.config";
+import { LayoutModule } from "./components/layout/layout.module";
+import { UserService } from "./services/user.service";
+import { DynamicComponentService } from "./services/dynamic-component.service";
+import { SdcConfig } from "./config/sdc-config.config";
+import { SdcMenu } from "./config/sdc-menu.config";
import { TranslateModule } from "./shared/translator/translate.module";
import { TranslationServiceConfig } from "./config/translation.service.config";
-import {ServicePathCreatorModule} from './pages/service-path-creator/service-path-creator.module';
-import {ServicePathsListModule} from './pages/service-paths-list/service-paths-list.module';
+import { MultilineEllipsisModule } from "./shared/multiline-ellipsis/multiline-ellipsis.module";
+import { ServicePathCreatorModule } from './pages/service-path-creator/service-path-creator.module';
+import { ServicePathsListModule } from './pages/service-paths-list/service-paths-list.module';
+import { ServicePathModule } from 'app/ng2/components/logic/service-path/service-path.module';
+import { ServicePathSelectorModule } from 'app/ng2/components/logic/service-path-selector/service-path-selector.module';
+import { CompositionPanelModule } from 'app/ng2/pages/composition/panel/panel.module';
+import { WindowRef } from "./services/window.service";
+import {ArchiveService} from "./services/archive.service";
+import { ModalsHandlerProvider } from './utils/ng1-upgraded-provider';
import {PluginFrameModule} from "./components/ui/plugin/plugin-frame.module";
import {PluginsService} from "./services/plugins.service";
import {EventBusService} from "./services/event-bus.service";
-import {ServicePathModule} from 'app/ng2/components/logic/service-path/service-path.module';
-import {ServicePathSelectorModule} from 'app/ng2/components/logic/service-path-selector/service-path-selector.module';
+import {GroupsService} from "./services/groups.service";
+import {PoliciesService} from "./services/policies.service";
+import {AutomatedUpgradeService} from "./pages/automated-upgrade/automated-upgrade.service";
+import {AutomatedUpgradeModule} from "./pages/automated-upgrade/automated-upgrade.module";
export const upgradeAdapter = new UpgradeAdapter(forwardRef(() => AppModule));
-export function configServiceFactory(config:ConfigService) {
+export function configServiceFactory(config: ConfigService) {
return () => {
return Promise.all([
config.loadValidationConfiguration(),
@@ -83,8 +93,11 @@
HttpModule,
LayoutModule,
TranslateModule,
+ MultilineEllipsisModule,
UiElementsModule,
-
+ CompositionPanelModule,
+ SdcUiComponentsModule,
+ AutomatedUpgradeModule,
//We need to import them here since we use them in angular1
ConnectionWizardModule,
PropertiesAssignmentModule,
@@ -97,10 +110,15 @@
ServicePathSelectorModule
],
exports: [],
- entryComponents: [],
+ entryComponents: [
+ // *** sdc-ui components to be used as downgraded:
+ // SdcUiComponents.ButtonComponent
+ ],
providers: [
+ WindowRef,
DataTypesServiceProvider,
SharingServiceProvider,
+ ComponentFactoryProvider,
CookieServiceProvider,
StateServiceFactory,
StateParamsServiceFactory,
@@ -108,6 +126,7 @@
CacheServiceProvider,
EventListenerServiceProvider,
NotificationServiceProvider,
+ ModalsHandlerProvider,
AuthenticationService,
Cookie2Service,
ConfigService,
@@ -115,14 +134,18 @@
ComponentServiceFactoryNg2,
ModalService,
ServiceServiceNg2,
+ AutomatedUpgradeService,
HttpService,
UserService,
PoliciesService,
+ GroupsService,
DynamicComponentService,
SdcConfig,
+ SdcMenu,
ComponentInstanceServiceNg2,
TranslationServiceConfig,
PluginsService,
+ ArchiveService,
EventBusService,
{
provide: APP_INITIALIZER,
@@ -130,13 +153,13 @@
deps: [ConfigService],
multi: true
},
- ],
+ ],
bootstrap: [AppComponent]
})
export class AppModule {
+ constructor(public upgrade: UpgradeModule, public eventBusService:EventBusService) {
- constructor(public upgrade:UpgradeModule, eventBusService:EventBusService) {
}
}
diff --git a/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.html b/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.html
index 55c4bf0..78f3111 100644
--- a/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.html
+++ b/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.html
@@ -20,7 +20,7 @@
<li [ngClass]="{'selected': $last }">
<a (click)="menuItemClick(groupItem, groupItem.menuItems[groupItem.selectedIndex])"
[attr.data-tests-id]="'breadcrumbs-button-' + $index">
- {{groupItem.menuItems[groupItem.selectedIndex].text}}
+ {{groupItem.menuItems[groupItem.selectedIndex]?.text}}
</a>
</li>
<li class="triangle-dropdown"
diff --git a/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.ts b/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.ts
index a0b6b2b..881a916 100644
--- a/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.ts
+++ b/catalog-ui/src/app/ng2/components/layout/top-nav/top-nav.component.ts
@@ -41,6 +41,8 @@
@Input() public hideSearch:boolean;
@Input() public searchTerm:string;
@Input() public notificationIconCallback:Function;
+ @Input() public unsavedChanges: boolean;
+ @Input() public unsavedChangesCallback: (completeCallback:Function)=> Promise<any>;
@Output() public searchTermChange:EventEmitter<string> = new EventEmitter<string>();
emitSearchTerm(event:string) {
this.searchTermChange.emit(event);
@@ -80,17 +82,21 @@
return true;
});
- //if it's a different state , checking previous state param
+ //if it's a different state
if (result === -1) {
- this.topLvlMenu.menuItems.forEach((item:MenuItem, index:number)=> {
- if (item.state === this.$state.params['previousState']) {
- result = index;
- }
- });
- }
+ //if in 'workspace' - checking previous state param
+ if (this.$state.includes('workspace')) {
+ // if previous state is 'dashboard' or 'catalog', then select it - otherwise, use 'catalog' as default for 'workspace'
+ const selectedStateName = (['dashboard', 'catalog'].indexOf(this.$state.params['previousState']) !== -1)
+ ? this.$state.params['previousState']
+ : 'catalog';
+ result = this.topLvlMenu.menuItems.findIndex((item:MenuItem) => item.state === selectedStateName);
+ }
- if (result === -1) {
- result = 0;
+ //if yet, none is selected, then select the first as default
+ if (result === -1) {
+ result = 0;
+ }
}
return result;
@@ -151,8 +157,21 @@
}
menuItemClick(itemGroup:MenuItemGroup, item:MenuItem) {
- itemGroup.itemClick = false;
+ let onSuccessFunction = () => {
+ this.navigate(itemGroup, item);
+ }
+ if (this.unsavedChanges && this.unsavedChangesCallback){
+ this.unsavedChangesCallback(onSuccessFunction).then((onSuccess)=> {
+ this.navigate(itemGroup, item);
+ }, (onReject) => {});
+ } else {
+ this.navigate(itemGroup, item);
+ }
+ }
+
+ navigate(itemGroup:MenuItemGroup, item:MenuItem) {
+ itemGroup.itemClick = false;
let onSuccess = ():void => {
itemGroup.selectedIndex = itemGroup.menuItems.indexOf(item);
};
@@ -165,4 +184,5 @@
this[item.action](item.state, item.params).then(onSuccess, onFailed);
}
}
+
}
diff --git a/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-display-options.ts b/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-display-options.ts
index c8d4566..36257ca 100644
--- a/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-display-options.ts
+++ b/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-display-options.ts
@@ -23,10 +23,16 @@
valueProperty: string;
childrenProperty: string;
searchText:string;
- constructor(idProperty:string, valueProperty:string, childrenProperty?:string, searchText?:string) {
+ archived:boolean;
+
+ iconProperty: string;
+ constructor(idProperty:string, valueProperty:string, childrenProperty?:string, searchText?:string, iconProperty?:string, archived?:boolean) {
+
this.idProperty = idProperty;
this.valueProperty = valueProperty;
this.childrenProperty = childrenProperty;
this.searchText = searchText;
+ this.archived = archived;
+ this.iconProperty = iconProperty;
}
}
diff --git a/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.html b/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.html
index c3f9e5a..aa60337 100644
--- a/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.html
+++ b/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.html
@@ -1,7 +1,12 @@
<div class="navigation-wrapper">
<div class="node-item" *ngFor="let item of displayData" (click)="onClick($event, item)">
<div class="node-data-wrapper" [ngClass]="{'selected': selectedItem && selectedItem === item[displayOptions.idProperty]}">
- <span class="node-data" [ngClass]="{'mark':item[displayOptions.valueProperty] === displayOptions.searchText}" [attr.data-tests-id]="item[displayOptions.valueProperty]">{{item[displayOptions.valueProperty]}}</span>
+ <span class="node-data" [ngClass]="{'mark':item[displayOptions.valueProperty] === displayOptions.searchText}" [attr.data-tests-id]="item[displayOptions.valueProperty]">
+
+ <span *ngIf="displayOptions.iconProperty" [ngClass]="['node-data-icon', item[displayOptions.iconProperty], 'small']"></span>
+ {{item[displayOptions.valueProperty]}}
+ <span class="sprite-new archive-label" *ngIf="item.originArchived"></span>
+ </span>
</div>
<div class="children-node" *ngIf="item[displayOptions.childrenProperty]">
<hierarchy-navigation class="children-hierarchy" [displayData]="item[displayOptions.childrenProperty]"
diff --git a/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.less b/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.less
index 4befa2c..33ffb49 100644
--- a/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.less
+++ b/catalog-ui/src/app/ng2/components/logic/hierarchy-navigtion/hierarchy-navigation.component.less
@@ -1,3 +1,5 @@
+@import './../../../../../assets/styles/mixins.less';
+
.navigation-wrapper {
text-align: left;
}
@@ -30,6 +32,25 @@
.node-data {
margin-left: 10px;
margin-right: 10px;
+ align-items: center;
+ display: block;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ max-width: 300px;
+ .archive-label{
+ margin-left: 5px;
+ }
+}
+
+.node-data-icon {
+ vertical-align: middle;
+ margin-right: 7px;
+
+ &.defaulticon.small {
+ background-color: #999;
+ border-radius: 14px;
+ }
}
.node-data-wrapper.selected {
@@ -50,3 +71,20 @@
+.icon-group {
+ .square-icon();
+ background-color: @main_color_a;
+
+ &::before {
+ content: "G";
+ }
+}
+.icon-policy {
+ .square-icon();
+ background-color: @main_color_r;
+
+ &::before {
+ content: "P";
+ }
+}
+
diff --git a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html
index b7cde7e..daffc9e 100644
--- a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html
+++ b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.html
@@ -17,8 +17,8 @@
tooltip="{{input.description}}" tooltipDelay="0"></span>
</div>
<div class="table-cell col3">
- <div class="inner-cell-div" tooltip="{{instanceNamesMap[input.instanceUniqueId]}}">
- <span>{{instanceNamesMap[input.instanceUniqueId]}}</span>
+ <div class="inner-cell-div" tooltip="{{instanceNamesMap[input.instanceUniqueId]?.name}}">
+ <span>{{instanceNamesMap[input.instanceUniqueId]?.name}}</span>
</div>
</div>
<div class="table-cell col2">
@@ -34,7 +34,8 @@
[type]="input.type"
[name]="input.name"
(elementChanged)="onInputChanged(input, $event)"
- [readonly]="readonly">
+ [readonly]="readonly"
+ [testId]="'input-' + input.name">
</dynamic-element>
<div class="delete-button-container">
<span *ngIf="input.instanceUniqueId && !readonly" class="sprite-new delete-btn" (click)="openDeleteModal(input)" data-tests-id="delete-input-button"></span>
diff --git a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less
index d709f3f..5fbb62f 100644
--- a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less
+++ b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.less
@@ -85,8 +85,8 @@
border-right:#d2d2d2 solid 1px;
}
&.col1 {
- flex: 1 0 210px;
- max-width:210px;
+ flex: 1 0 120px;
+ max-width:120px;
display: flex;
justify-content: space-between;
@@ -112,14 +112,7 @@
}
&.valueCol {
- flex: 1 0 auto;
- min-width: 350px;
- display: flex;
- justify-content: flex-end;
- padding: 0px;
- align-items: center;
-
- .value-input {
+ .value-input {
flex: 1;
border: none;
background-color: inherit;
@@ -142,7 +135,7 @@
padding: 0px;
.delete-button-container {
- padding: 3px 5px 0 0 ;
+ padding: 0 8px 0 0 ;
}
}
}
diff --git a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts
index ebecbc9..0c7fc2a 100644
--- a/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts
+++ b/catalog-ui/src/app/ng2/components/logic/inputs-table/inputs-table.component.ts
@@ -24,6 +24,7 @@
import {Component, Input, Output, EventEmitter} from "@angular/core";
import {InputFEModel} from "app/models";
import {ModalService} from "../../../services/modal.service";
+import { InstanceFeDetails } from "app/models/instance-fe-details";
@Component({
selector: 'inputs-table',
@@ -33,7 +34,7 @@
export class InputsTableComponent {
@Input() inputs: Array<InputFEModel>;
- @Input() instanceNamesMap: Map<string, string>;
+ @Input() instanceNamesMap: Map<string, InstanceFeDetails>;
@Input() readonly:boolean;
@Input() isLoading:boolean;
@Output() inputChanged: EventEmitter<any> = new EventEmitter<any>();
diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html
index 4805875..b5ae7a8 100644
--- a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html
+++ b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html
@@ -19,6 +19,7 @@
[name]="property.name"
(elementChanged)="mapKeyChanged.emit($event.value)"
[readonly]="readonly"
+ [testId]="'prop-key-' + propertyTestsId"
></dynamic-element>
</div>
</ng-container>
@@ -27,12 +28,13 @@
<div class="table-cell">
<dynamic-element class="value-input"
pattern="validationUtils.getValidationPattern(property.type)"
- [value]="property.valueObj"
+ [value]="property.isDeclared ? property.value : property.valueObj"
[type]="property.isDeclared ? 'string' : property.type"
[name]="property.name"
[path]="property.propertiesName"
(elementChanged)="onElementChanged($event)"
[readonly]="readonly || property.isDeclared || property.isDisabled"
+ [testId]="'prop-' + propertyTestsId"
></dynamic-element>
</div>
</ng-container>
@@ -45,9 +47,9 @@
</ng-container>
<!-- ICONS: add, delete, and expand -->
<ng-container *ngIf="!property.isDeclared">
- <a *ngIf="(propType == derivedPropertyTypes.LIST || propType == derivedPropertyTypes.MAP) && !property.isChildOfListOrMap" class="property-icon add-item" (click)="createNewChildProperty();" [ngClass]="{'disabled':readonly || preventInsertItem(property)}">Add value to list</a>
- <span *ngIf="property.isChildOfListOrMap" (click)="deleteItem.emit(property);" class="property-icon sprite-new delete-item-icon" [ngClass]="{'disabled':readonly}"></span>
- <span *ngIf="!isPropertyFEModel && (propType == derivedPropertyTypes.COMPLEX || ((propType == derivedPropertyTypes.LIST || propType == derivedPropertyTypes.MAP) && hasChildren))" (click)="expandChildById(propPath)" class="property-icon sprite-new round-expand-icon" [class.open]="expandedChildId.indexOf(propPath) == 0"></span>
+ <a *ngIf="(propType == derivedPropertyTypes.LIST || propType == derivedPropertyTypes.MAP) && !property.isChildOfListOrMap" class="property-icon add-item" (click)="createNewChildProperty();" [ngClass]="{'disabled':readonly || preventInsertItem(property)}" [attr.data-tests-id]="'add-to-list-' + propertyTestsId">Add value to list</a>
+ <span *ngIf="property.isChildOfListOrMap" (click)="deleteItem.emit(property);" class="property-icon sprite-new delete-item-icon" [ngClass]="{'disabled':readonly}" [attr.data-tests-id]="'delete-from-list-' + propertyTestsId"></span>
+ <span *ngIf="!isPropertyFEModel && (propType == derivedPropertyTypes.COMPLEX || ((propType == derivedPropertyTypes.LIST || propType == derivedPropertyTypes.MAP) && hasChildren))" (click)="expandChildById(propPath)" class="property-icon sprite-new round-expand-icon" [class.open]="expandedChildId.indexOf(propPath) == 0" [attr.data-tests-id]="'expand-' + propertyTestsId"></span>
</ng-container>
</div>
@@ -59,6 +61,7 @@
[hasDeclareOption]="hasDeclareOption"
[canBeDeclared]="hasDeclareOption && prop.canBeDeclared"
[property]="prop"
+ [rootProperty]="rootProperty || property"
[expandedChildId]="expandedChildId"
[propertyNameSearchText]="propertyNameSearchText"
[readonly]="readonly"
diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts
index 6f7e57b..6e19c95 100644
--- a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts
+++ b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts
@@ -41,6 +41,7 @@
propPath: string;
isPropertyFEModel: boolean;
nestedLevel: number;
+ propertyTestsId: string;
@Input() canBeDeclared: boolean;
@Input() property: PropertyFEModel | DerivedFEProperty;
@@ -50,6 +51,7 @@
@Input() readonly: boolean;
@Input() hasChildren: boolean;
@Input() hasDeclareOption:boolean;
+ @Input() rootProperty: PropertyFEModel;
@Output('propertyChanged') emitter: EventEmitter<void> = new EventEmitter<void>();
@Output() expandChild: EventEmitter<string> = new EventEmitter<string>();
@@ -69,6 +71,8 @@
this.propType = this.property.derivedDataType;
this.propPath = (this.property instanceof PropertyFEModel) ? this.property.name : this.property.propertiesName;
this.nestedLevel = (this.property.propertiesName.match(/#/g) || []).length;
+ this.rootProperty = (this.rootProperty) ? this.rootProperty : <PropertyFEModel>this.property;
+ this.propertyTestsId = this.getPropertyTestsId();
}
ngDoCheck() {
@@ -105,6 +109,10 @@
}).length > 1;
}
+ getPropertyTestsId = () => {
+ return [this.rootProperty.name].concat(this.rootProperty.getParentNamesArray(this.property.propertiesName, [], true)).join('.');
+ };
+
onElementChanged = (event: IUiElementChangeEvent) => {
this.property.updateValueObj(event.value, event.isValid);
this.emitter.emit();
diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html
index ecfa7e7..b574b55 100644
--- a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html
+++ b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html
@@ -9,8 +9,14 @@
<div class="table-body" [ngClass]="{'view-mode': readonly}">
<div class="no-data" *ngIf="!fePropertiesMap || !(fePropertiesMap | keys).length">No data to display</div>
- <ng-container *ngFor="let instanceId of fePropertiesMap | keys; trackBy:instanceId">
- <div class="table-rows-header white-sub-header" *ngIf="feInstanceNamesMap">{{feInstanceNamesMap[instanceId]}}</div>
+ <ng-container *ngFor="let instanceId of fePropertiesMap | keys; trackBy:vspId">
+ <div class="table-rows-header white-sub-header" *ngIf="feInstanceNamesMap">
+
+
+ <span [ngClass]="['prop-instance-icon', feInstanceNamesMap[instanceId].iconClass, 'small']"></span>
+ {{feInstanceNamesMap[instanceId].name}}
+ <div class="sprite-new archive-label" *ngIf="feInstanceNamesMap[instanceId].originArchived == true" ></div>
+ </div>
<div class="table-row"
*ngFor="let property of fePropertiesMap[instanceId] | searchFilter:'name':searchTerm; trackBy:property?.name"
@@ -22,8 +28,8 @@
<checkbox *ngIf="hasDeclareOption" [(checked)]="property.isSelected"
[disabled]="property.isDisabled || property.isDeclared || readonly"
(checkedChange)="propertyChecked(property)" [attr.data-tests-id]="property.name"></checkbox>
- <div class="inner-cell-div" tooltip="{{property.name}}">
- <span>{{property.name}}</span>
+ <div class="inner-cell-div-multiline" tooltip="{{property.name}}">
+ <multiline-ellipsis className="table-cell-multiline-ellipsis" [lines]="2">{{property.name}}</multiline-ellipsis>
</div>
</div>
<span *ngIf="property.description" class="property-description-icon sprite-new show-desc" tooltip="{{property.description}}" tooltipDelay="0"></span>
diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.less b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.less
index 20da0b6..72f67e4 100644
--- a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.less
+++ b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.less
@@ -1,4 +1,4 @@
-@import './../../../../../assets/styles/variables.less';
+@import './../../../../../assets/styles/mixins.less';
@import '../../../../../assets/styles/sprite';
@smaller-screen: ~"only screen and (max-width: 1580px)";
@@ -12,13 +12,16 @@
text-align:left;
- .inner-cell-div{
- max-width: 100%;
+ .inner-cell-div {
text-overflow: ellipsis;
overflow: hidden;
height: 20px;
}
+ .inner-cell-div-multiline {
+ max-width: 100%;
+ }
+
.table-header {
display: flex;
flex-direction:row;
@@ -36,6 +39,11 @@
.table-rows-header {
border: #d2d2d2 solid 1px;
border-top:none;
+ display: flex;
+ align-items: center;
+ .archive-label{
+ margin-left: 10px;
+ }
}
.table-body {
@@ -120,7 +128,7 @@
.property-description-icon {
float: right;
margin-top: 4px;
- margin-left: 5px;
+ margin-left: 15px;
flex: 0 0 auto;
}
}
@@ -177,4 +185,53 @@
}
}
+ .table-row {
+ /deep/ .table-cell-multiline-ellipsis .multiline-ellipsis-dots {
+ background: linear-gradient(to right, transparent 0%, #ffffff 80%);
+ padding-left: 1em;
+ }
+
+ &.selected /deep/ .table-cell-multiline-ellipsis .multiline-ellipsis-dots {
+ background: linear-gradient(to right, transparent 0%, #e6f6fb 80%);
+ padding-left: 1em;
+ }
+
+ &.readonly /deep/ .table-cell-multiline-ellipsis .multiline-ellipsis-dots {
+ background: linear-gradient(to right, transparent 0%, #f8f8f8 80%);
+ padding-left: 1em;
+ }
+
+ &:hover:not(.selected) /deep/ .table-cell-multiline-ellipsis .multiline-ellipsis-dots {
+ background: linear-gradient(to right, transparent 0%, #f8f8f8 80%);
+ padding-left: 1em;
+ }
+ }
+
+ .prop-instance-icon {
+ vertical-align: middle;
+ margin-right: 7px;
+ &.defaulticon.small {
+ background-color: @main_color_q;
+ border-radius:14px;
+ }
+ // square icons
+
+ &.icon-group {
+ .square-icon();
+ background-color: @main_color_a;
+
+ &::before {
+ content: "G";
+ }
+ }
+ &.icon-policy {
+ .square-icon();
+ background-color: @main_color_r;
+
+ &::before {
+ content: "P";
+ }
+ }
+
+ }
}
diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts
index 093fae1..da1fb82 100644
--- a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts
+++ b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.ts
@@ -21,6 +21,7 @@
import { Component, Input, Output, EventEmitter} from "@angular/core";
import {PropertyFEModel, DerivedFEProperty, InstanceFePropertiesMap} from "app/models";
import {PropertiesService} from "../../../services/properties.service";
+import { InstanceFeDetails } from "../../../../models/instance-fe-details";
@Component({
selector: 'properties-table',
@@ -30,7 +31,7 @@
export class PropertiesTableComponent {
@Input() fePropertiesMap: InstanceFePropertiesMap;
- @Input() feInstanceNamesMap: Map<string, string>;
+ @Input() feInstanceNamesMap: Map<string, InstanceFeDetails>;
@Input() selectedPropertyId: string;
@Input() propertyNameSearchText:string;
@Input() searchTerm:string;
diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/property-table.module.ts b/catalog-ui/src/app/ng2/components/logic/properties-table/property-table.module.ts
index 91f3348..91baaf1 100644
--- a/catalog-ui/src/app/ng2/components/logic/properties-table/property-table.module.ts
+++ b/catalog-ui/src/app/ng2/components/logic/properties-table/property-table.module.ts
@@ -8,6 +8,7 @@
import {FilterChildPropertiesPipe} from "./pipes/filterChildProperties.pipe";
import {GlobalPipesModule} from "../../../pipes/global-pipes.module";
import {PropertiesService} from "../../../services/properties.service";
+import {MultilineEllipsisModule} from "../../../shared/multiline-ellipsis/multiline-ellipsis.module";
@NgModule({
imports: [
@@ -15,7 +16,8 @@
HttpModule,
CommonModule,
GlobalPipesModule,
- UiElementsModule
+ UiElementsModule,
+ MultilineEllipsisModule
],
declarations: [
FilterChildPropertiesPipe,
diff --git a/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.html b/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.html
index 6e0f93f..9d570f0 100644
--- a/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.html
+++ b/catalog-ui/src/app/ng2/components/logic/select-requirement-or-capability/select-requirement-or-capability.component.html
@@ -9,7 +9,7 @@
</radio-buttons>
<label class="select-type-label">Select type:</label>
<div class="select-type">
- <ui-element-dropdown [values]="types" [(value)]="selectedType" (valueChange)="onTypeSelected($event)"></ui-element-dropdown>
+ <ui-element-dropdown [values]="types" [(value)]="selectedType" (valueChange)="onTypeSelected($event)" testId="select"></ui-element-dropdown>
</div>
<div class="table-and-list-container">
diff --git a/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.html b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.html
index 72e0835..af7a470 100644
--- a/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.html
+++ b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.html
@@ -1,5 +1,5 @@
<div class="service-path-selector">
- <label>Service Paths:</label>
+ <label>Service Flows:</label>
<ui-element-dropdown
class="path-dropdown"
data-tests-id="service-path-selector"
diff --git a/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.ts b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.ts
index be9966a..e09001f 100644
--- a/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.ts
+++ b/catalog-ui/src/app/ng2/components/logic/service-path-selector/service-path-selector.component.ts
@@ -1,4 +1,3 @@
-import * as _ from "lodash";
import {Component, Input, KeyValueDiffer, IterableDiffers, KeyValueDiffers, DoCheck} from '@angular/core';
import {Service} from "app/models/components/service";
import {TranslateService} from "app/ng2/shared/translator/translate.service";
diff --git a/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.html b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.html
index ff7902e..75f0642 100644
--- a/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.html
+++ b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.html
@@ -1,22 +1,15 @@
<div class='service-path'>
<button class='zoom-icons create-path-button' data-tests-id="pathsMenuBtn" (click)="showServicePathMenu = !showServicePathMenu">...</button>
- <div class="service-path-menu"
- *ngIf="showServicePathMenu" >
+ <div class="service-path-menu" *ngIf="showServicePathMenu">
<div >
<ul>
- <li><div class="hand" (click)="onCreateServicePath()" data-tests-id="createPathMenuItem">
- Create Service Path
+ <li *ngIf='!isViewOnly'><div class="hand" (click)="onCreateServicePath()" data-tests-id="createPathMenuItem">
+ Create Service Flow
</div></li>
<li><div class="hand" (click)="onListServicePath()" data-tests-id="pathsListMenuItem">
- Service Paths List
+ Service Flows List
</div></li>
</ul>
</div>
</div>
- <!-- TODO - ask Orit about positioning issues and styling issues -->
- <!--
- <menu-list [open]="showServicePathMenu" [position]="menuPos" >
- <menu-item [action]="onCreateServicePath">Create Path</menu-item>
- <menu-item [action]="onListServicePath">Paths' List</menu-item>
- </menu-list> -->
</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.ts b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.ts
index 4a6209f..d66c5f0 100644
--- a/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.ts
+++ b/catalog-ui/src/app/ng2/components/logic/service-path/service-path.component.ts
@@ -39,6 +39,7 @@
@Input() service: Service;
@Input() onCreate: Function;
@Input() onSave: Function;
+ @Input() isViewOnly:boolean;
constructor(private ModalServiceNg2: ModalService) {}
@@ -46,7 +47,7 @@
this.showServicePathMenu = false;
let cancelButton: ButtonModel = new ButtonModel('Cancel', 'outline white', this.ModalServiceNg2.closeCurrentModal);
let saveButton: ButtonModel = new ButtonModel('Create', 'blue', this.createPath, this.getDisabled );
- let modalModel: ModalModel = new ModalModel('l', 'Create Service Path', '', [saveButton, cancelButton], 'standard', true);
+ let modalModel: ModalModel = new ModalModel('l', 'Create Service Flow', '', [saveButton, cancelButton], 'standard', true);
this.modalInstance = this.ModalServiceNg2.createCustomModal(modalModel);
this.ModalServiceNg2.addDynamicContentToModal(this.modalInstance, ServicePathCreatorComponent, {service: this.service});
this.modalInstance.instance.open();
@@ -55,10 +56,10 @@
onListServicePath = ():void => {
this.showServicePathMenu = false;
let cancelButton: ButtonModel = new ButtonModel('Close', 'outline white', this.ModalServiceNg2.closeCurrentModal);
- let modalModel: ModalModel = new ModalModel('md', 'Service Paths List','', [cancelButton], 'standard', true);
+ let modalModel: ModalModel = new ModalModel('md', 'Service Flows List','', [cancelButton], 'standard', true);
this.modalInstance = this.ModalServiceNg2.createCustomModal(modalModel);
this.ModalServiceNg2.addDynamicContentToModal(this.modalInstance, ServicePathsListComponent, {service: this.service,
- onCreateServicePath: this.onCreateServicePath, onEditServicePath: this.onEditServicePath});
+ onCreateServicePath: this.onCreateServicePath, onEditServicePath: this.onEditServicePath, isViewOnly: this.isViewOnly});
this.modalInstance.instance.open();
};
@@ -70,14 +71,14 @@
onEditServicePath = (id:string):void => {
let cancelButton: ButtonModel = new ButtonModel('Cancel', 'outline white', this.ModalServiceNg2.closeCurrentModal);
let saveButton: ButtonModel = new ButtonModel('Save', 'blue', this.createPath, this.getDisabled );
- let modalModel: ModalModel = new ModalModel('l', 'Edit Path', '', [saveButton, cancelButton]);
+ let modalModel: ModalModel = new ModalModel('l', 'Edit Path', '', [saveButton, cancelButton], 'standard', true);
this.modalInstance = this.ModalServiceNg2.createCustomModal(modalModel);
this.ModalServiceNg2.addDynamicContentToModal(this.modalInstance, ServicePathCreatorComponent, {service: this.service, pathId: id});
this.modalInstance.instance.open();
};
getDisabled = ():boolean => {
- return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit();
+ return this.isViewOnly || !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit();
};
}
diff --git a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.html b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.html
index e279e3f..981efbb 100644
--- a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.html
+++ b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.html
@@ -1,11 +1,11 @@
-<div class="sdc-canvas-zone {{class}}-zone" [class.minimized]="minifyZone" [class.hidden]="!showZone">
- <div class="sdc-canvas-zone__header" (click)="unminifyZone()" >
+<div class="sdc-canvas-zone {{class}}-zone" [class.minimized]="minimized" [class.hidden]="!visible" (click)="backgroundClicked()">
+ <div class="sdc-canvas-zone__header" (click)="unminifyZone(); $event.stopPropagation();" >
<div class="sdc-canvas-zone__title">{{title}}
<span class="sdc-canvas-zone__counter">{{count}}</span>
</div>
<span class="sdc-canvas-zone__state-button">–</span>
</div>
- <div class="sdc-canvas-zone__container">
+ <div class="sdc-canvas-zone__container" #scrollDiv >
<ng-content></ng-content>
</div>
</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.less b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.less
index 3e77c5c..02880a9 100644
--- a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.less
+++ b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.less
@@ -1,5 +1,5 @@
.sdc-canvas-zone {
- width: 280px;
+ width: 285px;
max-height:186px;
display:flex;
flex-direction:column;
diff --git a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.ts b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.ts
index 7e60cb3..4059ad6 100644
--- a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.ts
+++ b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-container.component.ts
@@ -1,6 +1,5 @@
-import { Component, Input, Output, ViewEncapsulation, EventEmitter } from '@angular/core';
-import { EventListenerService } from 'app/services';
-import { GRAPH_EVENTS } from 'app/utils';
+import { Component, Input, Output, ViewEncapsulation, EventEmitter, OnInit } from '@angular/core';
+import { ZoneInstanceType } from '../../../../models/graph/zones/zone-instance';
@Component({
selector: 'zone-container',
@@ -9,17 +8,28 @@
encapsulation: ViewEncapsulation.None
})
-export class ZoneContainerComponent {
+export class ZoneContainerComponent implements OnInit {
@Input() title:string;
- @Input() class:string;
- @Input() count:number;
- @Input() showZone:boolean;
- @Input() minifyZone:boolean;
- constructor(private eventListenerService:EventListenerService) {}
+ @Input() type:ZoneInstanceType;
+ @Input() count:number;
+ @Input() visible:boolean;
+ @Input() minimized:boolean;
+ @Output() minimize: EventEmitter<any> = new EventEmitter<any>();
+ @Output() backgroundClick: EventEmitter<void> = new EventEmitter<void>();
+ private class:string;
+
+ constructor() {}
+
+ ngOnInit() {
+ this.class = ZoneInstanceType[this.type].toLowerCase();
+ }
private unminifyZone = () => {
- this.minifyZone = !this.minifyZone;
- this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_ZONE_SIZE_CHANGE);
+ this.minimize.emit();
+ }
+
+ private backgroundClicked = () => {
+ this.backgroundClick.emit();
}
}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.html b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.html
index d36b7ae..031b081 100644
--- a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.html
+++ b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.html
@@ -1,8 +1,10 @@
-<div class="zone-child mode-{{config.mode}}" [class.locked]="activeInstanceMode > MODE.HOVER"
- (mouseenter)="setMode(MODE.HOVER)" (mouseleave)="setMode(MODE.NONE)" (click)="setMode(MODE.SELECTED)">
- <div class="zone-child__handle" (click)="setMode(MODE.TAG, $event)">+</div>
- <div class="zone-child__body">
- <div class="zone-child__body-content">{{config.count || defaultIconText}}</div>
+<div tooltip="{{zoneInstance.instanceData.name}}" #currentComponent
+ class="zone-instance mode-{{zoneInstance.mode}}" [class.locked]="activeInstanceMode > MODE.HOVER" [class.hiding]="hidden"
+ (mouseenter)="setMode(MODE.HOVER)" (mouseleave)="setMode(MODE.NONE)" (click)="setMode(MODE.SELECTED, $event)">
+ <div *ngIf="zoneInstance.handle" class="target-handle {{zoneInstance.handle}}" (click)="tagHandleClicked($event)"></div>
+ <div *ngIf="!isViewOnly" class="zone-instance__handle" (click)="setMode(MODE.TAG, $event)">+</div>
+ <div class="zone-instance__body">
+ <div class="zone-instance__body-content">{{zoneInstance.assignments.length || defaultIconText}}</div>
</div>
- <div class="zone-child__name">{{config.name}}</div>
+ <div class="zone-instance__name">{{zoneInstance.instanceData.name}}</div>
</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.less b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.less
index a1d56df..b562c08 100644
--- a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.less
+++ b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.less
@@ -1,9 +1,12 @@
-.zone-child {
+@import '../../../../../../assets/styles/variables';
+
+.zone-instance {
position:relative;
width:76px;
margin:5px;
+ opacity:1;
- .zone-child__handle {
+ .zone-instance__handle {
display:none;
position:absolute;
right:4px;
@@ -11,33 +14,34 @@
width:22px;
height:22px;
cursor:pointer;
- border: solid white 1px;
+ border: solid @main_color_p 1px;
border-radius: 2px;
text-align: center;
font-weight:bold;
}
- .zone-child__body {
+ .zone-instance__body {
margin:0 auto;
width:43px;
height:43px;
display:flex;
padding:3px;
-
}
- .zone-child__body-content {
+ .zone-instance__body-content {
border-radius: 2px;
flex:1;
- color:white;
- font-size:18px;
+ color:@main_color_p;
+ font-size:16px;
text-align:center;
display:flex;
align-items: center;
justify-content: center;
+ box-shadow:none;
+ transition:box-shadow 5s;
}
- .zone-child__name {
+ .zone-instance__name {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
@@ -45,66 +49,86 @@
}
/* Dynamic classes below */
+ .target-handle {
+ position:absolute;
+ width:18px;
+ height:18px;
+ display:block;
+ top: -4px;
+ right: 10px;
+ background-size: 100% 100%;
+ cursor: url("../../../../../../assets/styles/images/canvas-tagging-icons/policy_2.svg"), pointer;
+
+ &.tagged-policy {
+ background-image: url('../../../../../../assets/styles/images/canvas-tagging-icons/policy_added.svg');
+ }
+
+ &.tag-available {
+ background-image: url('../../../../../../assets/styles/images/canvas-tagging-icons/indication.svg');
+ }
+ }
+
+
&.mode-1, &.mode-2, &.mode-3 { //hover, selected, tag
- .zone-child__body {
+ .zone-instance__body {
border:solid 2px;
border-radius: 2px;
padding:2px;
cursor:pointer;
}
- .zone-child__handle{
+ }
+
+ &.mode-1, &.mode-2:hover{
+ .zone-instance__handle{
display:block;
- cursor:pointer;
}
}
&.locked {
- cursor: default;
+ cursor: inherit;
+ }
+
+ &.hiding {
+ opacity:0;
+ .zone-instance__body-content {
+ box-shadow: #CCC 0px 0px 15px;
+ }
}
- // &:not(.locked):hover .zone-child__handle{
- // display:block;
- // }
- .zone-child__body {
- cursor: default;
- }
- &.mode-3 .zone-child__handle {
+
+ &.mode-3 .zone-instance__handle {
width:24px;
height:24px;
right:3px;
top:9px;
display:block;
background-image: linear-gradient(-140deg, #009E98 0%, #97D648 100%);
- border: 2px solid #FFFFFF;
+ border: 2px solid @main_color_p;
border-radius: 2px;
box-shadow: inset 2px -2px 3px 0 #007A3E;
- cursor: pointer;
}
}
.sdc-canvas-zone.group-zone {
- .zone-child__handle {
- background-color:#009FDB;
+ .zone-instance__handle {
+ background-color:@main_color_a;
}
- .zone-child__body {
- border-color:#009FDB;
- }
- .zone-child__body-content {
- background: #009FDB;
+ .zone-instance__body {
+ border-color:@main_color_a;
+ .zone-instance__body-content {
+ background: @main_color_a;
+ }
}
}
.sdc-canvas-zone.policy-zone {
- .zone-child__handle {
- background-color:#0568AE;
+ .zone-instance__handle {
+ background-color:@main_color_r;
}
- .zone-child__body {
- border-color:#1287D9;
- .zone-child__body-content {
- background: #1287D9;
+ .zone-instance__body {
+ border-color:@main_color_r;
+ .zone-instance__body-content {
+ background: @main_color_r;
}
}
- .zone-child__body-content {
- background: #0568AE;
- }
}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.ts b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.ts
index 8057ae9..3c2dd45 100644
--- a/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.ts
+++ b/catalog-ui/src/app/ng2/components/ui/canvas-zone/zone-instance/zone-instance.component.ts
@@ -1,5 +1,14 @@
-import { Component, Input, Output, EventEmitter, ViewEncapsulation } from '@angular/core';
-import { ZoneInstanceConfig, ZoneInstanceMode } from 'app/models/graph/zones/zone-child';
+import { Component, Input, Output, EventEmitter, ViewEncapsulation, OnInit, SimpleChange, ElementRef, ViewChild, SimpleChanges } from '@angular/core';
+import {
+ ZoneInstance, ZoneInstanceMode, ZoneInstanceType,
+ IZoneInstanceAssignment
+} from 'app/models/graph/zones/zone-instance';
+import { PoliciesService } from '../../../../services/policies.service';
+import { GroupsService } from '../../../../services/groups.service';
+import { IZoneService } from "../../../../../models/graph/zones/zone";
+import { EventListenerService } from 'app/services';
+import { GRAPH_EVENTS } from '../../../../../utils';
+import { Subject, Observable } from 'rxjs';
@Component({
selector: 'zone-instance',
@@ -7,22 +16,95 @@
styleUrls: ['./zone-instance.component.less'],
encapsulation: ViewEncapsulation.None
})
-export class ZoneInstanceComponent {
+export class ZoneInstanceComponent implements OnInit {
- @Input() config:ZoneInstanceConfig;
+ @Input() zoneInstance:ZoneInstance;
@Input() defaultIconText:string;
@Input() isActive:boolean;
+ @Input() isViewOnly:boolean;
@Input() activeInstanceMode: ZoneInstanceMode;
+ @Input() hidden:boolean;
+ @Input() forceSave:Subject<Function>;
@Output() modeChange: EventEmitter<any> = new EventEmitter<any>();
+ @Output() assignmentSaveStart: EventEmitter<void> = new EventEmitter<void>();
+ @Output() assignmentSaveComplete: EventEmitter<boolean> = new EventEmitter<boolean>();
+ @Output() tagHandleClick: EventEmitter<ZoneInstance> = new EventEmitter<ZoneInstance>();
+ @ViewChild('currentComponent') currentComponent: ElementRef;
private MODE = ZoneInstanceMode;
+ private zoneService:IZoneService;
- private setMode = (mode:ZoneInstanceMode, event?:any):void => {
- if(!this.isActive || this.isActive && mode == ZoneInstanceMode.TAG){ //when active, do not allow hover/select mode toggling
- this.modeChange.emit({newMode: mode, instance: this.config});
+ constructor(private policiesService:PoliciesService, private groupsService:GroupsService, private eventListenerService:EventListenerService){}
+
+ ngOnInit(){
+ if(this.zoneInstance.type == ZoneInstanceType.POLICY){
+ this.zoneService = this.policiesService;
+ } else {
+ this.zoneService = this.groupsService;
}
- if(event){
- event.stopPropagation();
+ this.forceSave.subscribe((afterSaveFunction:Function) => {
+ this.setMode(ZoneInstanceMode.TAG, null, afterSaveFunction);
+ })
+ }
+
+ ngOnChanges(changes:SimpleChanges) {
+ if(changes.hidden){
+ this.currentComponent.nativeElement.scrollIntoView({behavior: "smooth", block: "nearest", inline:"end"});
}
}
+ ngOnDestroy() {
+ this.forceSave.unsubscribe();
+ }
+
+ private setMode = (mode:ZoneInstanceMode, event?:any, afterSaveCallback?:Function):void => {
+
+ if(event){ //prevent event from handle and then repeat event from zone instance
+ event.stopPropagation();
+ }
+
+ if(!this.isActive && this.activeInstanceMode === ZoneInstanceMode.TAG) {
+ return; //someone else is tagging. No events allowed
+ }
+
+ if(this.isActive && this.zoneInstance.mode === ZoneInstanceMode.TAG){
+ if(mode !== ZoneInstanceMode.TAG) {
+ return; //ignore all other events. The only valid option is saving changes.
+ }
+
+ let oldAssignments:Array<IZoneInstanceAssignment> = this.zoneInstance.instanceData.getSavedAssignments();
+ if(this.zoneInstance.isZoneAssignmentChanged(oldAssignments, this.zoneInstance.assignments)) {
+
+ this.assignmentSaveStart.emit();
+
+ this.zoneService.updateZoneInstanceAssignments(this.zoneInstance.parentComponentType, this.zoneInstance.parentComponentID, this.zoneInstance.instanceData.uniqueId, this.zoneInstance.assignments).subscribe(
+ (success) => {
+ this.zoneInstance.instanceData.setSavedAssignments(this.zoneInstance.assignments);
+ if(this.zoneInstance.type === ZoneInstanceType.POLICY){
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_POLICY_INSTANCE_UPDATE, this.zoneInstance.instanceData);
+ } else {
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_GROUP_INSTANCE_UPDATE, this.zoneInstance.instanceData);
+ }
+ this.assignmentSaveComplete.emit(true);
+ if(afterSaveCallback) afterSaveCallback();
+ }, (error) => {
+ this.zoneInstance.assignments = oldAssignments;
+ this.assignmentSaveComplete.emit(false);
+ });
+ } else {
+ if(afterSaveCallback) afterSaveCallback();
+ }
+ this.modeChange.emit({newMode: ZoneInstanceMode.NONE, instance: this.zoneInstance});
+
+ } else {
+ this.modeChange.emit({newMode: mode, instance: this.zoneInstance});
+ }
+
+
+ }
+
+ private tagHandleClicked = (event:Event) => {
+ this.tagHandleClick.emit(this.zoneInstance);
+ event.stopPropagation();
+ };
+
}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts b/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts
index d1e68f3..c15f92c 100644
--- a/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts
+++ b/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts
@@ -53,6 +53,7 @@
@ViewChild('target', { read: ViewContainerRef }) target: any;
@Input() type: any;
@Input() name: string;
+ @Input() testId: string;
@Input() readonly:boolean;
@Input() path:string;//optional param. used only for for subnetpoolid type
@@ -111,6 +112,7 @@
if (this.cmpRef) {
this.cmpRef.instance.name = this.name;
this.cmpRef.instance.type = this.type;
+ this.cmpRef.instance.testId = this.testId;
this.cmpRef.instance.value = this.value;
this.cmpRef.instance.readonly = this.readonly;
}
@@ -133,7 +135,7 @@
case DynamicElementComponentCreatorIdentifier.FLOAT:
this.createComponent(UiElementIntegerInputComponent);
- this.cmpRef.instance.pattern = /^[-+]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?$/;
+ this.cmpRef.instance.pattern = /^[-+]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?$/.source;
break;
case DynamicElementComponentCreatorIdentifier.STRING:
@@ -156,10 +158,10 @@
case DynamicElementComponentCreatorIdentifier.DEFAULT:
default:
this.createComponent(UiElementInputComponent);
- console.log("ERROR: No ui component to handle type: " + this.type);
+ console.log("ERROR: No ui-models component to handle type: " + this.type);
}
- // Subscribe to change event of of ui-element-basic and fire event to change the value
+ // Subscribe to change event of of ui-models-element-basic and fire event to change the value
this.cmpRef.instance.baseEmitter.subscribe((event) => { this.emitter.emit(event); });
this.cmpRef.instance.valueChange.subscribe((event) => { this.valueChange.emit(event); });
}
diff --git a/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.html b/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.html
new file mode 100644
index 0000000..83daca2
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.html
@@ -0,0 +1,13 @@
+<h1 class="w-sdc-designer-sidebar-section-title"
+ tooltip="{{titleTooltip}}"
+ [ngClass]="{'expanded': state == 0, 'collapsed': state == 1}"
+ (click)="toggleState()">
+ {{caption}}<span class="w-sdc-designer-sidebar-section-title-icon"></span>
+ <ng-content select="header"></ng-content>
+ <span class="w-sdc-designer-sidebar-section-title-icon"></span>
+</h1>
+
+<div class="expand-collapse-content" [ngClass]="{'visible': state === 0, 'hidden': state === 1}">
+ <ng-content></ng-content>
+ <ng-content select="content"></ng-content>
+</div>
diff --git a/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.less b/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.less
new file mode 100644
index 0000000..e5dd252
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.less
@@ -0,0 +1,7 @@
+.ellipsis-directive-more-less {
+ float: right;
+ margin-right: 10px;
+ line-height: 23px;
+ text-decoration: underline;
+ text-align: left;
+}
diff --git a/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.ts b/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.ts
new file mode 100644
index 0000000..0fa0d33
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/expand-collapse/expand-collapse.component.ts
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import { Component, Input, Output, ViewEncapsulation, AfterViewInit } from '@angular/core';
+
+export enum ExpandState {
+ EXPANDED,
+ COLLAPSED
+}
+
+@Component({
+ selector: 'ng2-expand-collapse',
+ templateUrl: './expand-collapse.component.html',
+ styleUrls: ['./expand-collapse.component.less'],
+ encapsulation: ViewEncapsulation.None
+})
+
+export class ExpandCollapseComponent implements AfterViewInit {
+ @Input() caption: String;
+ @Input() state: ExpandState;
+ @Input() titleTooltip: String;
+
+ constructor() {
+
+ }
+
+ toggleState():void {
+ if (this.state == ExpandState.EXPANDED) {
+ this.state = ExpandState.COLLAPSED;
+ } else {
+ this.state = ExpandState.EXPANDED;
+ }
+ }
+
+ ngAfterViewInit(): void {
+
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component.html b/catalog-ui/src/app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component.html
index 805e5ac..c564abc 100644
--- a/catalog-ui/src/app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component.html
+++ b/catalog-ui/src/app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component.html
@@ -1,3 +1,3 @@
-<select name='{{name}}' [(ngModel)]="value" (change)="onChange()" [ngClass]="{'disabled':readonly}" data-tests-id="SelectType">
+<select name='{{name}}' [(ngModel)]="value" (change)="onChange()" [ngClass]="{'disabled':readonly}" [attr.data-tests-id]="'value-' + testId">
<option *ngFor="let ddvalue of values" [ngValue]="ddvalue.label != undefined ? ddvalue.value : ddvalue">{{ddvalue.label||ddvalue}}</option>
</select>
diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/input/ui-element-input.component.html b/catalog-ui/src/app/ng2/components/ui/form-components/input/ui-element-input.component.html
index 057e731..fdba850 100644
--- a/catalog-ui/src/app/ng2/components/ui/form-components/input/ui-element-input.component.html
+++ b/catalog-ui/src/app/ng2/components/ui/form-components/input/ui-element-input.component.html
@@ -11,4 +11,5 @@
[formControl]="control"
tooltip="{{value}}"
[readonly]="readonly"
+ [attr.data-tests-id]="'value-' + testId"
/>
diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/integer-input/ui-element-integer-input.component.html b/catalog-ui/src/app/ng2/components/ui/form-components/integer-input/ui-element-integer-input.component.html
index e1555e8..04307e4 100644
--- a/catalog-ui/src/app/ng2/components/ui/form-components/integer-input/ui-element-integer-input.component.html
+++ b/catalog-ui/src/app/ng2/components/ui/form-components/integer-input/ui-element-integer-input.component.html
@@ -11,4 +11,5 @@
[formControl]="control"
tooltip="{{value}}"
[readonly]="readonly"
+ [attr.data-tests-id]="'value-' + testId"
/>
diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.html b/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.html
index 3bd51b4..3bc94de 100644
--- a/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.html
+++ b/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.html
@@ -7,7 +7,7 @@
[value]="value!=undefined?value:''"
disabled
/>
- <button [popover]="popoverForm" [ngClass]="{'disabled':readonly}">Edit</button>
+ <button [popover]="popoverForm" (onShown)="setEditValue()" [ngClass]="{'disabled':readonly}" [attr.data-tests-id] ="'edit-button-' + testId">Edit</button>
</div>
<popover-content #popoverForm [title]="name" [buttons]="buttonsArray" [placement]="'top'" [closeOnClickOutside]="true">
@@ -16,11 +16,12 @@
#textArea
class="subnet-value"
[ngClass]="{'error': control.invalid}"
- [(ngModel)]="value"
+ [(ngModel)]="editValue"
[attr.maxlength]="validation.propertyValue.max"
[attr.minlength]="validation.propertyValue.min"
[pattern]="pattern"
[formControl]="control"
+ [attr.data-tests-id]="'value-' + testId"
></textarea>
</div>
</popover-content>
diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.ts b/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.ts
index 525cd17..f485d27 100644
--- a/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.ts
+++ b/catalog-ui/src/app/ng2/components/ui/form-components/popover-input/ui-element-popover-input.component.ts
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-import {Component, ViewChild, ElementRef, Input} from '@angular/core';
+import {Component, ViewChild, ElementRef} from '@angular/core';
import {ButtonsModelMap, ButtonModel} from "app/models";
import {PopoverContentComponent} from "../../popover/popover-content.component";
import {UiElementBase, UiElementBaseInterface} from "../ui-element-base.component";
@@ -32,13 +32,14 @@
@ViewChild('textArea') textArea: ElementRef;
@ViewChild('popoverForm') popoverContentComponent: PopoverContentComponent;
+ editValue: any;
saveButton: ButtonModel;
buttonsArray: ButtonsModelMap;
constructor() {
super();
// Create Save button and insert to buttons map
- this.saveButton = new ButtonModel('save', 'blue', this.onChange);
+ this.saveButton = new ButtonModel('Set', 'blue', this.onChange.bind(this));
this.buttonsArray = { 'test': this.saveButton };
// Define the regex pattern for this controller
@@ -47,4 +48,15 @@
// Disable / Enable button according to validation
//this.control.valueChanges.subscribe(data => this.saveButton.disabled = this.control.invalid);
}
+
+ public setEditValue() {
+ // copy value to edit
+ this.editValue = angular.copy(this.value);
+ }
+
+ public onChange() {
+ this.popoverContentComponent.hide();
+ this.value = this.editValue;
+ super.onChange();
+ }
}
diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/ui-element-base.component.ts b/catalog-ui/src/app/ng2/components/ui/form-components/ui-element-base.component.ts
index b4e9e7d..31fa7c3 100644
--- a/catalog-ui/src/app/ng2/components/ui/form-components/ui-element-base.component.ts
+++ b/catalog-ui/src/app/ng2/components/ui/form-components/ui-element-base.component.ts
@@ -46,9 +46,12 @@
@Input() name: string;
@Input() type: string;
+ @Input() path: string;
@Input() pattern: any;
@Input() readonly:boolean;
+ @Input() testId:string;
+
constructor() {
//this.control = new FormControl('', [Validators.required]);
this.control = new FormControl('', []);
diff --git a/catalog-ui/src/app/ng2/components/ui/forms/modal-forms.module.ts b/catalog-ui/src/app/ng2/components/ui/forms/modal-forms.module.ts
new file mode 100644
index 0000000..34404e5
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/forms/modal-forms.module.ts
@@ -0,0 +1,27 @@
+import { NgModule } from "@angular/core";
+import { CommonModule } from '@angular/common';
+import { SdcUiComponentsModule } from "sdc-ui/lib/angular";
+import { ValueEditComponent } from './value-edit/value-edit.component';
+import { UnsavedChangesComponent } from "./unsaved-changes/unsaved-changes.component";
+import { UiElementsModule } from "../ui-elements.module";
+
+
+
+@NgModule({
+ declarations: [
+ ValueEditComponent,
+ UnsavedChangesComponent
+ ],
+ imports: [
+ CommonModule,
+ SdcUiComponentsModule,
+ UiElementsModule
+ ],
+ exports: [ValueEditComponent, UnsavedChangesComponent],
+ entryComponents: [ UnsavedChangesComponent
+ ],
+ providers: []
+})
+export class ModalFormsModule {
+
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component.html b/catalog-ui/src/app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component.html
new file mode 100644
index 0000000..bdf21de
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component.html
@@ -0,0 +1,6 @@
+<div class="unsaved-changes-modal">
+ <div class="message">
+ <p>Your changes {{isValidChangedData ? '' : '(invalid)'}} have not been saved.</p>
+ <p>Do you want to {{isValidChangedData ? 'save' : 'discard'}} them?</p>
+ </div>
+</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component.ts b/catalog-ui/src/app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component.ts
new file mode 100644
index 0000000..b8fdeaf
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component.ts
@@ -0,0 +1,17 @@
+import { Component, Input } from "@angular/core";
+
+@Component({
+ selector: 'unsaved-changes',
+ templateUrl: './unsaved-changes.component.html',
+ styleUrls: []
+})
+export class UnsavedChangesComponent {
+
+ @Input() isValidChangedData:boolean;
+
+ constructor(){
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.html b/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.html
new file mode 100644
index 0000000..464b756
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.html
@@ -0,0 +1,12 @@
+<div class="name-update-container">
+ <sdc-input #updateNameInput
+ label="Instance Name"
+ required="true"
+ [maxLength]="50"
+ [(value)]="name"
+ testId="instanceName"></sdc-input>
+ <sdc-validation [validateElement]="updateNameInput" (validityChanged)="validityChanged($event)">
+ <sdc-required-validator message="Name is required."></sdc-required-validator>
+ <sdc-regex-validator message="Special characters not allowed." [pattern]="pattern"></sdc-regex-validator>
+ </sdc-validation>
+</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.less b/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.less
new file mode 100644
index 0000000..b958ca1
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.less
@@ -0,0 +1,3 @@
+.name-update-container {
+ min-height: 90px;
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.ts b/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.ts
new file mode 100644
index 0000000..08bc058
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/forms/value-edit/value-edit.component.ts
@@ -0,0 +1,25 @@
+import { Component, Input } from "@angular/core";
+
+@Component({
+ selector: 'value-edit',
+ templateUrl: './value-edit.component.html',
+ styleUrls: ['./value-edit.component.less']
+})
+export class ValueEditComponent {
+
+ @Input() name:String;
+ @Input() validityChangedCallback: Function;
+
+ private pattern:string = "^[\\s\\w\&_.:-]{1,1024}$"
+ constructor(){
+ }
+
+ private validityChanged = (value):void => {
+ if(this.validityChangedCallback) {
+ this.validityChangedCallback(value);
+ }
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.html b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.html
new file mode 100644
index 0000000..ba89719
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.html
@@ -0,0 +1,30 @@
+<div class="component-add-element">
+ <div class="add-element-selection-container">
+ <sdc-dropdown class="add-element-selection" selectedOption="selectedElement" placeHolder="Please choose option"
+ (changed)="onElementSelected($event)" [options]="dropdownOptions"></sdc-dropdown>
+ <svg-icon-label class="add-element-button" [class.disabled]="!selectedElement"
+ name="plus-circle-o"
+ mode="primary"
+ size="medium"
+ label="ADD"
+ labelPlacement="right"
+ clickable="{{!!selectedElement}}"
+ (click)="addElement()">
+ </svg-icon-label>
+ </div>
+
+ <div class="elements-list">
+ <ul>
+ <li *ngFor="let element of existingElements" class="elements-list-item">
+ <span>{{element.name}}</span>
+ <svg-icon-label name="trash-o" clickable="true" size="small" class="elements-list-item-delete"
+ data-tests-id="delete_target" (click)="removeElement(element)"></svg-icon-label>
+ </li>
+ </ul>
+ <div *ngIf="existingElements.length===0" class="add-element-no-data">
+ <div class="add-element-no-data-title">No {{elementName}} have been added yet.</div>
+ <div class="add-element-no-data-content">Begin typing or select {{elementName}} above</div>
+ </div>
+ </div>
+
+</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.less b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.less
new file mode 100644
index 0000000..522483d
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.less
@@ -0,0 +1,61 @@
+@import "./../../../../../../assets/styles/variables-old";
+
+.component-add-element {
+
+ .add-element-selection-container {
+
+ display: flex;
+ flex-direction: row;
+ .add-element-selection {
+ flex: 2;
+ }
+
+ .add-element-button {
+ padding: 0px 0px 0px 15px;
+ &:not(.disabled) {
+ cursor:pointer;
+ }
+ }
+
+ }
+
+ .elements-list {
+ border: 1px solid #d2d2d2;
+ margin-top: 10px;
+ height: 300px;
+ overflow: auto;
+
+ .elements-list-item {
+ padding: 10px 20px 10px 20px;
+
+ &:first-child {
+ padding-top: 15px;
+ }
+
+ &:hover {
+ background-color: #f8f8f8;
+ .elements-list-item-delete {
+ visibility: visible;
+ }
+ }
+ }
+ }
+
+ .elements-list-item-delete {
+ float:right;
+ cursor: pointer;
+ visibility: hidden;
+ }
+
+
+ .add-element-no-data {
+ margin: 0 auto;
+ padding-top: 30px;
+ text-align: center;
+
+ .add-element-no-data-title {
+ font-family: @font-opensans-bold;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.ts b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.ts
new file mode 100644
index 0000000..1d05b27
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.component.ts
@@ -0,0 +1,65 @@
+/**
+ * Created by ob0695 on 11.04.2018.
+ */
+import {Component, Input} from "@angular/core";
+import {UiBaseObject} from "../../../../../models/ui-models/ui-base-object";
+import {IDropDownOption} from "sdc-ui/lib/angular/form-elements/dropdown/dropdown-models";
+
+@Component({
+ selector: 'add-elements',
+ templateUrl: './add-elements.component.html',
+ styleUrls: ['./add-elements.component.less']
+})
+
+export class AddElementsComponent {
+
+ @Input() elementsToAdd:Array<UiBaseObject>;
+ @Input() elementName: string;
+
+ private existingElements:Array<UiBaseObject>;
+ private dropdownOptions:Array<IDropDownOption>;
+ private selectedElement:IDropDownOption;
+
+ ngOnInit() {
+ this.existingElements = [];
+ this.convertElementToDropdownDisplay();
+
+ }
+
+ private convertElementToDropdownDisplay = () => {
+ this.dropdownOptions = [];
+ _.forEach(this.elementsToAdd, (elementToAdd:UiBaseObject) =>{
+ this.dropdownOptions.push({label:elementToAdd.name, value: elementToAdd.uniqueId })
+ });
+ }
+
+ onElementSelected(selectedElement:IDropDownOption):void {
+ this.selectedElement = selectedElement
+ }
+
+ addElement():void {
+
+ if(this.selectedElement){
+ this.dropdownOptions = _.reject(this.dropdownOptions, (option: IDropDownOption) => { // remove from dropDown
+ return option.value === this.selectedElement.value;
+ });
+
+ let selected = _.find(this.elementsToAdd, (element:UiBaseObject) => {
+ return this.selectedElement.value === element.uniqueId;
+ });
+
+ this.elementsToAdd =_.without(this.elementsToAdd, selected); // remove from optional elements to add
+ this.existingElements.push(selected); // add to existing element list
+ this.selectedElement = undefined;
+ } else {
+ console.log("no element selected"); //TODO:show error?
+ }
+ }
+
+ removeElement(element:UiBaseObject):void {
+
+ this.existingElements =_.without(this.existingElements, element); // remove from optional elements to add
+ this.dropdownOptions.push({label:element.name, value: element.uniqueId });
+ this.elementsToAdd.push(element);
+ }
+}
diff --git a/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.module.ts b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.module.ts
new file mode 100644
index 0000000..a1c34f5
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/modal/add-elements/add-elements.module.ts
@@ -0,0 +1,30 @@
+/**
+ * Created by ob0695 on 11.04.2018.
+ */
+import {NgModule} from "@angular/core";
+import {SdcUiComponentsModule} from "sdc-ui/lib/angular/index";
+import {AddElementsComponent} from "./add-elements.component";
+import {CommonModule} from "@angular/common";
+
+/**
+ * Created by ob0695 on 9.04.2018.
+ */
+@NgModule({
+ declarations: [
+ AddElementsComponent
+ ],
+
+ imports: [
+ CommonModule,
+ SdcUiComponentsModule
+ ],
+
+ entryComponents: [
+ AddElementsComponent
+ ],
+ exports: [],
+ providers: []
+})
+export class AddElementsModule {
+
+}
diff --git a/catalog-ui/src/app/ng2/components/ui/modal/modal.component.html b/catalog-ui/src/app/ng2/components/ui/modal/modal.component.html
index 6fc55d1..1708fc4 100644
--- a/catalog-ui/src/app/ng2/components/ui/modal/modal.component.html
+++ b/catalog-ui/src/app/ng2/components/ui/modal/modal.component.html
@@ -1,6 +1,5 @@
<div class="custom-modal {{input.size}}">
<div class="ng2-modal-content"
- ngDraggable
[ngDraggable]="input.isMovable"
[handle]="ModalHandle"
[bounds]="ModalBounds"
diff --git a/catalog-ui/src/app/ng2/components/ui/palette-animation/palette-animation.component.ts b/catalog-ui/src/app/ng2/components/ui/palette-animation/palette-animation.component.ts
index 609a1fc..7e45b9e 100644
--- a/catalog-ui/src/app/ng2/components/ui/palette-animation/palette-animation.component.ts
+++ b/catalog-ui/src/app/ng2/components/ui/palette-animation/palette-animation.component.ts
@@ -24,6 +24,7 @@
import { EventListenerService } from 'app/services';
import { GRAPH_EVENTS } from 'app/utils';
import { Point } from 'app/models';
+import { ZoneInstanceType, ZoneInstance } from '../../../../models/graph/zones/zone-instance';
@@ -37,8 +38,9 @@
@Input() from : Point;
@Input() to : Point;
+ @Input() type: ZoneInstanceType;
@Input() iconName : string;
- @Input() data : any;
+ @Input() zoneInstance : ZoneInstance;
public animation;
private visible:boolean = false;
@@ -47,6 +49,11 @@
constructor(private eventListenerService:EventListenerService) {}
+
+ ngOnDestroy(){
+ this.zoneInstance.hidden = false; //if animation component is destroyed before animation is complete
+ }
+
public runAnimation() {
this.visible = true;
let positionDiff:Point = new Point(this.to.x - this.from.x, this.to.y - this.from.y);
@@ -57,7 +64,7 @@
public animationComplete = (e) => {
this.visible = false;
- this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_FINISH_ANIMATION_ZONE);
+ this.zoneInstance.hidden = false;
};
diff --git a/catalog-ui/src/app/ng2/components/ui/palette-popup-panel/palette-popup-panel.component.ts b/catalog-ui/src/app/ng2/components/ui/palette-popup-panel/palette-popup-panel.component.ts
index d30d5f6..a10ca7d 100644
--- a/catalog-ui/src/app/ng2/components/ui/palette-popup-panel/palette-popup-panel.component.ts
+++ b/catalog-ui/src/app/ng2/components/ui/palette-popup-panel/palette-popup-panel.component.ts
@@ -35,7 +35,8 @@
public addZoneInstance(): void {
if(this.displayComponent) {
- this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_ADD_COMPONENT_INSTANCE_ZONE_START, this.component, this.displayComponent, this.popupPanelPosition);
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_ADD_ZONE_INSTANCE_FROM_PALETTE, this.component, this.displayComponent, this.popupPanelPosition);
+ this.hidePopupPanel();
}
}
diff --git a/catalog-ui/src/app/ng2/components/ui/tile/tile.component.html b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.html
new file mode 100644
index 0000000..a7a7b2c
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.html
@@ -0,0 +1,28 @@
+<div class="sdc-tile sdc-tile-fix-width">
+
+ <div class='sdc-tile-header' [ngClass]="{'purple': component.isResource(), 'blue': !component.isResource()}">
+ <div *ngIf="component.isResource()" data-tests-id="asset-type">{{component.getComponentSubType()}}</div>
+ <div *ngIf="component.isService()">S</div>
+ </div>
+
+ <div class='sdc-tile-content' data-tests-id="dashboard-Elements" (click)="tileClicked()">
+ <div class='sdc-tile-content-icon'>
+ <div [ngClass]="[component.iconSprite, component.icon]" [ngClass]="{'sprite-resource-icons': component.isResource(), 'sprite-services-icons': component.isService()}"
+ [attr.data-tests-id]="component.name"></div>
+ </div>
+
+ <div class='sdc-tile-content-info'>
+ <div class="sdc-tile-info-line title" [attr.data-tests-id]="component.name | resourceName" [tooltip]="component.name | resourceName" [tooltipDisabled]="!hasEllipsis">
+ <multiline-ellipsis className="w-sdc-tile-multiline-ellipsis" [lines]="3" (hasEllipsisChanged)="hasEllipsis = $event">{{component.name | resourceName}}</multiline-ellipsis>
+ </div>
+ <div class="sdc-tile-info-line subtitle" [attr.data-tests-id]="component.name+'Version'">V {{component.version}}</div>
+ </div>
+ </div>
+
+ <div class='sdc-tile-footer'>
+ <div class="sdc-tile-footer-content">
+ <div class='sdc-tile-footer-text'>{{component.getStatus(sdcMenu)}}</div>
+ </div>
+ </div>
+
+</div>
diff --git a/catalog-ui/src/app/ng2/components/ui/tile/tile.component.less b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.less
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.less
diff --git a/catalog-ui/src/app/ng2/components/ui/tile/tile.component.ts b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.ts
new file mode 100644
index 0000000..b6f6358
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/tile/tile.component.ts
@@ -0,0 +1,24 @@
+import {Component, Input, Output, Inject, EventEmitter} from '@angular/core';
+import {Component as ComponentModel} from 'app/models';
+import {SdcMenuToken, IAppMenu} from "../../../config/sdc-menu.config";
+
+@Component({
+ selector: 'ui-tile',
+ templateUrl: './tile.component.html',
+ styleUrls: ['./tile.component.less']
+})
+export class TileComponent {
+ @Input() public component: ComponentModel;
+ @Output() public onTileClick: EventEmitter<ComponentModel>;
+
+ public hasEllipsis: boolean;
+
+ constructor(@Inject(SdcMenuToken) public sdcMenu:IAppMenu) {
+ this.onTileClick = new EventEmitter<ComponentModel>();
+ this.hasEllipsis = false;
+ }
+
+ public tileClicked() {
+ this.onTileClick.emit(this.component);
+ }
+}
diff --git a/catalog-ui/src/app/ng2/components/ui/tile/tile.module.ts b/catalog-ui/src/app/ng2/components/ui/tile/tile.module.ts
new file mode 100644
index 0000000..55b3440
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/tile/tile.module.ts
@@ -0,0 +1,15 @@
+import { NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+import { TileComponent } from './tile.component';
+import { GlobalPipesModule } from "../../../pipes/global-pipes.module";
+import { TooltipModule } from "../tooltip/tooltip.module";
+import {MultilineEllipsisModule} from "../../../shared/multiline-ellipsis/multiline-ellipsis.module";
+
+
+@NgModule({
+ imports: [BrowserModule, GlobalPipesModule, TooltipModule, MultilineEllipsisModule],
+ declarations: [TileComponent],
+ exports: [TileComponent],
+ entryComponents: [TileComponent]
+})
+export class TileModule { }
diff --git a/catalog-ui/src/app/ng2/components/ui/ui-elements.module.ts b/catalog-ui/src/app/ng2/components/ui/ui-elements.module.ts
index 4431473..e905db7 100644
--- a/catalog-ui/src/app/ng2/components/ui/ui-elements.module.ts
+++ b/catalog-ui/src/app/ng2/components/ui/ui-elements.module.ts
@@ -20,26 +20,28 @@
import { NgModule } from '@angular/core';
import { NavbarModule } from "./navbar/navbar.module";
-import {DynamicElementModule} from "./dynamic-element/dynamic-element.module";
-import {FormElementsModule} from "./form-components/form-elements.module";
-import {LoaderComponent} from "./loader/loader.component";
-import {ModalModule} from "./modal/modal.module";
-import {PopoverModule} from "./popover/popover.module";
-import {SearchBarComponent} from "./search-bar/search-bar.component";
-import {SearchWithAutoCompleteComponent} from "./search-with-autocomplete/search-with-autocomplete.component";
-import {PalettePopupPanelComponent} from "./palette-popup-panel/palette-popup-panel.component";
-import {ZoneContainerComponent} from "./canvas-zone/zone-container.component";
-import {ZoneInstanceComponent } from "./canvas-zone/zone-instance/zone-instance.component";
-import {PaletteAnimationComponent} from "./palette-animation/palette-animation.component"
-import {TabModule} from "./tabs/tabs.module";
-import {TooltipModule} from "./tooltip/tooltip.module";
-import {CommonModule} from "@angular/common";
-import {FormsModule} from "@angular/forms";
-import {BrowserModule} from "@angular/platform-browser";
-import {MultiStepsWizardModule} from "./multi-steps-wizard/multi-steps-wizard.module";
-import {MenuListModule} from "./menu/menu-list.module";
-import {MenuListNg2Module} from "../downgrade-wrappers/menu-list-ng2/menu-list-ng2.module";
-//import {SdcUiComponentsModule} from "sdc-ui/lib/angular";
+import { DynamicElementModule } from "./dynamic-element/dynamic-element.module";
+import { FormElementsModule } from "./form-components/form-elements.module";
+import { LoaderComponent } from "./loader/loader.component";
+import { ModalModule } from "./modal/modal.module";
+import { PopoverModule } from "./popover/popover.module";
+import { SearchBarComponent } from "./search-bar/search-bar.component";
+import { SearchWithAutoCompleteComponent } from "./search-with-autocomplete/search-with-autocomplete.component";
+import { PalettePopupPanelComponent } from "./palette-popup-panel/palette-popup-panel.component";
+import { ZoneContainerComponent } from "./canvas-zone/zone-container.component";
+import { ZoneInstanceComponent } from "./canvas-zone/zone-instance/zone-instance.component";
+import { PaletteAnimationComponent } from "./palette-animation/palette-animation.component"
+import { TabModule } from "./tabs/tabs.module";
+import { TooltipModule } from "./tooltip/tooltip.module";
+import { CommonModule } from "@angular/common";
+import { FormsModule } from "@angular/forms";
+import { BrowserModule } from "@angular/platform-browser";
+import { MultiStepsWizardModule } from "./multi-steps-wizard/multi-steps-wizard.module";
+import { MenuListModule } from "./menu/menu-list.module";
+import { MenuListNg2Module } from "../downgrade-wrappers/menu-list-ng2/menu-list-ng2.module";
+import { ExpandCollapseComponent } from './expand-collapse/expand-collapse.component';
+import { SdcUiComponentsModule } from "sdc-ui/lib/angular";
+import { TileModule } from "./tile/tile.module";
@NgModule({
declarations: [
@@ -49,11 +51,12 @@
PalettePopupPanelComponent,
ZoneContainerComponent,
ZoneInstanceComponent,
- PaletteAnimationComponent
+ PaletteAnimationComponent,
+ ExpandCollapseComponent
],
-
+
imports: [
- //SdcUiComponentsModule,
+ SdcUiComponentsModule,
BrowserModule,
FormsModule,
CommonModule,
@@ -66,7 +69,8 @@
TooltipModule,
MultiStepsWizardModule,
MenuListModule,
- MenuListNg2Module
+ MenuListNg2Module,
+ TileModule
],
exports: [
LoaderComponent,
@@ -85,7 +89,9 @@
TooltipModule,
MenuListModule,
MenuListNg2Module,
- PaletteAnimationComponent
+ PaletteAnimationComponent,
+ ExpandCollapseComponent,
+ TileModule
],
entryComponents: [SearchWithAutoCompleteComponent, PalettePopupPanelComponent, ZoneContainerComponent, ZoneInstanceComponent, PaletteAnimationComponent]
})
diff --git a/catalog-ui/src/app/ng2/config/sdc-menu.config.factory.ts b/catalog-ui/src/app/ng2/config/sdc-menu.config.factory.ts
new file mode 100644
index 0000000..4417c32
--- /dev/null
+++ b/catalog-ui/src/app/ng2/config/sdc-menu.config.factory.ts
@@ -0,0 +1,6 @@
+import {IAppMenu} from "app/models";
+
+export function getSdcMenu() : IAppMenu{
+ const sdcMenu:IAppMenu = require('./../../../../configurations/menu.js');
+ return sdcMenu;
+}
diff --git a/catalog-ui/src/app/ng2/config/sdc-menu.config.ts b/catalog-ui/src/app/ng2/config/sdc-menu.config.ts
new file mode 100644
index 0000000..07680b5
--- /dev/null
+++ b/catalog-ui/src/app/ng2/config/sdc-menu.config.ts
@@ -0,0 +1,12 @@
+import {Provider, OpaqueToken} from "@angular/core";
+import {getSdcMenu} from "./sdc-menu.config.factory";
+import {IAppMenu} from "app/models";
+
+export { IAppMenu };
+
+export const SdcMenuToken = new OpaqueToken('SdcMenuToken');
+
+export const SdcMenu:Provider = {
+ provide: SdcMenuToken,
+ useFactory: getSdcMenu
+};
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-models/ui-component-to-upgrade.ts b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-models/ui-component-to-upgrade.ts
new file mode 100644
index 0000000..97fb71e
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-models/ui-component-to-upgrade.ts
@@ -0,0 +1,103 @@
+import {ComponentState} from "../../../../utils/constants";
+import {IDependenciesServerResponse} from "../../../services/responses/dependencies-server-response";
+import {UiBaseObject} from "../../../../models/ui-models/ui-base-object";
+
+/**
+ * Created by ob0695 on 5/1/2018.
+ */
+export enum AutomatedUpgradeInstanceType {
+ VF, SERVICE_PROXY, ALLOTTED_RESOURCE
+}
+export class ServiceContainerToUpgradeUiObject extends UiBaseObject {
+
+ icon:string;
+ version:string;
+ isLock:boolean; // true if service is in check-out or ceritification-in-progress
+ vspInstances:Array<VspInstanceUiObject>; // list of instances of the vsp contain in the service - intances can be vf, proxy or allotted
+ isAlreadyUpgrade:boolean; // true if all instances is in latest version
+
+ constructor(componentToUpgrade:IDependenciesServerResponse) {
+ super(componentToUpgrade.uniqueId, componentToUpgrade.type, componentToUpgrade.name);
+ this.icon = componentToUpgrade.icon;
+ this.version = componentToUpgrade.version;
+ this.isAlreadyUpgrade = true;
+ this.isLock = componentToUpgrade.state === ComponentState.CERTIFICATION_IN_PROGRESS || componentToUpgrade.state === ComponentState.NOT_CERTIFIED_CHECKOUT;
+ this.vspInstances = [];
+ }
+
+ public addVfInstance = (vsp: IDependenciesServerResponse, latestVersion:string):void => {
+ let isNeededUpgrade = parseInt(vsp.version) < parseInt(latestVersion);
+ this.vspInstances.push(new VspInstanceUiObject(vsp.uniqueId, vsp.name, vsp.version, vsp.icon));
+ if (isNeededUpgrade) {
+ this.isAlreadyUpgrade = false;
+ }
+ }
+
+ public addProxyInstance = (vsp: IDependenciesServerResponse, isNeededUpgrade:boolean, instanceName:string):void => {
+ this.vspInstances.push(new ProxyVspInstanceUiObject(vsp.uniqueId, vsp.name, vsp.version, vsp.icon, instanceName));
+ if (isNeededUpgrade) {
+ this.isAlreadyUpgrade = false;
+ }
+ }
+
+ public addAllottedResourceInstance = (vsp: IDependenciesServerResponse, isNeededUpgrade:boolean, instanceName:string, vfName:string, vfId:string):void => {
+ this.vspInstances.push(new AllottedResourceInstanceUiObject(vsp.uniqueId, vsp.name, vsp.version, vsp.icon, instanceName, vfName, vfId));
+ if (isNeededUpgrade) {
+ this.isAlreadyUpgrade = false;
+ }
+ }
+
+ public addMultipleInstances = (vsp: IDependenciesServerResponse, vspLatestVersion:string, instancesNames:Array<string>, allottedOriginVf: IDependenciesServerResponse):void => {
+ _.forEach(instancesNames, (instanceName:string) => {
+ let isNeededUpgrade = parseInt(vsp.version) < parseInt(vspLatestVersion);
+ if (allottedOriginVf) {
+ this.addAllottedResourceInstance(vsp, isNeededUpgrade, instanceName, allottedOriginVf.name, allottedOriginVf.uniqueId);
+ } else {
+ this.addProxyInstance(vsp, isNeededUpgrade, instanceName);
+ }
+ })
+ }
+}
+
+export class VspInstanceUiObject {
+
+ vspName:string;
+ vspVersion:string;
+ vspId:string;
+ icon:string;
+ instanceType:AutomatedUpgradeInstanceType;
+
+ constructor(uniqueId:string, vspName:string, vspVersion:string, icon:string) {
+ this.vspId = uniqueId;
+ this.vspName = vspName;
+ this.vspVersion = vspVersion;
+ this.icon = icon;
+ this.instanceType = AutomatedUpgradeInstanceType.VF;
+ }
+}
+
+export class ProxyVspInstanceUiObject extends VspInstanceUiObject {
+
+ instanceName:string;
+
+ constructor(uniqueId:string, vspName:string, vspVersion:string, icon:string, instanceName: string) {
+ super(uniqueId, vspName, vspVersion, icon);
+ this.instanceName = instanceName;
+ this.instanceType = AutomatedUpgradeInstanceType.SERVICE_PROXY;
+ }
+}
+
+export class AllottedResourceInstanceUiObject extends VspInstanceUiObject {
+
+ instanceName:string;
+ originVfName:string;
+ originVfId:string;
+
+ constructor(uniqueId:string, vspName:string, vspVersion:string, icon:string, instanceName:string, originVfName:string, originVfId:string) {
+ super(uniqueId, vspName, vspVersion, icon)
+ this.instanceName = instanceName;
+ this.originVfId = originVfId;
+ this.originVfName = originVfName;
+ this.instanceType = AutomatedUpgradeInstanceType.ALLOTTED_RESOURCE;
+ }
+}
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-status/automated-upgrade-status.component.html b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-status/automated-upgrade-status.component.html
new file mode 100644
index 0000000..12a3b72
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-status/automated-upgrade-status.component.html
@@ -0,0 +1,10 @@
+<div class="automated-upgrade-component">
+ <span innerHTML="{{statusText}}"> </span>
+ <div class="components-to-upgrade-list">
+ <ul>
+ <li class="components-to-upgrade-list-item " *ngFor="let component of upgradedComponentsList">
+ <upgrade-list-status-item [upgradedComponent]="component" [upgradeComponentStatus]="upgradeStatusMap[component.name]"></upgrade-list-status-item>
+ </li>
+ </ul>
+ </div>
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-status/automated-upgrade-status.component.ts b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-status/automated-upgrade-status.component.ts
new file mode 100644
index 0000000..0bc342c
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-status/automated-upgrade-status.component.ts
@@ -0,0 +1,24 @@
+/**
+ * Created by ob0695 on 4/24/2018.
+ */
+import {Component, Input} from "@angular/core";
+import Dictionary = _.Dictionary;
+import {AutomatedUpgradeStatusResponse} from "../../../services/responses/automated-upgrade-response";
+import {ServiceContainerToUpgradeUiObject} from "../automated-upgrade-models/ui-component-to-upgrade";
+
+@Component({
+ selector: 'automated-upgrade-status',
+ templateUrl: './automated-upgrade-status.component.html',
+ styleUrls: ['./../automated-upgrade.component.less']
+})
+export class AutomatedUpgradeStatusComponent {
+
+ @Input() upgradedComponentsList: Array<ServiceContainerToUpgradeUiObject>;
+ @Input() upgradeStatusMap: Dictionary<AutomatedUpgradeStatusResponse>;
+ @Input() statusText: string;
+
+ constructor () {
+
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/list-item-inner-content/list-item-inner-content.component.html b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/list-item-inner-content/list-item-inner-content.component.html
new file mode 100644
index 0000000..2a03d94
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/list-item-inner-content/list-item-inner-content.component.html
@@ -0,0 +1,25 @@
+<ul class="list-item-inner-content">
+ <li *ngFor="let vspInstance of vspInstances" class="first-line">
+ <div [ngSwitch]="vspInstance.instanceType">
+
+ <div *ngSwitchCase="automatedUpgradeType.VF">
+ <upgrade-line-item arrowName="arrow2-right-child" text="{{vspInstance.vspName}} ({{vspInstance.vspVersion}})"></upgrade-line-item>
+ </div>
+
+ <div *ngSwitchCase="automatedUpgradeType.SERVICE_PROXY">
+ <upgrade-line-item arrowName="arrow2-right-child" prefix="Service Proxy: " text="{{vspInstance.instanceName}}"></upgrade-line-item>
+ <div class="second-line">
+ <upgrade-line-item arrowName="arrow2-right-child" icon="{{vspInstance.icon}}" text="{{ vspInstance.vspName }} ({{vspInstance.vspVersion}})"></upgrade-line-item>
+ </div>
+ </div>
+
+ <div *ngSwitchCase="automatedUpgradeType.ALLOTTED_RESOURCE">
+ <upgrade-line-item class="allotted-resource-line" arrowName="arrow2-right-child" prefix=" VNF: " text="{{vspInstance.originVfName}}"></upgrade-line-item>
+ <upgrade-line-item arrowName="arrow2-right" prefix=" VFC: " text="{{vspInstance.instanceName}}"></upgrade-line-item>
+ <div class="second-line">
+ <upgrade-line-item arrowName="arrow2-right-child" icon="vspInstance.icon" prefix=" VFC: " text="{{ vspInstance.vspName }} ({{vspInstance.vspVersion}})"></upgrade-line-item>
+ </div>
+ </div>
+ </div>
+ </li>
+</ul>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/list-item-inner-content/list-item-inner-content.component.less b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/list-item-inner-content/list-item-inner-content.component.less
new file mode 100644
index 0000000..24f8107
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/list-item-inner-content/list-item-inner-content.component.less
@@ -0,0 +1,25 @@
+@import "./../../../../../../assets/styles/override";
+
+.list-item-inner-content {
+ .first-line {
+
+ padding: 2px 20px 2px 65px;
+ border-bottom: 1px solid @sdcui_color_silver;
+
+ &:last-child {
+ border-bottom: none;
+ }
+ }
+
+ .second-line {
+ padding-left: 45px;
+ font-weight: bold;
+ }
+
+ .allotted-resource-line {
+
+ float: left;
+ margin-right: 15px;
+
+ }
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/list-item-inner-content/list-item-inner-content.component.ts b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/list-item-inner-content/list-item-inner-content.component.ts
new file mode 100644
index 0000000..0fa467c
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/list-item-inner-content/list-item-inner-content.component.ts
@@ -0,0 +1,24 @@
+/**
+ * Created by ob0695 on 5/7/2018.
+ */
+/**
+ * Created by ob0695 on 5/2/2018.
+ */
+import {Component, Input} from "@angular/core";
+import {
+ VspInstanceUiObject,
+ AutomatedUpgradeInstanceType
+} from "../../automated-upgrade-models/ui-component-to-upgrade";
+
+
+@Component({
+ selector: 'upgrade-list-item-inner-content',
+ templateUrl: './list-item-inner-content.component.html',
+ styleUrls: ['./list-item-inner-content.component.less']
+})
+export class UpgradeListItemInnerContent {
+
+ @Input() vspInstances:Array<VspInstanceUiObject>;
+
+ automatedUpgradeType = AutomatedUpgradeInstanceType;
+}
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/list-item-order-pipe/list-item-order-pipe.ts b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/list-item-order-pipe/list-item-order-pipe.ts
new file mode 100644
index 0000000..abebe0b
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/list-item-order-pipe/list-item-order-pipe.ts
@@ -0,0 +1,42 @@
+import {Pipe, PipeTransform} from "@angular/core";
+import {ServiceContainerToUpgradeUiObject} from "../../automated-upgrade-models/ui-component-to-upgrade";
+
+/*
+ This filter needs to return all not upgraded components sorted by name first, after that all upgraded components sorted by name
+ And in the end all the locked components sorted by name
+ */
+
+@Pipe({
+ name: 'upgradeListItemOrderBy'
+})
+export class UpgradeListItemOrderPipe implements PipeTransform {
+
+ private orderByName = (firstName:string, secondName:string):number => {
+ var textA = firstName.toLocaleLowerCase();
+ var textB = secondName.toLocaleLowerCase();
+ return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
+ }
+
+ transform(array:Array<ServiceContainerToUpgradeUiObject>):Array<ServiceContainerToUpgradeUiObject> {
+ array.sort((first:ServiceContainerToUpgradeUiObject, second:ServiceContainerToUpgradeUiObject) => {
+ if (first.isLock && second.isLock) {
+ return this.orderByName(first.name, second.name);
+ } else if (first.isLock) {
+ return 1;
+ } else if (second.isLock) {
+ return -1;
+ } else {
+ if (first.isAlreadyUpgrade && second.isAlreadyUpgrade) {
+ return this.orderByName(first.name, second.name);
+ } else if (first.isAlreadyUpgrade) {
+ return 1;
+ } else if (second.isAlreadyUpgrade) {
+ return -1;
+ } else {
+ return this.orderByName(first.name, second.name);
+ }
+ }
+ });
+ return array;
+ }
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-line-item/upgrade-line-item.component.html b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-line-item/upgrade-line-item.component.html
new file mode 100644
index 0000000..e848283
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-line-item/upgrade-line-item.component.html
@@ -0,0 +1,6 @@
+<div class="upgrade-line-item">
+ <svg-icon *ngIf="arrowName" name="{{arrowName}}" size="medium" mode="secondary"></svg-icon>
+ <div *ngIf="icon" class="line-item-icon small sprite-services-icons {{icon}}"></div>
+ <span *ngIf="prefix" class="line-item-prefix">{{prefix}}</span>
+ <span class="line-item-text">{{text}}</span>
+</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-line-item/upgrade-line-item.component.less b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-line-item/upgrade-line-item.component.less
new file mode 100644
index 0000000..d558e88
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-line-item/upgrade-line-item.component.less
@@ -0,0 +1,17 @@
+.upgrade-line-item{
+
+ display: flex;
+ align-items: center;
+
+ .line-item-icon {
+ margin-left: 10px;
+ }
+
+ .line-item-prefix {
+ margin-left: 7px;
+ }
+
+ .line-item-text {
+ margin-left: 7px;
+ }
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-line-item/upgrade-line-item.component.ts b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-line-item/upgrade-line-item.component.ts
new file mode 100644
index 0000000..b256d7e
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-line-item/upgrade-line-item.component.ts
@@ -0,0 +1,19 @@
+import {Component, Input} from "@angular/core";
+
+@Component({
+ selector: 'upgrade-line-item',
+ templateUrl: './upgrade-line-item.component.html',
+ styleUrls: ['./upgrade-line-item.component.less']
+})
+
+export class UpgradeLineItemComponent {
+
+ @Input() arrowName:string;
+ @Input() icon:string;
+ @Input() prefix:string;
+ @Input() text:string;
+
+ constructor() {
+
+ }
+}
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-list-item-status/upgrade-list-status-item.component.html b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-list-item-status/upgrade-list-status-item.component.html
new file mode 100644
index 0000000..c6d3add
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-list-item-status/upgrade-list-status-item.component.html
@@ -0,0 +1,13 @@
+<div class="components-to-upgrade-list-item">
+ <div class="component-to-upgrade-data">
+ <div class="component-to-upgrade-icon small sprite-services-icons {{upgradedComponent.icon}}"></div>
+ <span class="component-to-upgrade-name">{{upgradedComponent.name}} ({{upgradedComponent.version}})</span>
+ <svg-icon-label class="upgraded-component-status" *ngIf="upgradeComponentStatus.status === 'OK'"
+ name="success-circle-o" mode="success" size="medium" clickable="false"></svg-icon-label>
+ <svg-icon-label class="upgraded-component-status" *ngIf="upgradeComponentStatus.status !== 'OK'"
+ name="x-circle-o" mode="error"
+ size="medium" [label]="'Update Failed'" clickable="false" disabled="false" labelPlacement="left"></svg-icon-label>
+ </div>
+
+ <upgrade-list-item-inner-content [vspInstances]="upgradedComponent.vspInstances"></upgrade-list-item-inner-content>
+</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-list-item-status/upgrade-list-status-item.component.ts b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-list-item-status/upgrade-list-status-item.component.ts
new file mode 100644
index 0000000..726bc67
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-list-item-status/upgrade-list-status-item.component.ts
@@ -0,0 +1,19 @@
+import {Component, Input} from "@angular/core";
+import {AutomatedUpgradeStatusResponse} from "../../../../services/responses/automated-upgrade-response";
+import {ServiceContainerToUpgradeUiObject} from "../../automated-upgrade-models/ui-component-to-upgrade";
+
+@Component({
+ selector: 'upgrade-list-status-item',
+ templateUrl: './upgrade-list-status-item.component.html',
+ styleUrls: ['./../upgrade-list-item.component.less']
+})
+export class UpgradeListItemStatusComponent {
+
+ @Input() upgradedComponent: ServiceContainerToUpgradeUiObject;
+ @Input() upgradeComponentStatus: AutomatedUpgradeStatusResponse;
+
+ constructor () {
+
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-list-item.component.less b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-list-item.component.less
new file mode 100644
index 0000000..4507929
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-list-item.component.less
@@ -0,0 +1,44 @@
+@import "./../../../../../assets/styles/override";
+
+.components-to-upgrade-list-item {
+ border: 1px solid @sdcui_color_light-gray;
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.11);
+ margin-bottom: 10px;
+ line-height: 40px;
+
+ .component-to-upgrade-data {
+ display: flex;
+ background-color: @sdcui_color_light-silver;
+ height: 40px;
+ padding: 0 10px;
+ align-items: center;
+
+ .component-to-upgrade-icon {
+ margin-left: 26px;
+ }
+
+ .component-to-upgrade-name {
+ margin-left: 8px;
+ }
+
+ .component-to-upgrade-checkbox {
+ height: 24px; // Workaround can not vertical center
+ }
+
+ .upgraded-component-status {
+ margin-left: auto;
+ }
+ }
+
+ .vsp-data {
+ align-items: center;
+ display: flex;
+ border-bottom: 1px solid @sdcui_color_silver;
+ padding: 0 10px 0 64px;
+ .vsp-data-label {
+ color: @sdcui_color_text-black;
+ margin-left: 7px;
+ font-weight: 600;
+ }
+ }
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-list-item/upgrade-list-item.component.html b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-list-item/upgrade-list-item.component.html
new file mode 100644
index 0000000..6e6af0c
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-list-item/upgrade-list-item.component.html
@@ -0,0 +1,19 @@
+<div class="components-to-upgrade-list-item ">
+ <div class="component-to-upgrade-data">
+ <sdc-checkbox class="component-to-upgrade-checkbox"
+ *ngIf="!componentToUpgrade.isAlreadyUpgrade && !componentToUpgrade.isLock"
+ [checked]="true"
+ [disabled]="disabled"
+ (checkedChange)="onComponentChecked(componentToUpgrade.uniqueId)">
+ </sdc-checkbox>
+ <svg-icon *ngIf="componentToUpgrade.isAlreadyUpgrade" name="success-circle-o" mode="success"
+ size="medium"></svg-icon>
+ <svg-icon *ngIf="!componentToUpgrade.isAlreadyUpgrade && componentToUpgrade.isLock" name="locked" mode="info"
+ size="small"></svg-icon>
+ <div class="component-to-upgrade-icon small sprite-services-icons {{componentToUpgrade.icon}}"></div>
+ <span class="component-to-upgrade-name">{{componentToUpgrade.name}} ({{componentToUpgrade.version}})</span>
+ </div>
+
+ <upgrade-list-item-inner-content [vspInstances]="componentToUpgrade.vspInstances"></upgrade-list-item-inner-content>
+
+</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-list-item/upgrade-list-item.component.ts b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-list-item/upgrade-list-item.component.ts
new file mode 100644
index 0000000..806b831
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade-ui-components/upgrade-list-item/upgrade-list-item.component.ts
@@ -0,0 +1,23 @@
+import {Component, Input, Output, EventEmitter} from "@angular/core";
+import {ServiceContainerToUpgradeUiObject, AutomatedUpgradeInstanceType} from "../../automated-upgrade-models/ui-component-to-upgrade";
+
+@Component({
+ selector: 'upgrade-list-item',
+ templateUrl: './upgrade-list-item.component.html',
+ styleUrls: ['./../upgrade-list-item.component.less']
+})
+export class UpgradeListItemComponent {
+
+ @Input() componentToUpgrade:ServiceContainerToUpgradeUiObject;
+ @Input() disabled: boolean;
+ @Output() onCheckedChange:EventEmitter<any> = new EventEmitter<any>();
+
+ constructor() {
+ }
+
+ onComponentChecked = ():void => {
+ this.onCheckedChange.emit();
+ }
+
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade.component.html b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade.component.html
new file mode 100644
index 0000000..67e7f08
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade.component.html
@@ -0,0 +1,25 @@
+<div class="automated-upgrade-component">
+
+ <div *ngIf="certificationStatusText" class="certification-status">
+ <svg-icon-label
+ name="success-circle-o"
+ mode="success"
+ size="medium"
+ clickable="false"
+ disabled="false"
+ labelPlacement="right">
+ </svg-icon-label>
+ <span class="certification-status-text">{{certificationStatusText}}</span>
+ </div>
+
+ <div>
+ <span innerHTML="{{informationText}}"> </span>
+ <div class="components-to-upgrade-list">
+ <ul>
+ <li *ngFor="let component of componentsToUpgrade | upgradeListItemOrderBy">
+ <upgrade-list-item (onCheckedChange)= "onComponentSelected(component.uniqueId)" [disabled]="disabled" [componentToUpgrade]="component"></upgrade-list-item>
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade.component.less b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade.component.less
new file mode 100644
index 0000000..2ab2130
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade.component.less
@@ -0,0 +1,23 @@
+.automated-upgrade-component {
+
+ min-height: 280px;
+ .certification-status {
+ border: 1px solid #4ca90c;
+ border-left: 5px solid #4ca90c;
+ margin-bottom: 20px;
+ padding: 5px 5px 5px 10px;
+ font-weight: bold;
+ display: flex;
+ line-height: 21px;
+
+ .certification-status-text {
+ padding-left: 5px;
+ }
+ }
+ .components-to-upgrade-list {
+
+ overflow: auto;
+ max-height: 300px;
+ margin-top: 15px;
+ }
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade.component.ts b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade.component.ts
new file mode 100644
index 0000000..9ae7349
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade.component.ts
@@ -0,0 +1,65 @@
+/**
+ * Created by ob0695 on 4/18/2018.
+ */
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {Component, Input, Inject, forwardRef} from "@angular/core";
+import {TranslateService} from "../../shared/translator/translate.service";
+import {ServiceContainerToUpgradeUiObject} from "./automated-upgrade-models/ui-component-to-upgrade";
+import {AutomatedUpgradeService} from "./automated-upgrade.service";
+
+@Component({
+ selector: 'upgrade-vsp',
+ templateUrl: './automated-upgrade.component.html',
+ styleUrls: ['./automated-upgrade.component.less'],
+ providers: [TranslateService]
+})
+export class AutomatedUpgradeComponent {
+
+ @Input() componentsToUpgrade: Array<ServiceContainerToUpgradeUiObject>;
+ @Input() certificationStatusText: string;
+ @Input() informationText: string;
+ @Input() disabled: string;
+ private selectedComponentsToUpgrade: Array<string> = [];
+
+ constructor (@Inject(forwardRef(() => AutomatedUpgradeService)) private automatedUpgradeService: AutomatedUpgradeService) {
+ }
+
+ ngOnInit(): void { // We need to check all elements that needed upgrade as default
+ this.selectedComponentsToUpgrade = _.filter(this.componentsToUpgrade, (componentToUpgrade:ServiceContainerToUpgradeUiObject) => {
+ return !componentToUpgrade.isAlreadyUpgrade && !componentToUpgrade.isLock;
+ }).map(element => element.uniqueId)
+ }
+
+ onComponentSelected = (uniqueId:string):void => {
+
+ if(this.selectedComponentsToUpgrade.indexOf(uniqueId) > -1) {
+ this.selectedComponentsToUpgrade = _.without(this.selectedComponentsToUpgrade, uniqueId);
+ } else {
+ this.selectedComponentsToUpgrade.push(uniqueId);
+ }
+ if(this.selectedComponentsToUpgrade.length === 0) {
+ this.automatedUpgradeService.changeUpgradeButtonState(true);
+ } else {
+ this.automatedUpgradeService.changeUpgradeButtonState(false);
+ }
+ }
+}
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade.module.ts b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade.module.ts
new file mode 100644
index 0000000..19f6412
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade.module.ts
@@ -0,0 +1,34 @@
+/**
+ * Created by ob0695 on 4/18/2018.
+ */
+import { NgModule } from "@angular/core";
+import {SdcUiComponentsModule} from "sdc-ui/lib/angular/index";
+import {CommonModule} from "@angular/common";
+import {AutomatedUpgradeStatusComponent} from "./automated-upgrade-status/automated-upgrade-status.component";
+import {AutomatedUpgradeComponent} from "./automated-upgrade.component";
+import {UpgradeListItemComponent} from "./automated-upgrade-ui-components/upgrade-list-item/upgrade-list-item.component";
+import {UpgradeListItemStatusComponent} from "./automated-upgrade-ui-components/upgrade-list-item-status/upgrade-list-status-item.component";
+import {TranslateService} from "../../shared/translator/translate.service";
+import {UpgradeListItemInnerContent} from "./automated-upgrade-ui-components/list-item-inner-content/list-item-inner-content.component";
+import {UpgradeLineItemComponent} from "./automated-upgrade-ui-components/upgrade-line-item/upgrade-line-item.component";
+import {UpgradeListItemOrderPipe} from "./automated-upgrade-ui-components/list-item-order-pipe/list-item-order-pipe";
+
+@NgModule({
+ declarations: [
+ AutomatedUpgradeStatusComponent,
+ UpgradeListItemComponent,
+ UpgradeListItemStatusComponent,
+ AutomatedUpgradeComponent,
+ UpgradeListItemInnerContent,
+ UpgradeLineItemComponent,
+ UpgradeListItemOrderPipe
+ ],
+ imports: [CommonModule, SdcUiComponentsModule],
+ exports: [],
+ entryComponents: [
+ AutomatedUpgradeComponent, AutomatedUpgradeStatusComponent
+ ],
+ providers: [TranslateService]
+})
+export class AutomatedUpgradeModule {
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade.service.ts b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade.service.ts
new file mode 100644
index 0000000..0acfece
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/automated-upgrade/automated-upgrade.service.ts
@@ -0,0 +1,279 @@
+import {SdcUiComponents} from "sdc-ui/lib/angular";
+import {Injectable, Inject} from "@angular/core";
+import {IModalConfig} from "sdc-ui/lib/angular/modals/models/modal-config";
+import {AutomatedUpgradeComponent} from "./automated-upgrade.component";
+import {Component} from "../../../models/components/component";
+import {ComponentServiceNg2} from "../../services/component-services/component.service";
+import {GeneralStatus, ComponentType} from "../../../utils/constants";
+import {IDependenciesServerResponse} from "../../services/responses/dependencies-server-response";
+import {AutomatedUpgradeStatusComponent} from "./automated-upgrade-status/automated-upgrade-status.component";
+import {AutomatedUpgradeStatusResponse} from "../../services/responses/automated-upgrade-response";
+import Dictionary = _.Dictionary;
+import {TranslateService, ITranslateArgs} from "../../shared/translator/translate.service";
+import {
+ ServiceContainerToUpgradeUiObject,
+ AllottedResourceInstanceUiObject, VspInstanceUiObject
+} from "./automated-upgrade-models/ui-component-to-upgrade";
+
+export interface IAutomatedUpgradeRequestObj {
+ serviceId:string;
+ resourceId?:string;
+}
+
+export enum Placement {
+ left = "left"
+}
+
+@Injectable()
+export class AutomatedUpgradeService {
+
+ private vspComponent:Component;
+ private uiComponentsToUpgrade:Array<ServiceContainerToUpgradeUiObject>;
+ private componentType:string;
+
+ constructor(private modalService:SdcUiComponents.ModalService,
+ private componentService:ComponentServiceNg2,
+ private translateService:TranslateService) {
+ }
+
+
+ public convertToServerRequest = (selectedServices:Array<string>):Array<IAutomatedUpgradeRequestObj> => {
+
+ let automatedRequest:Array<IAutomatedUpgradeRequestObj> = [];
+ _.forEach(selectedServices, (serviceId:string) => {
+ let serviceToUpgrade:ServiceContainerToUpgradeUiObject = _.find(this.uiComponentsToUpgrade, (service:ServiceContainerToUpgradeUiObject) => {
+ return serviceId === service.uniqueId;
+ });
+
+ if (serviceToUpgrade.vspInstances[0] instanceof AllottedResourceInstanceUiObject) { // If this is allotted resource instances, we need to take the origin vf id (all the instances have the save origin vspId
+ automatedRequest.push({
+ serviceId: serviceId,
+ resourceId: (<AllottedResourceInstanceUiObject> serviceToUpgrade.vspInstances[0]).originVfId
+ });
+ } else {
+ automatedRequest.push({serviceId: serviceId});
+ }
+ });
+ return automatedRequest;
+ }
+
+ private getStatusText = (statusMap:Dictionary<AutomatedUpgradeStatusResponse>):string => {
+ let failedUpgraded = _.filter(_.flatMap(statusMap), (upgradeStatus:AutomatedUpgradeStatusResponse) => {
+ return upgradeStatus.status !== GeneralStatus.OK
+ });
+
+ if (failedUpgraded.length > 0) {
+ return this.getTextByComponentType("_UPGRADE_STATUS_FAIL");
+ }
+ return this.getTextByComponentType("_UPGRADE_STATUS_SUCCESS");
+ }
+
+ private disabledAllModalButtons = ():void => {
+ this.modalService.getCurrentInstance().innerModalContent.instance.disabled = true;
+ this.modalService.getCurrentInstance().buttons[0].show_spinner = true;
+ this.modalService.getCurrentInstance().buttons[1].disabled = true;
+ }
+
+ public changeUpgradeButtonState = (isDisabled:boolean):void => {
+ if (this.modalService.getCurrentInstance().buttons[0].disabled !== isDisabled) {
+ this.modalService.getCurrentInstance().buttons[0].disabled = isDisabled;
+ }
+ }
+
+ //TODO We will need to replace this function after sdc-ui modal new design, this is just a workaround
+ public automatedUpgrade = ():void => {
+
+ let selectedServices = this.modalService.getCurrentInstance().innerModalContent.instance.selectedComponentsToUpgrade;
+ this.disabledAllModalButtons();
+ this.componentService.automatedUpgrade(this.vspComponent.componentType, this.vspComponent.uniqueId, this.convertToServerRequest(selectedServices)).subscribe((automatedUpgradeStatus:any) => {
+
+ if (automatedUpgradeStatus.status === GeneralStatus.OK) {
+
+ let statusMap:Dictionary<AutomatedUpgradeStatusResponse> = _.keyBy(automatedUpgradeStatus.componentToUpgradeStatus, 'name');
+ // In the status modal we only showing the upgraded component that the user selected, not the entire list
+ let upgradedComponent:Array<ServiceContainerToUpgradeUiObject> = _.filter(this.uiComponentsToUpgrade, (component:ServiceContainerToUpgradeUiObject) => {
+ return selectedServices.indexOf(component.uniqueId) > -1;
+ });
+
+ _.forEach(upgradedComponent, (upgradedComponent:ServiceContainerToUpgradeUiObject) => { // If upgrade success we need to upgrade the version all success
+ if (statusMap[upgradedComponent.name].status === GeneralStatus.OK) {
+ upgradedComponent.version = statusMap[upgradedComponent.name].version;
+ _.forEach(upgradedComponent.vspInstances, (instance:VspInstanceUiObject) => {
+ instance.vspVersion = this.vspComponent.version;
+ });
+ }
+ });
+
+ let statusModalTitle = this.getTextByComponentType("_UPGRADE_STATUS_TITLE");
+ this.modalService.getCurrentInstance().setTitle(statusModalTitle);
+ this.modalService.getCurrentInstance().getButtons().splice(0, 1); // Remove the upgrade button
+ this.modalService.getCurrentInstance().buttons[0].disabled = false; // enable close again
+ this.modalService.getCurrentInstance().innerModalContent.destroy();
+ this.modalService.createInnnerComponent(AutomatedUpgradeStatusComponent, {
+ upgradedComponentsList: upgradedComponent,
+ upgradeStatusMap: statusMap,
+ statusText: this.getStatusText(statusMap)
+ });
+ }
+ });
+ }
+
+ public isAlreadyAdded = (uniqueId:string):ServiceContainerToUpgradeUiObject => {
+ let componentToUpgrade = _.find(this.uiComponentsToUpgrade, (componentToUpgrade:ServiceContainerToUpgradeUiObject) => {
+ return componentToUpgrade.uniqueId === uniqueId;
+ });
+ return componentToUpgrade;
+ }
+
+ public initVfUpgradeData = (serviceToUpgrade:IDependenciesServerResponse, vsp:IDependenciesServerResponse) => {
+
+ let existed = this.isAlreadyAdded(serviceToUpgrade.uniqueId);
+ if (existed) { // We will take the VF with the lower version existed - only one exist all the time in vf upgrade
+ if (vsp.version < existed.vspInstances[0].vspVersion) {
+ existed.vspInstances = [];
+ existed.addVfInstance(vsp, this.vspComponent.version);
+ }
+ } else {
+ let dependencyUiObj:ServiceContainerToUpgradeUiObject = new ServiceContainerToUpgradeUiObject(serviceToUpgrade);
+ dependencyUiObj.addVfInstance(vsp, this.vspComponent.version);
+ this.uiComponentsToUpgrade.push(dependencyUiObj);
+ }
+ }
+
+ // Service data will create instances of proxy or allotted resources
+ public initServiceUpgradeData = (serviceToUpgrade:IDependenciesServerResponse, vsp:IDependenciesServerResponse, instanceNames:Array<string>, allottedOriginVf?:IDependenciesServerResponse) => {
+
+ let existedService = this.isAlreadyAdded(serviceToUpgrade.uniqueId);
+ if (existedService) {
+ existedService.addMultipleInstances(vsp, this.vspComponent.version, instanceNames, allottedOriginVf);
+ }
+ else {
+ let dependencyUiObj:ServiceContainerToUpgradeUiObject = new ServiceContainerToUpgradeUiObject(serviceToUpgrade);
+ dependencyUiObj.addMultipleInstances(vsp, this.vspComponent.version, instanceNames, allottedOriginVf);
+ this.uiComponentsToUpgrade.push(dependencyUiObj);
+ }
+ }
+
+ /*
+ The server return response of 3 level nested object
+ First level - Vsp data by version
+ Each vsp have a decencies (the services contains the vsp - By default this is vf upgrade
+ If instancesNames exist - this can be proxy or allotted
+ If we have second layer of dependencies than this is allotted
+ Since we display the data the opposite way the BE return, this function will order the data in order to display it
+ */
+ public convertToComponentsToUpgradeUiObjArray = (dependenciesServerResponse:Array<IDependenciesServerResponse>):void => {
+
+ this.uiComponentsToUpgrade = [];
+
+ _.forEach(dependenciesServerResponse, (vsp:IDependenciesServerResponse) => { // 3 nested levels - 1 level for vf, 2 level proxy, 3 levels allotted
+ if (vsp.dependencies) {
+ _.forEach(vsp.dependencies, (dependency:IDependenciesServerResponse) => {
+ if (dependency.instanceNames) { // Init service upgrade data
+ if (dependency.dependencies) {
+ _.forEach(dependency.dependencies, (serviceContainer:IDependenciesServerResponse) => { // Initiate allotted_resource instances
+ this.initServiceUpgradeData(serviceContainer, vsp, dependency.instanceNames, dependency);
+ });
+ } else { //Init service_proxy instances
+ this.initServiceUpgradeData(dependency, vsp, dependency.instanceNames);
+ }
+ } else { // Init vf upgrade data
+ this.initVfUpgradeData(dependency, vsp);
+ }
+ })
+ }
+ });
+ }
+
+ public isAllComponentsUpgraded = ():boolean => {
+ let isAllComponentUpgrade = _.filter(this.uiComponentsToUpgrade, (component:ServiceContainerToUpgradeUiObject) => {
+ return !component.isAlreadyUpgrade;
+ });
+ return isAllComponentUpgrade.length === 0;
+ }
+
+ public isAllComponentsLocked = ():boolean => {
+ let unLockedComponents = _.filter(this.uiComponentsToUpgrade, (component:ServiceContainerToUpgradeUiObject) => {
+ return !component.isLock;
+ });
+ return unLockedComponents.length === 0;
+ }
+
+ public isUpgradeNeeded = ():boolean => {
+ let neededUpgradeList = _.filter(this.uiComponentsToUpgrade, (component:ServiceContainerToUpgradeUiObject) => {
+ return !component.isLock && !component.isAlreadyUpgrade;
+ });
+ return neededUpgradeList.length > 0;
+ }
+
+ private getTextByComponentType (textLabel: string, params?:ITranslateArgs) {
+ return this.translateService.translate(this.componentType + textLabel, params);
+ }
+ public getInformationTextToDisplay = ():string => {
+
+ let isAllComponentsUpgraded = this.isAllComponentsUpgraded();
+ let isAllComponentsLocked = this.isAllComponentsLocked();
+ let params = {vspName: this.vspComponent.name, vspVersion: this.vspComponent.version};
+
+ if (this.uiComponentsToUpgrade.length === 0) {
+ return this.getTextByComponentType("_NOTHING_TO_UPGRADE", params);
+ }
+
+ switch (true) {
+
+ case this.isUpgradeNeeded():
+ {
+ return this.getTextByComponentType("_AUTOMATED_UPGRADE_WITH_COMPONENTS_TO_UPGRADE", params);
+ }
+ case !this.isUpgradeNeeded() && isAllComponentsLocked:
+ {
+ return this.getTextByComponentType("_AUTOMATED_UPGRADE_ALL_COMPONENTS_LOCKED", params);
+ }
+ case !this.isUpgradeNeeded() && !isAllComponentsLocked && isAllComponentsUpgraded:
+ {
+ return this.getTextByComponentType("_AUTOMATED_UPGRADE_ALL_COMPONENTS_UPGRADED", params);
+ }
+ case !this.isUpgradeNeeded() && !isAllComponentsLocked && !isAllComponentsUpgraded:
+ {
+ return this.getTextByComponentType("_AUTOMATED_UPGRADE_ALL_COMPONENTS_LOCKED", params);
+ }
+ }
+ }
+
+ public openAutomatedUpgradeModal = (componentsToUpgrade:Array<IDependenciesServerResponse>, component:Component, isAfterCertification?:boolean):void => {
+
+ this.vspComponent = component;
+ this.componentType = this.vspComponent.isResource() ? ComponentType.RESOURCE : ComponentType.SERVICE;
+
+ this.convertToComponentsToUpgradeUiObjArray(componentsToUpgrade);
+ let informationalText = this.getInformationTextToDisplay();
+ let modalTitle = this.getTextByComponentType("_UPGRADE_TITLE");
+ let certificationText = isAfterCertification ? this.getTextByComponentType("_CERTIFICATION_STATUS_TEXT", {resourceName: this.vspComponent.name}) : undefined;
+
+ let upgradeVspModalConfig:IModalConfig = {
+ title: modalTitle,
+ size: "md",
+ type: "custom",
+ testId: "upgradeVspModal",
+ buttons: [
+ {
+ text: this.vspComponent.isResource() ? "UPGRADE" : "UPDATE",
+ spinner_position: Placement.left,
+ size: 'sm',
+ callback: this.automatedUpgrade,
+ closeModal: false,
+ disabled: !this.isUpgradeNeeded(),
+
+ },
+ {text: 'CLOSE', size: 'sm', closeModal: true, type: 'secondary'}
+ ]
+ };
+
+ this.modalService.openCustomModal(upgradeVspModalConfig, AutomatedUpgradeComponent, {
+ componentsToUpgrade: this.uiComponentsToUpgrade,
+ informationText: informationalText,
+ certificationStatusText: certificationText
+ });
+ }
+}
+
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-header/panel-header.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-header/panel-header.component.html
new file mode 100644
index 0000000..731d6a3
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-header/panel-header.component.html
@@ -0,0 +1,14 @@
+<div class="component-details-panel-header" data-tests-id="w-sdc-designer-sidebar-head">
+
+ <div class="icon">
+ <div class="large {{iconClassName}}">
+ <div [ngClass]="{'non-certified': nonCertified}" tooltip="Not certified"></div>
+ </div>
+ </div>
+
+ <div class="title" data-tests-id="selectedCompTitle" tooltip="​{{name}}">{{name}}</div>
+
+ <svg-icon-label *ngIf="!isViewOnly" name="edit-file-o" clickable="true" size="small" class="rename-instance" data-tests-id="renameInstance" (click)="renameInstance()"></svg-icon-label>
+ <svg-icon-label *ngIf="!isViewOnly" name="trash-o" clickable="true" size="small" class="delete-instance" data-tests-id="deleteInstance" (click)="deleteInstance()"></svg-icon-label>
+
+</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-header/panel-header.component.less b/catalog-ui/src/app/ng2/pages/composition/panel/panel-header/panel-header.component.less
new file mode 100644
index 0000000..9bbc765
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-header/panel-header.component.less
@@ -0,0 +1,34 @@
+/deep/
+.component-details-panel-header {
+ display: flex;
+ flex-direction: row;
+ height: 120px;
+ align-items: center;
+
+ .icon {
+ margin: 0 20px;
+ }
+
+ .title {
+ font-size: 16px;
+ text-overflow: ellipsis;
+ max-width: 180px;
+ white-space: nowrap;
+ overflow: hidden;
+ }
+
+ .rename-instance {
+ position: absolute;
+ top: 14px;
+ right: 20px;
+ cursor: pointer;
+ }
+
+ .delete-instance {
+ position: absolute;
+ top: 14px;
+ right: 40px;
+ cursor: pointer;
+ }
+
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-header/panel-header.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-header/panel-header.component.ts
new file mode 100644
index 0000000..ab659a3
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-header/panel-header.component.ts
@@ -0,0 +1,135 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import { Component, Input, AfterViewInit, SimpleChanges, OnInit, OnChanges } from "@angular/core";
+import { SdcUiComponents } from "sdc-ui/lib/angular";
+import { IModalConfig } from 'sdc-ui/lib/angular/modals/models/modal-config';
+import { ZoneInstanceType } from 'app/models/graph/zones/zone-instance';
+import { ValueEditComponent } from './../../../../components/ui/forms/value-edit/value-edit.component';
+import { Component as TopologyTemplate, ComponentInstance, IAppMenu } from "app/models";
+import { PoliciesService } from '../../../../services/policies.service';
+import { GroupsService } from '../../../../services/groups.service';
+import {IZoneService} from "../../../../../models/graph/zones/zone";
+import { EventListenerService, LoaderService } from "../../../../../services";
+import { GRAPH_EVENTS, EVENTS } from "../../../../../utils";
+import { UIZoneInstanceObject } from "../../../../../models/ui-models/ui-zone-instance-object";
+import { ModalButtonComponent } from "sdc-ui/lib/angular/components";
+
+@Component({
+ selector: 'ng2-composition-panel-header',
+ templateUrl: './panel-header.component.html',
+ styleUrls: ['./panel-header.component.less']
+})
+export class CompositionPanelHeaderComponent implements OnInit, OnChanges {
+
+ @Input() topologyTemplate: TopologyTemplate;
+ @Input() selectedZoneInstanceType: ZoneInstanceType;
+ @Input() selectedZoneInstanceId: string;
+ @Input() name: string;
+ @Input() nonCertified: boolean;
+ @Input() isViewOnly: boolean;
+ @Input() isLoading: boolean;
+
+ constructor(private groupsService:GroupsService, private policiesService: PoliciesService,
+ private modalService:SdcUiComponents.ModalService, private eventListenerService:EventListenerService) { }
+
+ private service:IZoneService;
+ private iconClassName: string;
+
+ ngOnInit(): void {
+ this.init();
+ }
+
+ ngOnChanges (changes:SimpleChanges):void {
+ if(changes.selectedZoneInstanceId){
+ this.init();
+ }
+ }
+
+ ngOnDestroy() {
+
+
+ }
+ private init = (): void => {
+ if (this.selectedZoneInstanceType === ZoneInstanceType.POLICY) {
+ this.iconClassName = "sprite-policy-icons policy";
+ this.service = this.policiesService;
+ } else if (this.selectedZoneInstanceType === ZoneInstanceType.GROUP) {
+ this.iconClassName = "sprite-group-icons group";
+ this.service = this.groupsService;
+ } else {
+ this.iconClassName = "sprite-resource-icons defaulticon";
+ }
+ }
+
+ private renameInstance = (): void => {
+ const modalConfig = {
+ 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}
+ ] as ModalButtonComponent[]
+ } as IModalConfig;
+ this.modalService.openCustomModal(modalConfig, ValueEditComponent, {name: this.name, validityChangedCallback: this.enableOrDisableSaveButton});
+ };
+
+ private enableOrDisableSaveButton = (shouldEnable: boolean): void => {
+ let saveButton: ModalButtonComponent = this.modalService.getCurrentInstance().getButtonById('saveButton');
+ saveButton.disabled = !shouldEnable;
+ }
+
+ private saveInstanceName = ():void => {
+ let currentModal = this.modalService.getCurrentInstance();
+ let nameFromModal:string = currentModal.innerModalContent.instance.name;
+
+ if(nameFromModal != this.name){
+ currentModal.buttons[0].disabled = true;
+ this.service.updateName(this.topologyTemplate.componentType, this.topologyTemplate.uniqueId, this.selectedZoneInstanceId, nameFromModal).subscribe((success)=>{
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_ZONE_INSTANCE_NAME_CHANGED, nameFromModal);
+ this.modalService.closeModal();
+ }, (error)=> {
+ currentModal.buttons[0].disabled = false;
+ });
+ } else {
+ this.modalService.closeModal();
+ }
+ };
+
+ private deleteInstance = (): void => {
+ let title:string = "Delete Confirmation";
+ let message:string = "Are you sure you would like to delete "+ this.name + "?";
+ this.modalService.openAlertModal(title, message, "OK", this.deleteInstanceConfirmed, "deleteInstanceModal");
+ };
+
+ private deleteInstanceConfirmed = () => {
+ this.eventListenerService.notifyObservers(EVENTS.SHOW_LOADER_EVENT + 'composition-graph');
+ this.service.deleteZoneInstance(this.topologyTemplate.componentType, this.topologyTemplate.uniqueId, this.selectedZoneInstanceId).finally(()=> {
+ this.eventListenerService.notifyObservers(EVENTS.HIDE_LOADER_EVENT + 'composition-graph');
+ }).subscribe(()=> {
+ let deletedItem:UIZoneInstanceObject = new UIZoneInstanceObject(this.selectedZoneInstanceId, this.selectedZoneInstanceType, this.name);
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_DELETE_ZONE_INSTANCE, deletedItem);
+ });
+ };
+
+}
+
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-header/panel-header.module.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-header/panel-header.module.ts
new file mode 100644
index 0000000..bde0a14
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-header/panel-header.module.ts
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+import { NgModule } from "@angular/core";
+import { HttpModule } from "@angular/http";
+import { FormsModule } from "@angular/forms";
+import { BrowserModule } from "@angular/platform-browser";
+import { CompositionPanelHeaderComponent } from "./panel-header.component";
+import { UiElementsModule } from './../../../../components/ui/ui-elements.module';
+import { ValueEditComponent } from './../../../../components/ui/forms/value-edit/value-edit.component';
+import { SdcUiComponentsModule } from "sdc-ui/lib/angular";
+import { ModalFormsModule } from "app/ng2/components/ui/forms/modal-forms.module";
+
+@NgModule({
+ declarations: [
+ CompositionPanelHeaderComponent
+ ],
+ imports: [
+ BrowserModule,
+ FormsModule,
+ HttpModule,
+ UiElementsModule,
+ SdcUiComponentsModule,
+ ModalFormsModule
+ ],
+ entryComponents: [
+ CompositionPanelHeaderComponent, ValueEditComponent
+ ],
+ exports: [
+ CompositionPanelHeaderComponent
+ ],
+})
+export class CompositionPanelHeaderModule {
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/base/base-tab.component.less b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/base/base-tab.component.less
new file mode 100644
index 0000000..aa8e751
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/base/base-tab.component.less
@@ -0,0 +1,66 @@
+@import './../../../../../../../assets/styles/mixins';
+@import "./../../../../../../../assets/styles/variables-old";
+@import './../../../../../../../assets/styles/mixins_old';
+
+/deep/
+.expand-collapse-content {
+ padding: 20px;
+}
+
+.component-details-panel-tab-no-data {
+ margin: 0 auto;
+ padding-top: 30px;
+ text-align: center;
+
+ .component-details-panel-tab-no-data-title {
+ font-family: @font-opensans-bold;
+ }
+
+}
+
+.component-details-panel-large-item {
+ font-family: OpenSans-Semibold, sans-serif;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ height: 32px;
+ line-height: 32px;
+ vertical-align: middle;
+
+ &:hover {
+ background-color: #f8f8f8;
+ margin: 0 -20px; /* to fill expand-collapse-content padding */
+ padding: 0 20px;
+ .component-details-panel-item-delete {
+ visibility: visible;
+ }
+ }
+}
+
+.component-details-panel-item {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ height: 22px;
+ line-height: 22px;
+ vertical-align: middle;
+
+ &.description {
+ margin-top: 28px;
+ white-space: normal;
+ word-wrap: break-word;
+ .value {
+ max-width: none;
+ font-weight: normal;
+ font-family: @font-opensans-regular;
+ }
+ }
+
+ .name { font-family: OpenSans-Semibold, sans-serif; }
+ .value { }
+}
+
+.component-details-panel-item-delete {
+ cursor: pointer;
+ visibility: hidden;
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-information-tab.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-information-tab.component.html
new file mode 100644
index 0000000..3c875fd
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-information-tab.component.html
@@ -0,0 +1,30 @@
+<ng2-expand-collapse state="0">
+
+ <header tooltip="General Information">General Info</header>
+
+ <content>
+ <!-- CATEGORY -->
+ <div class="component-details-panel-item">
+ <span class="name" [innerHTML]="'GENERAL_LABEL_CATEGORY' | translate"></span>
+ <span class="value" data-tests-id="rightTab_category" tooltip="Group">Group</span>
+ </div>
+
+ <!-- SUB CATEGORY -->
+ <div class="component-details-panel-item">
+ <span class="name" [innerHTML]="'GENERAL_LABEL_SUB_CATEGORY' | translate"></span>
+ <span class="value" data-tests-id="rightTab_subCategory" tooltip="Group">Group</span>
+ </div>
+
+ <!-- VERSION -->
+ <div class="component-details-panel-item">
+ <span class="name" [innerHTML]="'GENERAL_LABEL_VERSION' | translate"></span>
+ <span class="value" data-tests-id="rightTab_version" tooltip="{{group.version}}">{{group.version}}</span>
+ </div>
+
+ <!-- DESCRIPTION -->
+ <div class="component-details-panel-item description">
+ <span class="name" [innerHTML]="'GENERAL_LABEL_DESCRIPTION' | translate"></span>
+ <span class="value" ellipsis="group.description" max-chars="55" data-tests-id="rightTab_description">{{group.description}}</span>
+ </div>
+ </content>
+</ng2-expand-collapse>
diff --git a/catalog-ui/src/app/filters/catalog-status-filter.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-information-tab.component.ts
similarity index 67%
rename from catalog-ui/src/app/filters/catalog-status-filter.ts
rename to catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-information-tab.component.ts
index 3c0389d..2660222 100644
--- a/catalog-ui/src/app/filters/catalog-status-filter.ts
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-information-tab.component.ts
@@ -7,9 +7,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,21 +18,22 @@
* ============LICENSE_END=========================================================
*/
-/**
- * Created by obarda on 19/08/2015.
- */
-export class CatalogStatusFilter {
+import * as _ from "lodash";
+import { Component, Inject, Input, Output, EventEmitter } from "@angular/core";
+import { GroupInstance } from 'app/models/graph/zones/group-instance';
+
+@Component({
+ selector: 'group-information-tab',
+ templateUrl: './group-information-tab.component.html',
+ styleUrls: ['./../base/base-tab.component.less']
+})
+export class GroupInformationTabComponent {
+
+ @Input() group: GroupInstance;
+ @Input() isViewOnly: boolean;
constructor() {
- let filter = <CatalogStatusFilter>( (statuses:any) => {
- let filtered = [];
- angular.forEach(statuses, function (status) {
- filtered.push(status);
- });
- return filtered;
- });
- return filter;
}
-}
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-members-tab.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-members-tab.component.html
new file mode 100644
index 0000000..f298a39
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-members-tab.component.html
@@ -0,0 +1,31 @@
+<div class="w-sdc-designer-sidebar-section-title" tooltip="Members">Members
+ <svg-icon-label *ngIf="!isViewOnly"
+ class="add-members-btn"
+ name="plus-circle-o"
+ mode="primary"
+ size="medium"
+ label="ADD"
+ labelPlacement="right"
+ (click)="openAddMembersModal()">
+ </svg-icon-label>
+</div>
+<div class="expand-collapse-content">
+ <ul>
+ <li *ngFor="let member of members; let i = index" class="component-details-panel-large-item"
+ tooltip="{{member.name}}">
+ <span>{{member.name}}</span>
+ <svg-icon-label *ngIf="!isViewOnly"
+ name="trash-o"
+ clickable="true"
+ size="small"
+ class="component-details-panel-item-delete"
+ data-tests-id="delete_member"
+ (click)="deleteMember(member)"></svg-icon-label>
+ </li>
+ </ul>
+
+ <div *ngIf="members.length===0" class="component-details-panel-tab-no-data">
+ <div class="component-details-panel-tab-no-data-title">No data to display yet</div>
+ <div class="component-details-panel-tab-no-data-content">Add members to group to see members</div>
+ </div>
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-members-tab.component.less b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-members-tab.component.less
new file mode 100644
index 0000000..1006e86
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-members-tab.component.less
@@ -0,0 +1,13 @@
+/deep/
+.component-details-panel-tab-group-members {
+ .component-details-panel-large-item {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ }
+
+ .w-sdc-designer-sidebar-section-title {
+ display: flex;
+ justify-content: space-between;
+ }
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-members-tab.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-members-tab.component.ts
new file mode 100644
index 0000000..148f213
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-members-tab.component.ts
@@ -0,0 +1,133 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import * as _ from "lodash";
+import { Component, Input, Output, EventEmitter, OnChanges, HostBinding } from "@angular/core";
+import { TranslateService } from './../../../../../shared/translator/translate.service';
+import { Component as TopologyTemplate } from "app/models";
+import { GroupInstance } from "app/models/graph/zones/group-instance";
+import { GroupsService } from "../../../../../services/groups.service";
+import { SimpleChanges } from "@angular/core/src/metadata/lifecycle_hooks";
+import { MemberUiObject } from "../../../../../../models/ui-models/ui-member-object";
+import { IModalConfig } from "sdc-ui/lib/angular/modals/models/modal-config";
+import { AddElementsComponent } from "../../../../../components/ui/modal/add-elements/add-elements.component";
+import { GRAPH_EVENTS } from 'app/utils';
+import { EventListenerService } from 'app/services/event-listener-service';
+import { ComponentInstance } from "../../../../../../models/componentsInstances/componentInstance";
+import { SdcUiComponents } from "sdc-ui/lib/angular";
+
+@Component({
+ selector: 'group-members-tab',
+ templateUrl: './group-members-tab.component.html',
+ styleUrls: ['./../base/base-tab.component.less', 'group-members-tab.component.less']
+})
+
+export class GroupMembersTabComponent implements OnChanges {
+
+
+ private members: Array<MemberUiObject>;
+
+ @Input() group: GroupInstance;
+ @Input() topologyTemplate: TopologyTemplate;
+ @Input() isViewOnly: boolean;
+ @Output() isLoading: EventEmitter<boolean> = new EventEmitter<boolean>();
+ @HostBinding('class') classes = 'component-details-panel-tab-group-members';
+
+ constructor(private translateService: TranslateService,
+ private groupsService: GroupsService,
+ private modalService: SdcUiComponents.ModalService,
+ private eventListenerService: EventListenerService
+ ) {
+ this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_GROUP_INSTANCE_UPDATE, this.initMembers)
+ }
+
+ ngOnChanges(changes:SimpleChanges):void {
+ this.initMembers();
+ }
+
+ deleteMember = (member: MemberUiObject):void => {
+ this.isLoading.emit(true);
+ this.groupsService.deleteGroupMember(this.topologyTemplate.componentType, this.topologyTemplate.uniqueId, this.group, member.uniqueId).subscribe(
+ (updatedMembers:Array<string>) => {
+ this.group.members = updatedMembers;
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_GROUP_INSTANCE_UPDATE, this.group);
+ },
+ error => console.log("Error deleting member!"),
+ () => this.isLoading.emit(false)
+ );
+ }
+
+ private initMembers = (groupInstance?: GroupInstance) => {
+ this.group = groupInstance ? groupInstance : this.group;
+ this.members = this.group.getMembersAsUiObject(this.topologyTemplate.componentInstances);
+ }
+
+ addMembers = ():void => {
+ var membersToAdd:Array<MemberUiObject> = this.modalService.getCurrentInstance().innerModalContent.instance.existingElements; //TODO refactor sdc-ui modal in order to return the data
+ if(membersToAdd.length > 0) {
+ this.modalService.closeModal();
+ this.isLoading.emit(true);
+ var updatedMembers: Array<MemberUiObject> = _.union(this.members, membersToAdd);
+ this.groupsService.updateMembers(this.topologyTemplate.componentType, this.topologyTemplate.uniqueId, this.group.uniqueId, updatedMembers).subscribe(
+ (updatedMembers:Array<string>) => {
+ this.group.members = updatedMembers;
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_GROUP_INSTANCE_UPDATE, this.group);
+ },
+ error => {
+ console.log("Error updating members!");
+ }, () =>
+ this.isLoading.emit(false)
+ );
+ }
+ }
+
+ getOptionalsMembersToAdd():Array<MemberUiObject> {
+
+ let optionalsMembersToAdd:Array<MemberUiObject> = [];
+
+ // adding all instances as optional members to add if not already exist
+ _.forEach(this.topologyTemplate.componentInstances, (instance:ComponentInstance) => {
+ if (!_.some(this.members, (member:MemberUiObject) => {
+ return member.uniqueId === instance.uniqueId
+ })) {
+ optionalsMembersToAdd.push(new MemberUiObject(instance.uniqueId, instance.name));
+ }
+ });
+ return optionalsMembersToAdd;
+ }
+
+ openAddMembersModal():void {
+ let addMembersModalConfig:IModalConfig = {
+ title: this.group.name + " ADD MEMBERS",
+ size: "md",
+ type: "custom",
+ testId: "addMembersModal",
+ buttons: [
+ {text: 'ADD MEMBERS', size: 'xsm', callback: this.addMembers, closeModal: false},
+ {text: 'CANCEL', size: 'sm', type: "secondary", closeModal: true}
+ ]
+ };
+ var optionalsMembersToAdd = this.getOptionalsMembersToAdd();
+ this.modalService.openCustomModal(addMembersModalConfig, AddElementsComponent, {
+ elementsToAdd: optionalsMembersToAdd,
+ elementName: "member"
+ });
+ }
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-properties-tab.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-properties-tab.component.html
new file mode 100644
index 0000000..9de489e
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-properties-tab.component.html
@@ -0,0 +1,23 @@
+<ng2-expand-collapse state="0">
+ <header tooltip="Properties">Properties</header>
+ <content>
+ <ul>
+ <li *ngFor="let property of properties; let i = index"
+ class="i-sdc-designer-sidebar-section-content-item-property-and-attribute" data-tests-id="propertyRow">
+ <div class="i-sdc-designer-sidebar-section-content-item-property-and-attribute-label hand"
+ [attr.data-tests-id]="'propertyName_'+property.name"
+ tooltip="{{property.name}}"
+ (click)="!isViewOnly && editProperty(property)">{{property.name}}
+ </div>
+ <div class="i-sdc-designer-sidebar-section-content-item-property-value"
+ [attr.data-tests-id]="'value_'+property.name"
+ tooltip="{{property.value || property.defaultValue}}">{{property.value || property.defaultValue}}
+ </div>
+ </li>
+ </ul>
+
+ <div *ngIf="properties.length===0" class="component-details-panel-tab-no-data">
+ <div class="component-details-panel-tab-no-data-title">No properties to display</div>
+ </div>
+ </content>
+</ng2-expand-collapse>
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-properties-tab.component.less b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-properties-tab.component.less
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-properties-tab.component.less
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-properties-tab.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-properties-tab.component.ts
new file mode 100644
index 0000000..6907934
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-properties-tab.component.ts
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import * as _ from "lodash";
+import { Component, Inject, Input, Output, EventEmitter, OnChanges, SimpleChanges } from "@angular/core";
+import { TranslateService } from './../../../../../shared/translator/translate.service';
+import { GroupInstance } from 'app/models/graph/zones/group-instance';
+import { PropertyBEModel } from 'app/models';
+import { PropertyModel } from './../../../../../../models/properties';
+import { ModalsHandler } from "app/utils";
+import { Component as TopologyTemplate, ComponentInstance, IAppMenu } from "app/models";
+
+@Component({
+ selector: 'group-properties-tab',
+ templateUrl: './group-properties-tab.component.html',
+ styleUrls: ['./../base/base-tab.component.less', 'group-properties-tab.component.less'],
+ host: {'class': 'component-details-panel-tab-group-properties'}
+})
+export class GroupPropertiesTabComponent implements OnChanges {
+
+ @Input() group:GroupInstance;
+ @Input() topologyTemplate:TopologyTemplate;
+ @Input() isViewOnly: boolean;
+
+ private properties:Array<PropertyModel>;
+
+ constructor(private translateService:TranslateService, private ModalsHandler:ModalsHandler) {
+ }
+
+ ngOnChanges(changes: SimpleChanges): void {
+ console.log("GroupPropertiesTabComponent: ngAfterViewInit: ");
+ console.log("group: " + JSON.stringify(this.group));
+ this.properties = [];
+ this.initProperties();
+ }
+
+ initProperties = ():void => {
+ this.properties= this.group.properties;
+ }
+
+ editProperty = (property?:PropertyModel):void => {
+ this.ModalsHandler.openEditPropertyModal((property ? property : new PropertyModel()), this.topologyTemplate, this.properties, false, 'group', this.group.uniqueId).then((updatedProperty:PropertyModel) => {
+ console.log("ok");
+ });
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-tabs.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-tabs.component.html
new file mode 100644
index 0000000..94b6619
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-tabs.component.html
@@ -0,0 +1,11 @@
+<sdc-tabs>
+ <sdc-tab titleIcon="info-circle">
+ <group-information-tab [group]="group" [isViewOnly]="isViewOnly" *ngIf="group"></group-information-tab>
+ </sdc-tab>
+ <sdc-tab titleIcon="inputs-o">
+ <group-members-tab [group]="group" [topologyTemplate]="topologyTemplate" [isViewOnly]="isViewOnly" (isLoading)="setIsLoading($event)" *ngIf="group"></group-members-tab>
+ </sdc-tab>
+ <sdc-tab titleIcon="settings-o">
+ <group-properties-tab [group]="group" [topologyTemplate]="topologyTemplate" [isViewOnly]="isViewOnly" *ngIf="group"></group-properties-tab>
+ </sdc-tab>
+</sdc-tabs>
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-tabs.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-tabs.component.ts
new file mode 100644
index 0000000..975d5c6
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-tabs.component.ts
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import * as _ from "lodash";
+import { Component, Inject, Input, Output, EventEmitter, SimpleChanges, OnChanges } from "@angular/core";
+import { TranslateService } from './../../../../../shared/translator/translate.service';
+import { Component as TopologyTemplate, ComponentInstance, IAppMenu } from "app/models";
+import { GroupsService } from '../../../../../services/groups.service';
+import { GroupInstance } from "app/models/graph/zones/group-instance";
+
+@Component({
+ selector: 'group-tabs',
+ templateUrl: './group-tabs.component.html'
+})
+export class GroupTabsComponent implements OnChanges {
+
+ @Input() topologyTemplate:TopologyTemplate;
+ @Input() selectedZoneInstanceType:string;
+ @Input() selectedZoneInstanceId:string;
+ @Input() isViewOnly: boolean;
+ @Output() isLoading: EventEmitter<boolean> = new EventEmitter<boolean>();
+
+ private group:GroupInstance;
+
+ constructor(private translateService:TranslateService,
+ private groupsService:GroupsService
+ ) {
+ }
+
+ ngOnChanges(changes: SimpleChanges): void {
+ this.initGroup();
+ }
+
+ private initGroup = ():void => {
+ this.isLoading.emit(true);
+ this.groupsService.getSpecificGroup(this.topologyTemplate.componentType, this.topologyTemplate.uniqueId, this.selectedZoneInstanceId).subscribe(
+ group => {
+ this.group = group;
+ console.log(JSON.stringify(group));
+ },
+ error => console.log("Error getting group!"),
+ () => this.isLoading.emit(false)
+ );
+ }
+
+ private setIsLoading = (value) :void => {
+ this.isLoading.emit(value);
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-tabs.module.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-tabs.module.ts
new file mode 100644
index 0000000..50797f8
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/groups/group-tabs.module.ts
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+import { NgModule } from "@angular/core";
+import { HttpModule } from "@angular/http";
+import { FormsModule } from "@angular/forms";
+import { BrowserModule } from "@angular/platform-browser";
+import { UiElementsModule } from 'app/ng2/components/ui/ui-elements.module';
+import { ExpandCollapseComponent } from 'app/ng2/components/ui/expand-collapse/expand-collapse.component';
+import { PoliciesService } from "../../../../../services/policies.service";
+import { GroupInformationTabComponent } from './group-information-tab.component';
+import { TooltipModule } from './../../../../../components/ui/tooltip/tooltip.module';
+import { GroupTabsComponent } from "./group-tabs.component";
+import { SdcUiComponentsModule } from "sdc-ui/lib/angular";
+import { GroupMembersTabComponent } from './group-members-tab.component';
+import { TranslateModule } from './../../../../../shared/translator/translate.module';
+import { GroupPropertiesTabComponent } from "./group-properties-tab.component";
+
+@NgModule({
+ declarations: [
+ GroupInformationTabComponent,
+ GroupMembersTabComponent,
+ GroupTabsComponent,
+ GroupPropertiesTabComponent
+ ],
+ imports: [
+ BrowserModule,
+ FormsModule,
+ HttpModule,
+ TooltipModule,
+ UiElementsModule,
+ SdcUiComponentsModule,
+ TranslateModule
+ ],
+ entryComponents: [
+ GroupInformationTabComponent,
+ GroupMembersTabComponent,
+ GroupTabsComponent,
+ GroupPropertiesTabComponent,
+ ExpandCollapseComponent
+ ],
+ exports: [
+ TooltipModule,
+ GroupInformationTabComponent,
+ GroupMembersTabComponent,
+ GroupTabsComponent,
+ GroupPropertiesTabComponent
+ ],
+ providers: [
+ PoliciesService
+ ]
+})
+export class GroupTabsModule {
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-information-tab.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-information-tab.component.html
new file mode 100644
index 0000000..a1b942d
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-information-tab.component.html
@@ -0,0 +1,34 @@
+<ng2-expand-collapse state="0">
+ <header tooltip="General Information">General Info</header>
+ <content>
+ <!-- TYPE -->
+ <div class="component-details-panel-item">
+ <span class="name" [innerHTML]="'GENERAL_LABEL_TYPE' | translate"></span>
+ <span class="value" data-tests-id="rightTab_componentType" tooltip="{{policy.policyTypeUid}}">{{policy.policyTypeUid}}</span>
+ </div>
+
+ <!-- CATEGORY -->
+ <div class="component-details-panel-item">
+ <span class="name" [innerHTML]="'GENERAL_LABEL_CATEGORY' | translate"></span>
+ <span class="value" data-tests-id="rightTab_category" tooltip="Policy">Policy</span>
+ </div>
+
+ <!-- SUB CATEGORY -->
+ <div class="component-details-panel-item">
+ <span class="name" [innerHTML]="'GENERAL_LABEL_SUB_CATEGORY' | translate"></span>
+ <span class="value" data-tests-id="rightTab_subCategory" tooltip="Policy">Policy</span>
+ </div>
+
+ <!-- VERSION -->
+ <div class="component-details-panel-item">
+ <span class="name" [innerHTML]="'GENERAL_LABEL_VERSION' | translate"></span>
+ <span class="value" data-tests-id="rightTab_version" tooltip="{{policy.version}}">{{policy.version}}</span>
+ </div>
+
+ <!-- DESCRIPTION -->
+ <div class="component-details-panel-item description">
+ <span class="name" [innerHTML]="'GENERAL_LABEL_DESCRIPTION' | translate"></span>
+ <span class="value" ellipsis="policy.description" max-chars="55" data-tests-id="rightTab_description">{{policy.description}}</span>
+ </div>
+ </content>
+</ng2-expand-collapse>
diff --git a/catalog-ui/src/app/filters/catalog-status-filter.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-information-tab.component.ts
similarity index 60%
copy from catalog-ui/src/app/filters/catalog-status-filter.ts
copy to catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-information-tab.component.ts
index 3c0389d..3639639 100644
--- a/catalog-ui/src/app/filters/catalog-status-filter.ts
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-information-tab.component.ts
@@ -7,9 +7,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,21 +18,22 @@
* ============LICENSE_END=========================================================
*/
-/**
- * Created by obarda on 19/08/2015.
- */
-export class CatalogStatusFilter {
+import * as _ from "lodash";
+import { Component, Inject, Input, Output, EventEmitter } from "@angular/core";
+import { TranslateService } from './../../../../../shared/translator/translate.service';
+import { PolicyInstance } from 'app/models/graph/zones/policy-instance';
- constructor() {
- let filter = <CatalogStatusFilter>( (statuses:any) => {
- let filtered = [];
- angular.forEach(statuses, function (status) {
- filtered.push(status);
- });
- return filtered;
- });
+@Component({
+ selector: 'policy-information-tab',
+ templateUrl: './policy-information-tab.component.html',
+ styleUrls: ['./../base/base-tab.component.less']
+})
+export class PolicyInformationTabComponent {
+
+ @Input() policy:PolicyInstance;
+ @Input() isViewOnly: boolean;
- return filter;
+ constructor(private translateService:TranslateService) {
}
-}
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-properties-tab.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-properties-tab.component.html
new file mode 100644
index 0000000..9de489e
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-properties-tab.component.html
@@ -0,0 +1,23 @@
+<ng2-expand-collapse state="0">
+ <header tooltip="Properties">Properties</header>
+ <content>
+ <ul>
+ <li *ngFor="let property of properties; let i = index"
+ class="i-sdc-designer-sidebar-section-content-item-property-and-attribute" data-tests-id="propertyRow">
+ <div class="i-sdc-designer-sidebar-section-content-item-property-and-attribute-label hand"
+ [attr.data-tests-id]="'propertyName_'+property.name"
+ tooltip="{{property.name}}"
+ (click)="!isViewOnly && editProperty(property)">{{property.name}}
+ </div>
+ <div class="i-sdc-designer-sidebar-section-content-item-property-value"
+ [attr.data-tests-id]="'value_'+property.name"
+ tooltip="{{property.value || property.defaultValue}}">{{property.value || property.defaultValue}}
+ </div>
+ </li>
+ </ul>
+
+ <div *ngIf="properties.length===0" class="component-details-panel-tab-no-data">
+ <div class="component-details-panel-tab-no-data-title">No properties to display</div>
+ </div>
+ </content>
+</ng2-expand-collapse>
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-properties-tab.component.less b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-properties-tab.component.less
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-properties-tab.component.less
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-properties-tab.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-properties-tab.component.ts
new file mode 100644
index 0000000..5862135
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-properties-tab.component.ts
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import * as _ from "lodash";
+import { Component, Inject, Input, Output, EventEmitter, OnChanges, SimpleChanges } from "@angular/core";
+import { TranslateService } from './../../../../../shared/translator/translate.service';
+import { PolicyInstance } from 'app/models/graph/zones/policy-instance';
+import { PropertyBEModel } from 'app/models';
+import { PropertyModel } from './../../../../../../models/properties';
+import { ModalsHandler } from "app/utils";
+import { Component as TopologyTemplate, ComponentInstance, IAppMenu } from "app/models";
+
+@Component({
+ selector: 'policy-properties-tab',
+ templateUrl: './policy-properties-tab.component.html',
+ styleUrls: ['./../base/base-tab.component.less', 'policy-properties-tab.component.less'],
+ host: {'class': 'component-details-panel-tab-policy-properties'}
+})
+export class PolicyPropertiesTabComponent implements OnChanges {
+
+ @Input() policy:PolicyInstance;
+ @Input() topologyTemplate:TopologyTemplate;
+ @Input() isViewOnly: boolean;
+
+ private properties:Array<PropertyModel>;
+
+ constructor(private translateService:TranslateService, private ModalsHandler:ModalsHandler) {
+ }
+
+ ngOnChanges(changes: SimpleChanges): void {
+ console.log("PolicyPropertiesTabComponent: ngAfterViewInit: ");
+ console.log("policy: " + this.policy);
+ this.properties = [];
+ this.initProperties();
+ }
+
+ initProperties = ():void => {
+ this.properties= this.policy.properties;
+ }
+
+ editProperty = (property?:PropertyModel):void => {
+ this.ModalsHandler.openEditPropertyModal((property ? property : new PropertyModel()), this.topologyTemplate, this.properties, false, 'policy', this.policy.uniqueId).then((updatedProperty:PropertyModel) => {
+ console.log("ok");
+ });
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-tabs.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-tabs.component.html
new file mode 100644
index 0000000..b11ad7e
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-tabs.component.html
@@ -0,0 +1,12 @@
+<sdc-tabs>
+ <sdc-tab titleIcon="info-circle">
+ <policy-information-tab [policy]="policy" [isViewOnly]="isViewOnly" *ngIf="policy"></policy-information-tab>
+ </sdc-tab>
+ <sdc-tab titleIcon="inputs-o">
+ <policy-targets-tab [policy]="policy" [topologyTemplate]="topologyTemplate" [isViewOnly]="isViewOnly" (isLoading)="setIsLoading($event)" *ngIf="policy"></policy-targets-tab>
+ </sdc-tab>
+ <sdc-tab titleIcon="settings-o">
+ <policy-properties-tab [policy]="policy" [topologyTemplate]="topologyTemplate" [isViewOnly]="isViewOnly" *ngIf="policy"></policy-properties-tab>
+ </sdc-tab>
+</sdc-tabs>
+
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-tabs.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-tabs.component.ts
new file mode 100644
index 0000000..1e27399
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-tabs.component.ts
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import * as _ from "lodash";
+import { Component, Inject, Input, Output, EventEmitter, AfterViewInit, OnChanges } from "@angular/core";
+import { TranslateService } from './../../../../../shared/translator/translate.service';
+import { PoliciesService } from "../../../../../services/policies.service";
+import { Component as TopologyTemplate, ComponentInstance, IAppMenu } from "app/models";
+import { PolicyInstance } from 'app/models/graph/zones/policy-instance';
+import { GRAPH_EVENTS } from './../../../../../../utils/constants';
+import { EventListenerService } from 'app/services/event-listener-service';
+import { ZoneInstance } from 'app/models/graph/zones/zone-instance';
+import { SimpleChanges } from "@angular/core/src/metadata/lifecycle_hooks";
+
+@Component({
+ selector: 'policy-tabs',
+ templateUrl: './policy-tabs.component.html'
+})
+export class PolicyTabsComponent implements OnChanges {
+
+ @Input() topologyTemplate:TopologyTemplate;
+ @Input() selectedZoneInstanceType:string;
+ @Input() selectedZoneInstanceId:string;
+ @Input() isViewOnly: boolean;
+ @Output() isLoading: EventEmitter<boolean> = new EventEmitter<boolean>();
+
+ private policy:PolicyInstance;
+
+ constructor(private translateService:TranslateService,
+ private policiesService:PoliciesService
+ ) {
+
+ }
+
+ ngOnChanges(changes: SimpleChanges): void {
+ this.initPolicy();
+ }
+
+ private initPolicy = ():void => {
+ this.isLoading.emit(true);
+ this.policiesService.getSpecificPolicy(this.topologyTemplate.componentType, this.topologyTemplate.uniqueId, this.selectedZoneInstanceId).subscribe(
+ policy => {
+ this.policy = policy;
+ console.log(JSON.stringify(policy));
+ },
+ error => console.log("Error getting policy!"),
+ () => this.isLoading.emit(false)
+ );
+ }
+
+ private setIsLoading = (value) :void => {
+ this.isLoading.emit(value);
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-tabs.module.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-tabs.module.ts
new file mode 100644
index 0000000..38dc19e
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-tabs.module.ts
@@ -0,0 +1,68 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+import { NgModule } from "@angular/core";
+import { HttpModule } from "@angular/http";
+import { FormsModule } from "@angular/forms";
+import { BrowserModule } from "@angular/platform-browser";
+import { UiElementsModule } from 'app/ng2/components/ui/ui-elements.module';
+import { ExpandCollapseComponent } from 'app/ng2/components/ui/expand-collapse/expand-collapse.component';
+import { PoliciesService } from "../../../../../services/policies.service";
+import { PolicyInformationTabComponent } from "./policy-information-tab.component";
+import { PolicyTargetsTabComponent } from "./policy-targets-tab.component";
+import { PolicyTabsComponent } from "./policy-tabs.component";
+import { PolicyPropertiesTabComponent } from "./policy-properties-tab.component";
+import { SdcUiComponentsModule } from "sdc-ui/lib/angular";
+import { TranslateModule } from './../../../../../shared/translator/translate.module';
+
+@NgModule({
+ declarations: [
+ PolicyInformationTabComponent,
+ PolicyTargetsTabComponent,
+ PolicyPropertiesTabComponent,
+ PolicyTabsComponent
+ ],
+ imports: [
+ BrowserModule,
+ FormsModule,
+ HttpModule,
+ SdcUiComponentsModule,
+ TranslateModule,
+ UiElementsModule
+ ],
+ entryComponents: [
+ PolicyInformationTabComponent,
+ PolicyTargetsTabComponent,
+ PolicyPropertiesTabComponent,
+ PolicyTabsComponent,
+ ExpandCollapseComponent
+ ],
+ exports: [
+ PolicyInformationTabComponent,
+ PolicyTargetsTabComponent,
+ PolicyPropertiesTabComponent,
+ PolicyTabsComponent
+ ],
+ providers: [
+ PoliciesService
+ ]
+})
+export class PolicyTabsModule {
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-targets-tab.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-targets-tab.component.html
new file mode 100644
index 0000000..097b3a4
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-targets-tab.component.html
@@ -0,0 +1,32 @@
+<div class="w-sdc-designer-sidebar-section-title" titleTooltip="Targets">Targets
+ <svg-icon-label *ngIf="!isViewOnly"
+ class="add-policy-button"
+ name="plus-circle-o"
+ mode="primary"
+ size="medium"
+ label="ADD"
+ labelPlacement="right"
+ (click)="openAddTargetModal()">
+ </svg-icon-label>
+</div>
+<div class="expand-collapse-content">
+ <ul>
+ <li *ngFor="let target of targets; let i = index" class="component-details-panel-large-item"
+ tooltip="{{target.name}}">
+ <span>{{target.name}}</span>
+ <svg-icon-label *ngIf="!isViewOnly"
+ name="trash-o"
+ clickable="true"
+ size="small"
+ class="component-details-panel-item-delete"
+ data-tests-id="delete_target"
+ (click)="deleteTarget(target)"></svg-icon-label>
+ </li>
+ </ul>
+
+ <div *ngIf="targets.length===0" class="component-details-panel-tab-no-data">
+ <div class="component-details-panel-tab-no-data-title">No data to display yet</div>
+ <div class="component-details-panel-tab-no-data-content">Add targets to policy to see targets</div>
+ </div>
+</div>
+
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-targets-tab.component.less b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-targets-tab.component.less
new file mode 100644
index 0000000..cd7ace2
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-targets-tab.component.less
@@ -0,0 +1,12 @@
+/deep/
+.component-details-panel-tab-policy-targets {
+ .component-details-panel-large-item {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ }
+ .w-sdc-designer-sidebar-section-title {
+ display: flex;
+ justify-content: space-between;
+ }
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-targets-tab.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-targets-tab.component.ts
new file mode 100644
index 0000000..b79f4d9
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/policies/policy-targets-tab.component.ts
@@ -0,0 +1,145 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import * as _ from "lodash";
+import { Component, Input, Output, EventEmitter, OnChanges, HostBinding, OnDestroy } from "@angular/core";
+import { TranslateService } from './../../../../../shared/translator/translate.service';
+import { Component as TopologyTemplate } from "app/models";
+import { PoliciesService } from "../../../../../services/policies.service";
+import { PolicyInstance, PolicyTargetsMap } from './../../../../../../models/graph/zones/policy-instance';
+import { SimpleChanges } from "@angular/core/src/metadata/lifecycle_hooks";
+import { SdcUiComponents } from "sdc-ui/lib/angular";
+import { IModalConfig } from "sdc-ui/lib/angular/modals/models/modal-config";
+import { AddElementsComponent } from "../../../../../components/ui/modal/add-elements/add-elements.component";
+import { TargetUiObject } from "../../../../../../models/ui-models/ui-target-object";
+import { ComponentInstance } from "../../../../../../models/componentsInstances/componentInstance";
+import { TargetOrMemberType } from "../../../../../../utils/constants";
+import { GRAPH_EVENTS } from 'app/utils';
+import { EventListenerService } from 'app/services/event-listener-service';
+
+@Component({
+ selector: 'policy-targets-tab',
+ templateUrl: './policy-targets-tab.component.html',
+ styleUrls: ['./../base/base-tab.component.less', 'policy-targets-tab.component.less']
+})
+
+export class PolicyTargetsTabComponent implements OnChanges, OnDestroy {
+
+ private targets: Array<TargetUiObject>; // UI object to hold all targets with names.
+
+ @Input() policy: PolicyInstance;
+ @Input() topologyTemplate: TopologyTemplate;
+ @Input() isViewOnly: boolean;
+ @Output() isLoading: EventEmitter<boolean> = new EventEmitter<boolean>();
+ @HostBinding('class') classes = 'component-details-panel-tab-policy-targets';
+
+ constructor(private translateService: TranslateService,
+ private policiesService: PoliciesService,
+ private modalService: SdcUiComponents.ModalService,
+ private eventListenerService: EventListenerService
+ ) {
+ this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_POLICY_INSTANCE_UPDATE, this.initTargets)
+ }
+
+ ngOnChanges(changes:SimpleChanges):void {
+ this.initTargets();
+ }
+
+ ngOnDestroy() {
+ this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_POLICY_INSTANCE_UPDATE);
+ }
+
+ deleteTarget(target: TargetUiObject): void {
+ this.isLoading.emit(true);
+ this.policiesService.deletePolicyTarget(this.topologyTemplate.componentType, this.topologyTemplate.uniqueId, this.policy, target.uniqueId, target.type).subscribe(
+ (policyInstance:PolicyInstance) => {
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_POLICY_INSTANCE_UPDATE, policyInstance);
+ },
+ error => console.log("Error deleting target!"),
+ () => this.isLoading.emit(false)
+ );
+ }
+
+ private initTargets = (policyInstance?: PolicyInstance) => {
+ this.policy = policyInstance ? policyInstance : this.policy;
+ this.targets = this.policy.getTargetsAsUiObject(this.topologyTemplate.componentInstances, this.topologyTemplate.groupInstances);
+ }
+
+ addTargets = ():void => {
+
+ var targetsToAdd:Array<TargetUiObject> = this.modalService.getCurrentInstance().innerModalContent.instance.existingElements; //TODO refactor sdc-ui modal in order to return the data
+ if(targetsToAdd.length > 0) {
+ this.modalService.closeModal();
+ this.isLoading.emit(true);
+ var updatedTarget: Array<TargetUiObject> = _.union(this.targets, targetsToAdd);
+ this.policiesService.updateTargets(this.topologyTemplate.componentType, this.topologyTemplate.uniqueId, this.policy.uniqueId, updatedTarget).subscribe(
+ (updatedPolicyInstance:PolicyInstance) => {
+ this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_POLICY_INSTANCE_UPDATE, updatedPolicyInstance);
+ },
+ error => {
+ console.log("Error updating targets!");
+ },
+ () => this.isLoading.emit(false)
+ );
+ }
+ }
+
+ getOptionalsTargetsToAdd():Array<TargetUiObject> {
+ let optionalsTargetsToAdd:Array<TargetUiObject> = [];
+ // adding all instances as optional targets to add if not already exist
+ _.forEach(this.topologyTemplate.componentInstances, (instance:ComponentInstance) => {
+ if (!_.some(this.targets, (target:TargetUiObject) => {
+ return target.uniqueId === instance.uniqueId
+ })) {
+ optionalsTargetsToAdd.push(new TargetUiObject(instance.uniqueId, TargetOrMemberType.COMPONENT_INSTANCES, instance.name));
+ }
+ });
+
+ // adding all groups as optional targets to add if not already exist
+ _.forEach(this.topologyTemplate.groupInstances, (groupInstance:ComponentInstance) => { // adding all instances as optional targets to add if not already exist
+ if (!_.some(this.targets, (target:TargetUiObject) => {
+ return target.uniqueId === groupInstance.uniqueId
+ })) {
+ optionalsTargetsToAdd.push(new TargetUiObject(groupInstance.uniqueId, TargetOrMemberType.GROUPS, groupInstance.name));
+ }
+ });
+
+ return optionalsTargetsToAdd;
+ }
+
+ openAddTargetModal(): void {
+ let addTargetModalConfig: IModalConfig = {
+ title: this.policy.name + " ADD TARGETS",
+ size: "md",
+ type: "custom",
+ testId: "addTargetsModal",
+ buttons: [
+ {text: "ADD TARGETS", size: 'xsm', callback: this.addTargets, closeModal: false},
+ {text: 'CANCEL', size: 'sm', type: "secondary", closeModal: true}
+ ]
+ };
+ var optionalTargetsToAdd = this.getOptionalsTargetsToAdd();
+ this.modalService.openCustomModal(addTargetModalConfig, AddElementsComponent, {
+ elementsToAdd: optionalTargetsToAdd,
+ elementName: "target"
+ });
+
+ }
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel.component.html
new file mode 100644
index 0000000..430b272
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel.component.html
@@ -0,0 +1,34 @@
+<ng2-composition-panel-header
+ [name]="selectedZoneInstanceName"
+ [topologyTemplate]="topologyTemplate"
+ [selectedZoneInstanceType]="selectedZoneInstanceType"
+ [selectedZoneInstanceId]="selectedZoneInstanceId"
+ [nonCertified]="nonCertified"
+ [isViewOnly]="isViewOnly"
+ [isLoading]="isLoading"
+></ng2-composition-panel-header>
+
+<div class="component-details-panel-tabs">
+ <loader [display]="isLoading" [size]="'large'" [relative]="true" [loaderDelay]="500"></loader>
+
+ <div *ngIf="selectedZoneInstanceType === zoneInstanceType.POLICY">
+ <policy-tabs
+ [topologyTemplate]="topologyTemplate"
+ [selectedZoneInstanceType]="selectedZoneInstanceType"
+ [selectedZoneInstanceId]="selectedZoneInstanceId"
+ [isViewOnly]="isViewOnly"
+ (isLoading)="setIsLoading($event)"
+ ></policy-tabs>
+ </div>
+
+ <div *ngIf="selectedZoneInstanceType === zoneInstanceType.GROUP">
+ <group-tabs
+ [topologyTemplate]="topologyTemplate"
+ [selectedZoneInstanceType]="selectedZoneInstanceType"
+ [selectedZoneInstanceId]="selectedZoneInstanceId"
+ [isViewOnly]="isViewOnly"
+ (isLoading)="setIsLoading($event)"
+ ></group-tabs>
+ </div>
+
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel.component.less b/catalog-ui/src/app/ng2/pages/composition/panel/panel.component.less
new file mode 100644
index 0000000..1777d54
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel.component.less
@@ -0,0 +1,11 @@
+/deep/
+.component-details-panel {
+
+ color: #666666;
+ font-family: OpenSans-Regular, sans-serif;
+ font-size: 14px;
+
+ .component-details-panel-tabs {
+
+ }
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel.component.ts
new file mode 100644
index 0000000..53599d6
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel.component.ts
@@ -0,0 +1,60 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import * as _ from "lodash";
+import { Component, Inject, Input, Output, EventEmitter, AfterViewInit, SimpleChanges, HostBinding } from "@angular/core";
+import { Component as TopologyTemplate, ComponentInstance, IAppMenu } from "app/models";
+import { PolicyInstance } from 'app/models/graph/zones/policy-instance';
+import { TranslateService } from 'app/ng2/shared/translator/translate.service';
+import { ZoneInstanceType } from "app/models/graph/zones/zone-instance";
+import { GroupsService } from "../../../services/groups.service";
+import { PoliciesService } from "../../../services/policies.service";
+import { SdcUiComponents } from "sdc-ui/lib/angular";
+import { IZoneService } from "../../../../models/graph/zones/zone";
+
+@Component({
+ selector: 'ng2-composition-panel',
+ templateUrl: './panel.component.html',
+ styleUrls: ['./panel.component.less'],
+ providers: [TranslateService]
+})
+export class CompositionPanelComponent {
+
+ @Input() topologyTemplate: TopologyTemplate;
+ @Input() selectedZoneInstanceType: ZoneInstanceType;
+ @Input() selectedZoneInstanceId: string;
+ @Input() selectedZoneInstanceName: string;
+ @Input() nonCertified: boolean;
+ @Input() isViewOnly: boolean;
+ @Input() isLoading: boolean;
+
+
+ @HostBinding('class') classes = 'component-details-panel';
+
+ private zoneInstanceType = ZoneInstanceType; // Expose ZoneInstanceType to use in template.
+
+ constructor(){
+ }
+
+ private setIsLoading = (value):void => {
+ this.isLoading = value;
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel.module.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel.module.ts
new file mode 100644
index 0000000..57f6be8
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel.module.ts
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+import {NgModule} from "@angular/core";
+import {HttpModule} from "@angular/http";
+import {FormsModule} from "@angular/forms";
+import {BrowserModule} from "@angular/platform-browser";
+import {CompositionPanelComponent} from "./panel.component";
+import {CompositionPanelHeaderModule} from "app/ng2/pages/composition/panel/panel-header/panel-header.module";
+import {GroupTabsModule} from "./panel-tabs/groups/group-tabs.module";
+import {PolicyTabsModule} from "./panel-tabs/policies/policy-tabs.module";
+import {SdcUiComponents} from "sdc-ui/lib/angular";
+import {UiElementsModule} from 'app/ng2/components/ui/ui-elements.module';
+import {AddElementsModule} from "../../../components/ui/modal/add-elements/add-elements.module";
+
+@NgModule({
+ declarations: [
+ CompositionPanelComponent
+ ],
+ imports: [
+ BrowserModule,
+ FormsModule,
+ HttpModule,
+ CompositionPanelHeaderModule,
+ PolicyTabsModule,
+ GroupTabsModule,
+ UiElementsModule,
+ AddElementsModule
+ ],
+ entryComponents: [
+ CompositionPanelComponent
+ ],
+ exports: [],
+ providers: [SdcUiComponents.ModalService]
+})
+export class CompositionPanelModule {
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard.service.ts b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard.service.ts
index bf5ec4c..af8dcb4 100644
--- a/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard.service.ts
+++ b/catalog-ui/src/app/ng2/pages/connection-wizard/connection-wizard.service.ts
@@ -22,19 +22,6 @@
// this.selectedCapability = rel
}
-
- // getComponentInstanceIdOfSelectedCapability = (): string => {
- // if(this.selectedMatch.capability){
- // if(this.selectedMatch.isFromTo) {
- // return this.selectedMatch.toNode;
- // } else {
- // return this.selectedMatch.fromNode;
- // }
- // }
- // return '';
- //
- // }
-
getOptionalRequirementsByInstanceUniqueId = (isFromTo: boolean, matchWith?:Capability): Dictionary<Requirement[]> => {
let requirements: Array<Requirement> = [];
_.forEach(this.connectRelationModel.possibleRelations, (match: Match) => {
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html
index 03e9f1f..5142bba 100644
--- a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html
@@ -10,7 +10,7 @@
[searchTerm]="searchQuery"
[selectedPropertyId]="selectedFlatProperty.path"
[propertyNameSearchText]="searchPropertyName"
- [readonly]="isReadonly"
+ [readonly]="isReadonly || resourceIsReadonly"
[isLoading]="loadingProperties || savingChangedData"
[hasDeclareOption]="true"
(propertyChanged)="dataChanged($event)"
@@ -59,7 +59,7 @@
<hierarchy-navigation class="hierarchy-nav"
(updateSelected)="onInstanceSelectedUpdate($event)"
[displayData]="isInputsTabSelected ? []: instancesNavigationData"
- [selectedItem]="selectedInstanceData.uniqueId"
+ [selectedItem]="selectedInstanceData?.uniqueId"
[displayOptions]="hierarchyInstancesDisplayOptions"></hierarchy-navigation>
</div>
</tab>
@@ -79,9 +79,4 @@
</tabs>
</div>
</div>
- <template #saveChangedDataModalContentTemplate>
- <loader [display]="savingChangedData" [size]="'medium'" [relative]="true"></loader>
- Your changes{{isValidChangedData ? '' : ' (invalid)'}} have not been saved.<br>
- Do you want to {{isValidChangedData ? 'save' : 'discard'}} them?
- </template>
</div>
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts
index 40818bc..5a21e86 100644
--- a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts
@@ -25,7 +25,7 @@
import { ResourceType } from "app/utils";
import {ComponentServiceNg2} from "../../services/component-services/component.service";
import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service"
-import { InputBEModel, InputFEModel, ComponentInstance, PropertyBEModel, DerivedFEProperty, ResourceInstance, SimpleFlatProperty } from "app/models";
+import { InputBEModel, InputFEModel, ComponentInstance, GroupInstance, PolicyInstance, PropertyBEModel, DerivedFEProperty, SimpleFlatProperty } from "app/models";
import { KeysPipe } from 'app/ng2/pipes/keys.pipe';
import {WorkspaceMode, EVENTS} from "../../../utils/constants";
import {EventListenerService} from "app/services/event-listener-service"
@@ -38,6 +38,11 @@
import {ModalService} from "../../services/modal.service";
import {Tabs, Tab} from "../../components/ui/tabs/tabs.component";
import {InputsUtils} from "./services/inputs.utils";
+import { InstanceFeDetails } from "../../../models/instance-fe-details";
+import { SdcUiComponents } from "sdc-ui/lib/angular";
+//import { ModalService as ModalServiceSdcUI} from "sdc-ui/lib/angular/modals/modal.service";
+import { IModalButtonComponent } from "sdc-ui/lib/angular/modals/models/modal-config";
+import { UnsavedChangesComponent } from "app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component";
@Component({
templateUrl: './properties-assignment.page.component.html',
@@ -47,30 +52,30 @@
title = "Properties & Inputs";
component: ComponentData;
- componentInstanceNamesMap: Map<string, string> = new Map<string, string>();//instanceUniqueId, name
+ componentInstanceNamesMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>();//instanceUniqueId, {name, iconClass}
propertiesNavigationData = [];
instancesNavigationData = [];
instanceFePropertiesMap:InstanceFePropertiesMap;
inputs: Array<InputFEModel> = [];
- instances: Array<ComponentInstance> = [];
+ instances: Array<ComponentInstance|GroupInstance|PolicyInstance> = [];
searchQuery: string;
propertyStructureHeader: string;
selectedFlatProperty: SimpleFlatProperty = new SimpleFlatProperty();
- selectedInstanceType: string;
- selectedInstanceData: ComponentInstance = new ComponentInstance();
+ selectedInstanceData: ComponentInstance|GroupInstance|PolicyInstance = null;
checkedPropertiesCount: number = 0;
hierarchyPropertiesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
- hierarchyInstancesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name');
+ hierarchyInstancesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
displayClearSearch = false;
searchPropertyName:string;
currentMainTab:Tab;
isInputsTabSelected:boolean;
isPropertiesTabSelected:boolean;
isReadonly:boolean;
+ resourceIsReadonly:boolean;
loadingInstances:boolean = false;
loadingInputs:boolean = false;
loadingProperties:boolean = false;
@@ -83,8 +88,7 @@
@ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs;
@ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
@ViewChild('advanceSearch') advanceSearch: FilterPropertiesAssignmentComponent;
- @ViewChild('saveChangedDataModalContentTemplate') saveChangedDataModalContentTemplateRef: TemplateRef<void>;
-
+
constructor(private propertiesService: PropertiesService,
private hierarchyNavService: HierarchyNavService,
private propertiesUtils:PropertiesUtils,
@@ -97,14 +101,15 @@
@Inject("Notification") private Notification:any,
private componentModeService:ComponentModeService,
private ModalService:ModalService,
- private EventListenerService:EventListenerService) {
+ private EventListenerService:EventListenerService,
+ private ModalServiceSdcUI: SdcUiComponents.ModalService) {
this.instanceFePropertiesMap = new InstanceFePropertiesMap();
/* This is the way you can access the component data, please do not use any data except metadata, all other data should be received from the new api calls on the first time
than if the data is already exist, no need to call the api again - Ask orit if you have any questions*/
this.component = _stateParams.component;
- this.EventListenerService.registerObserverCallback(EVENTS.ON_CHECKOUT, this.onCheckout);
+ this.EventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.onCheckout);
this.updateViewMode();
this.changedData = [];
@@ -129,13 +134,16 @@
}, error => {}); //ignore error
this.componentServiceNg2
- .getComponentResourceInstances(this.component)
+ .getComponentResourcePropertiesData(this.component)
.subscribe(response => {
- this.instances = response.componentInstances;
+ this.instances = [];
+ this.instances.push(...response.componentInstances);
+ this.instances.push(...response.groupInstances);
+ this.instances.push(...response.policies);
_.forEach(this.instances, (instance) => {
this.instancesNavigationData.push(instance);
- this.componentInstanceNamesMap[instance.uniqueId] = instance.name;
+ this.componentInstanceNamesMap[instance.uniqueId] = <InstanceFeDetails>{name: instance.name, iconClass:instance.iconClass, originArchived:instance.originArchived};
});
this.loadingInstances = false;
if (this.instancesNavigationData[0] == undefined) {
@@ -148,17 +156,15 @@
// stop if has changed properties
if (this.hasChangedData) {
event.preventDefault();
- this.openChangedDataModal().then((proceed) => {
- if (proceed) {
- this.$state.go(toState, toParams);
- }
- });
+ this.showUnsavedChangesAlert().then(() => {
+ this.$state.go(toState, toParams);
+ }, () => {});
}
});
};
ngOnDestroy() {
- this.EventListenerService.unRegisterObserver(EVENTS.ON_CHECKOUT);
+ this.EventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
this.stateChangeStartUnregister();
}
@@ -178,47 +184,64 @@
}
- onInstanceSelectedUpdate = (resourceInstance: ResourceInstance) => {
- console.log("==>" + this.constructor.name + ": onInstanceSelectedUpdate");
-
+ onInstanceSelectedUpdate = (instance: ComponentInstance|GroupInstance|PolicyInstance) => {
// stop if has changed properties
if (this.hasChangedData) {
- this.openChangedDataModal().then((proceed) => {
- if (proceed) {
- this.onInstanceSelectedUpdate(resourceInstance);
- }
+ this.showUnsavedChangesAlert().then((resolve)=> {
+ this.changeSelectedInstance(instance)
+ }, (reject) => {
});
return;
}
+ this.changeSelectedInstance(instance);
+ };
- let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
- this.selectedInstanceData = resourceInstance;
- this.selectedInstanceType = resourceInstance.originType;
-
+ changeSelectedInstance = (instance: ComponentInstance|GroupInstance|PolicyInstance) => {
+ this.selectedInstanceData = instance;
this.loadingProperties = true;
- if (this.isInput(resourceInstance.originType)) {
- this.componentInstanceServiceNg2
- .getComponentInstanceInputs(this.component, resourceInstance)
- .subscribe(response => {
- instanceBePropertiesMap[resourceInstance.uniqueId] = response;
- this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
- this.loadingProperties = false;
+ if (instance instanceof ComponentInstance) {
+ let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
+ if (this.isInput(instance.originType)) {
+ this.componentInstanceServiceNg2
+ .getComponentInstanceInputs(this.component, instance)
+ .subscribe(response => {
+ instanceBePropertiesMap[instance.uniqueId] = response;
+ this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
+ this.loadingProperties = false;
+ }, error => {
+ }); //ignore error
+ } else {
+ this.componentInstanceServiceNg2
+ .getComponentInstanceProperties(this.component, instance.uniqueId)
+ .subscribe(response => {
+ instanceBePropertiesMap[instance.uniqueId] = response;
+ this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
+ this.loadingProperties = false;
+ }, error => {
+ }); //ignore error
+ }
- }, error => {
- }); //ignore error
- } else {
+ this.resourceIsReadonly = (instance.componentName === "vnfConfiguration");
+ } else if (instance instanceof GroupInstance) {
+ let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
this.componentInstanceServiceNg2
- .getComponentInstanceProperties(this.component, resourceInstance.uniqueId)
- .subscribe(response => {
- instanceBePropertiesMap[resourceInstance.uniqueId] = response;
+ .getComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
+ .subscribe((response) => {
+ instanceBePropertiesMap[instance.uniqueId] = response;
this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
this.loadingProperties = false;
- }, error => {
- }); //ignore error
- }
-
- if (resourceInstance.componentName === "vnfConfiguration") {
- this.isReadonly = true;
+ });
+ } else if (instance instanceof PolicyInstance) {
+ let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
+ this.componentInstanceServiceNg2
+ .getComponentPolicyInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
+ .subscribe((response) => {
+ instanceBePropertiesMap[instance.uniqueId] = response;
+ this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
+ this.loadingProperties = false;
+ });
+ } else {
+ this.loadingProperties = false;
}
if (this.searchPropertyName) {
@@ -289,7 +312,7 @@
this.propertyStructureHeader = null;
// Build hirarchy tree for the navigation and update propertiesNavigationData with it.
- if(this.selectedInstanceData.originType !== ResourceType.VF) {
+ if (!(this.selectedInstanceData instanceof ComponentInstance) || this.selectedInstanceData.originType !== ResourceType.VF) {
let simpleFlatProperty:Array<SimpleFlatProperty>;
if (property instanceof PropertyFEModel) {
simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(property, instanceName);
@@ -322,14 +345,11 @@
tabChanged = (event) => {
// stop if has changed properties
if (this.hasChangedData) {
- this.openChangedDataModal().then((proceed) => {
- if (proceed) {
- this.propertyInputTabs.selectTab(this.propertyInputTabs.tabs.find((tab) => tab.title === event.title));
- }
- });
-
- // return to show the current tab
this.propertyInputTabs.triggerTabChange(this.currentMainTab.title);
+ this.showUnsavedChangesAlert().then((proceed) => {
+ this.propertyInputTabs.selectTab(this.propertyInputTabs.tabs.find((tab) => tab.title === event.title));
+ }, ()=> {
+ });
return;
}
@@ -347,21 +367,28 @@
declareProperties = (): void => {
console.log("==>" + this.constructor.name + ": declareProperties");
- let selectedProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
- let selectedInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
+ let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
+ let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
+ let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
+ let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap();
let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []);
angular.forEach(instancesIds, (instanceId: string): void => {
- let selectedInstanceData: ResourceInstance = this.instances.find(instance => instance.uniqueId == instanceId);
- let originType: string = (selectedInstanceData) ? selectedInstanceData.originType : this.selectedInstanceType;
- if (!this.isInput(originType)) {
- selectedProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
- } else {
- selectedInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
+ let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
+ if (selectedInstanceData instanceof ComponentInstance) {
+ if (!this.isInput(selectedInstanceData.originType)) {
+ selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
+ } else {
+ selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
+ }
+ } else if (selectedInstanceData instanceof GroupInstance) {
+ selectedGroupInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
+ } else if (selectedInstanceData instanceof PolicyInstance) {
+ selectedPolicyInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
}
});
- let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedInputs, selectedProperties);
+ let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
this.componentServiceNg2
.createInput(this.component, inputsToCreate)
@@ -399,20 +426,34 @@
return propBE;
});
- if (this.isInput(this.selectedInstanceData.originType)) {
+ if (this.selectedInstanceData instanceof ComponentInstance) {
+ if (this.isInput(this.selectedInstanceData.originType)) {
+ request = this.componentInstanceServiceNg2
+ .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedProperties);
+ handleSuccess = (response) => {
+ // reset each changed property with new value and remove it from changed properties list
+ response.forEach((resInput) => {
+ const changedProp = <PropertyFEModel>this.changedData.shift();
+ this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
+ });
+ console.log('updated instance inputs:', response);
+ };
+ } else {
+ request = this.componentInstanceServiceNg2
+ .updateInstanceProperties(this.component, this.selectedInstanceData.uniqueId, changedProperties)
+ handleSuccess = (response) => {
+ // reset each changed property with new value and remove it from changed properties list
+ response.forEach((resProp) => {
+ const changedProp = <PropertyFEModel>this.changedData.shift();
+ this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
+ });
+ resolve(response);
+ console.log("updated instance properties: ", response);
+ };
+ }
+ } else if (this.selectedInstanceData instanceof GroupInstance) {
request = this.componentInstanceServiceNg2
- .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedProperties);
- handleSuccess = (response) => {
- // reset each changed property with new value and remove it from changed properties list
- response.forEach((resInput) => {
- const changedProp = <PropertyFEModel>this.changedData.shift();
- this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
- });
- console.log('updated instance inputs:', response);
- };
- } else {
- request = this.componentInstanceServiceNg2
- .updateInstanceProperties(this.component, this.selectedInstanceData.uniqueId, changedProperties)
+ .updateComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId, changedProperties);
handleSuccess = (response) => {
// reset each changed property with new value and remove it from changed properties list
response.forEach((resProp) => {
@@ -420,7 +461,19 @@
this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
});
resolve(response);
- console.log("updated instance properties: ", response);
+ console.log("updated group instance properties: ", response);
+ };
+ } else if (this.selectedInstanceData instanceof PolicyInstance) {
+ request = this.componentInstanceServiceNg2
+ .updateComponentPolicyInstanceProperties(this.component, this.selectedInstanceData.uniqueId, changedProperties);
+ handleSuccess = (response) => {
+ // reset each changed property with new value and remove it from changed properties list
+ response.forEach((resProp) => {
+ const changedProp = <PropertyFEModel>this.changedData.shift();
+ this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
+ });
+ resolve(response);
+ console.log("updated policy instance properties: ", response);
};
}
} else if (this.isInputsTabSelected) {
@@ -484,66 +537,59 @@
const curHasChangedData:boolean = (this.changedData.length > 0);
if (curHasChangedData !== this.hasChangedData) {
this.hasChangedData = curHasChangedData;
- this.$scope.$emit('setWorkspaceTopBarActive', !this.hasChangedData);
- }
+ if(this.hasChangedData) {
+ this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
+ } else {
+ this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
+ }
+ }
return this.hasChangedData;
};
- doSaveChangedData = ():void => {
+ doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
this.saveChangedData().then(
() => {
this.Notification.success({
message: 'Successfully saved changes',
title: 'Saved'
});
+ if(onSuccessFunction) onSuccessFunction();
},
() => {
this.Notification.error({
message: 'Failed to save changes!',
title: 'Failure'
});
+ if(onError) onError();
}
);
};
- openChangedDataModal = ():Promise<boolean> => {
- let modalTitle;
+ showUnsavedChangesAlert = ():Promise<any> => {
+ let modalTitle:string;
if (this.isPropertiesTabSelected) {
modalTitle = `Unsaved properties for ${this.selectedInstanceData.name}`;
} else if (this.isInputsTabSelected) {
modalTitle = `Unsaved inputs for ${this.component.name}`;
}
- return new Promise<boolean>((resolve) => {
- const modal = this.ModalService.createCustomModal(new ModalModel(
- 'sm',
- modalTitle,
- null,
- [
- new ButtonModel('Cancel', 'outline grey', () => {
- modal.instance.close();
- resolve(false);
- }),
- new ButtonModel('Discard', 'outline blue', () => {
- this.reverseChangedData();
- modal.instance.close();
- resolve(true);
- }),
- new ButtonModel('Save', 'blue', () => {
- this.saveChangedData().then(() => {
- modal.instance.close();
- resolve(true);
- }, () => {
- modal.instance.close();
- resolve(false);
- });
- }, () => !this.isValidChangedData)
- ]
- ));
- this.ModalService.addDynamicTemplateToModal(modal, this.saveChangedDataModalContentTemplateRef);
- modal.instance.open();
+ return new Promise<any>((resolve, reject) => {
+ const modal = this.ModalServiceSdcUI.openCustomModal(
+ {
+ title: modalTitle,
+ size: 'sm',
+ type: 'custom',
+ testId: "id",
+
+ 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.reverseChangedData(); resolve()}},
+ {id: 'saveButton', text: 'Save', type: 'primary', size: 'xsm', closeModal: true, disabled: !this.isValidChangedData, callback: () => this.doSaveChangedData(resolve, reject)}
+ ] as IModalButtonComponent[]
+ }, UnsavedChangesComponent, {isValidChangedData: this.isValidChangedData});
});
- };
+
+ }
updatePropertyValueAfterDeclare = (input: InputFEModel) => {
if (this.instanceFePropertiesMap[input.instanceUniqueId]) {
@@ -567,7 +613,16 @@
this.propertyInputTabs.setTabIndication('Inputs', numInputs);
};
+ resetUnsavedChangesForInput = (input:InputFEModel) => {
+ this.inputsUtils.resetInputDefaultValue(input, input.defaultValue);
+ this.changedData = this.changedData.filter((changedItem) => changedItem.uniqueId !== input.uniqueId);
+ this.updateHasChangedData();
+ }
+
deleteInput = (input: InputFEModel) => {
+ //reset any unsaved changes to the input before deleting it
+ this.resetUnsavedChangesForInput(input);
+
console.log("==>" + this.constructor.name + ": deleteInput");
let inputToDelete = new InputBEModel(input);
@@ -577,7 +632,7 @@
this.inputs = this.inputs.filter(input => input.uniqueId !== response.uniqueId);
//Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
- this.onInstanceSelectedUpdate(this.selectedInstanceData);
+ this.changeSelectedInstance(this.selectedInstanceData);
// let instanceFeProperties = this.instanceFePropertiesMap[this.getInstanceUniqueId(input.instanceName)];
// if (instanceFeProperties) {
diff --git a/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.html b/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.html
index bbbf6ae..e029b7f 100644
--- a/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.html
+++ b/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.html
@@ -1,5 +1,45 @@
-<ui-element-dropdown data-tests-id="linkSrc" [readonly]="!link.isFirst || (link.isFirst && !link.canEdit)" class="cell link-selector" [values]="source" [(value)]="link.fromNode" (valueChange)="onSourceSelected($event)"></ui-element-dropdown>
-<ui-element-dropdown data-tests-id="linkSrcCP" [readonly]="!link.isFirst || (link.isFirst && !link.canEdit)" class="cell link-selector" [values]="srcCP" [(value)]="link.fromCP" (valueChange)="onSrcCPSelected($event)"></ui-element-dropdown>
-<ui-element-dropdown data-tests-id="linkTarget" [readonly]="!link.canEdit" class="cell link-selector" [values]="target" [(value)]="link.toNode" (valueChange)="onTargetSelected($event)"></ui-element-dropdown>
-<ui-element-dropdown data-tests-id="linkTargetCP" [readonly]="!link.canEdit" class="cell link-selector" [values]="targetCP" [(value)]="link.toCP" (valueChange)="onTargetCPSelected($event)"></ui-element-dropdown>
-<div class="cell remove" data-tests-id="removeLnk"><span *ngIf="link.canRemove" class="sprite-new delete-item-icon" (click)="removeRow()"></span></div>
\ No newline at end of file
+<ui-element-dropdown
+ data-tests-id="linkSrc"
+ [readonly]="!link.isFirst || (link.isFirst && !link.canEdit)"
+ class="cell link-selector"
+ [values]="source"
+ [(value)]="link.fromNode"
+ (valueChange)="onSourceSelected($event)">
+</ui-element-dropdown>
+
+<ui-element-dropdown
+ data-tests-id="linkSrcCP"
+ [readonly]="!link.isFirst || (link.isFirst && !link.canEdit)"
+ class="cell link-selector"
+ [values]="srcCP"
+ [(value)]="link.fromCP"
+ (valueChange)="onSrcCPSelected($event)">
+</ui-element-dropdown>
+
+<ui-element-dropdown
+ data-tests-id="linkTarget"
+ [readonly]="!link.canEdit"
+ class="cell link-selector"
+ [values]="target"
+ [(value)]="link.toNode"
+ (valueChange)="onTargetSelected($event)">
+</ui-element-dropdown>
+
+<ui-element-dropdown
+ data-tests-id="linkTargetCP"
+ [readonly]="!link.canEdit"
+ class="cell link-selector"
+ [values]="targetCP"
+ [(value)]="link.toCP"
+ (valueChange)="onTargetCPSelected($event)">
+</ui-element-dropdown>
+
+<div
+ class="cell remove"
+ data-tests-id="removeLnk">
+ <span
+ *ngIf="link.canRemove"
+ class="sprite-new delete-item-icon"
+ (click)="removeRow()">
+ </span>
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.ts b/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.ts
index 1643324..e4fc1d4 100644
--- a/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.ts
+++ b/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.ts
@@ -14,7 +14,7 @@
@Input() data:Array<ServicePathMapItem>;
@Input() link:Link;
@Input() removeRow:Function;
- source:Array<DropdownValue> = [];
+ source: Array<DropdownValue> = [];
target: Array<DropdownValue> = [];
srcCP: Array<DropdownValue> = [];
targetCP: Array<DropdownValue> = [];
@@ -32,11 +32,9 @@
if (!srcCPOptions) { return; }
this.srcCP = this.convertValuesToDropDownOptions(srcCPOptions);
if (this.link.fromCP) {
- let targetOptions = this.findOptions(srcCPOptions, this.link.fromCP);
- if (!targetOptions) { return; }
- this.target = this.convertValuesToDropDownOptions(targetOptions);
+ this.target = this.convertValuesToDropDownOptions(data);
if (this.link.toNode) {
- let targetCPOptions = this.findOptions(targetOptions, this.link.toNode);
+ let targetCPOptions = this.findOptions(data, this.link.toNode);
if (!targetCPOptions) { return; }
this.targetCP = this.convertValuesToDropDownOptions(targetCPOptions);
}
@@ -45,7 +43,7 @@
}
private findOptions(items: Array<ServicePathMapItem>, nodeOrCPId: string) {
- let item = items.find((dataItem)=> nodeOrCPId === dataItem.id);
+ let item = _.find(items, (dataItem) => nodeOrCPId === dataItem.id);
if (item && item.data && item.data.options) {
return item.data.options;
}
@@ -53,12 +51,12 @@
return null;
}
- private convertValuesToDropDownOptions(values: Array<ServicePathMapItem>) : Array<DropdownValue> {
- let result = [];
+ private convertValuesToDropDownOptions(values: Array<ServicePathMapItem>): Array<DropdownValue> {
+ let result:Array<DropdownValue> = [];
for (let i = 0; i < values.length ; i++) {
result[result.length] = new DropdownValue(values[i].id, values[i].data.name);
}
- return result;
+ return result.sort((a, b) => a.label.localeCompare(b.label));
}
onSourceSelected(id) {
@@ -75,10 +73,9 @@
onSrcCPSelected (id) {
if (id) {
- let srcCPData = this.data.find((dataItem)=> this.link.fromNode === dataItem.id).data;
- let srcCPOptions = srcCPData.options;
- let targetOptions = this.findOptions(srcCPOptions, id);
- this.target = this.convertValuesToDropDownOptions(targetOptions);
+ let srcCPOptions = this.findOptions(this.data, this.link.fromNode);
+ let srcCPData = srcCPOptions.find(option => id === option.id).data;
+ this.target = this.convertValuesToDropDownOptions(this.data);
this.link.fromCPOriginId = srcCPData.ownerId;
this.link.toNode = '';
this.link.toCP = '';
@@ -89,9 +86,7 @@
onTargetSelected(id) {
if (id) {
- let srcCPOptions = this.findOptions(this.data, this.link.fromNode);
- let targetOptions = this.findOptions(srcCPOptions, this.link.fromCP);
- let targetCPOptions = this.findOptions(targetOptions, id);
+ let targetCPOptions = this.findOptions(this.data, id);
this.targetCP = this.convertValuesToDropDownOptions(targetCPOptions);
this.link.toCP = '';
}
@@ -100,11 +95,9 @@
onTargetCPSelected(id) {
if (id) {
- let srcCPOptions = this.findOptions(this.data, this.link.fromNode);
- let targetOptions = this.findOptions(srcCPOptions, this.link.fromCP);
- let targetCPOptions = this.findOptions(targetOptions, this.link.toNode);
- let targetCPDataObj = targetCPOptions.find((dataItem)=> id === dataItem.id).data;
+ let targetCPOptions = this.findOptions(this.data, this.link.toNode);
+ let targetCPDataObj = targetCPOptions.find(option => id === option.id).data;
this.link.toCPOriginId = targetCPDataObj.ownerId;
}
}
-}
\ No newline at end of file
+}
diff --git a/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.html b/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.html
index 96cd83ee..76c5c53 100644
--- a/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.html
+++ b/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.html
@@ -1,27 +1,24 @@
<div class="service-path-creator">
<form class="w-sdc-form">
<div class="i-sdc-form-item" >
- <label class="i-sdc-form-label required">Path Name</label>
- <!-- <ui-element-input type="text" name="pathName" [value]="pathName" ></ui-element-input> -->
- <input type="text" data-tests-id="pathName" name="pathName" [(ngModel)]="forwardingPath.name" [attr.maxLength]="100" /> <!-- TODO - make unique -->
+ <label class="i-sdc-form-label required">Flow Name</label>
+ <input type="text" data-tests-id="pathName" name="pathName" [(ngModel)]="forwardingPath.name" [attr.maxLength]="200" />
</div>
<div class="side-by-side">
<div class="i-sdc-form-item" >
<label class="i-sdc-form-label">Protocol</label>
- <!-- <ui-element-input type="text" name="protocol" [value]="protocol" ></ui-element-input> -->
- <input type="text" data-tests-id="pathProtocol" name="protocol" [(ngModel)]="forwardingPath.protocol" [attr.maxLength]="100" />
+ <input type="text" data-tests-id="pathProtocol" name="protocol" [(ngModel)]="forwardingPath.protocol" [attr.maxLength]="200" />
</div>
<div class="i-sdc-form-item" >
<label class="i-sdc-form-label">Destination Port Numbers</label>
- <!-- <ui-element-input type="text" name="portNumbers" [value]="portNumbers" ></ui-element-input> -->
- <input type="text" data-tests-id="pathPortNumbers" name="portNumbers" [(ngModel)]="forwardingPath.destinationPortNumber" pattern="[0-9,]*" /> <!-- TODO - validate delimiter -->
+ <input type="text" data-tests-id="pathPortNumbers" name="portNumbers" [(ngModel)]="forwardingPath.destinationPortNumber" pattern="[0-9,]*" />
</div>
</div>
<div class="separator-buttons">
<span class="based-on-title">Based On</span>
- <a (click)="addRow()" [ngClass]="{'disabled':!isExtendAllowed()}" data-tests-id="extendPathlnk">Extend Path</a>
+ <a (click)="addRow()" [ngClass]="{'disabled':!isExtendAllowed()}" data-tests-id="extendPathlnk">Extend Flow</a>
</div>
<div class="generic-table">
diff --git a/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.ts b/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.ts
index dac41a3..bffb1c5 100644
--- a/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.ts
+++ b/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.ts
@@ -73,12 +73,11 @@
this.forwardingPath.uniqueId = forwardingPath.uniqueId;
this.links = [];
_.forEach(forwardingPath.pathElements.listToscaDataDefinition, (link:ForwardingPathLink) => {
- this.links[this.links.length] = new Link( link, false, false, false);
+ this.links[this.links.length] = new Link(link, false, false, false);
});
- this.links[this.links.length -1].canEdit = true;
- this.links[this.links.length -1].canRemove = true;
+ this.links[this.links.length - 1].canEdit = true;
+ this.links[this.links.length - 1].canRemove = true;
this.links[0].isFirst = true;
-
}
}
@@ -98,7 +97,18 @@
addRow() {
this.disableRows();
- this.links[this.links.length] = new Link( new ForwardingPathLink(this.links[this.links.length-1].toNode,this.links[this.links.length-1].toCP,'','',this.links[this.links.length-1].toCPOriginId,''),true, true, false);
+ this.links[this.links.length] = new Link(
+ new ForwardingPathLink(this.links[this.links.length-1].toNode,
+ this.links[this.links.length-1].toCP,
+ '',
+ '',
+ this.links[this.links.length-1].toCPOriginId,
+ ''
+ ),
+ true,
+ true,
+ false
+ );
}
disableRows() {
diff --git a/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.html b/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.html
index 8a31c76..39c4191 100644
--- a/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.html
+++ b/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.html
@@ -1,5 +1,5 @@
<div class="service-path-list">
- <div class="add-path-link"><a (click)="onAddServicePath()" data-tests-id="add-service-path-lnk" >+ Add Path</a></div>
+ <div class="add-path-link" *ngIf="!isViewOnly"><a (click)="onAddServicePath()" data-tests-id="add-service-path-lnk" >+ Add Flow</a></div>
<div class="generic-table table-container" >
<div class="header-row">
<div class="cell header-cell" *ngFor="let header of headers">
@@ -10,11 +10,11 @@
<div class="cell" data-tests-id="path-name" >{{path.name}}</div>
<div class="cell path-action-buttons">
<span class="sprite-new update-component-icon" (click)="onEditServicePath(path.uniqueId)" data-tests-id="update-service-path-btn" ></span>
- <span class="sprite-new delete-item-icon" (click)="deletePath(path.uniqueId)" data-tests-id="delete-service-path-btn"></span>
+ <span class="sprite-new delete-item-icon" *ngIf="!isViewOnly" (click)="deletePath(path.uniqueId)" data-tests-id="delete-service-path-btn"></span>
</div>
</div>
<div *ngIf="paths && paths.length === 0" class="no-row-text" >
- No paths have been added yet.
+ No flows have been added yet.
</div>
</div>
diff --git a/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.less b/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.less
index aff597f..291119f 100644
--- a/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.less
+++ b/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.less
@@ -18,4 +18,7 @@
.sprite-new {
cursor: pointer;
}
+ & > span:only-child {
+ margin: auto;
+}
}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.ts b/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.ts
index 04083e8..1625ab4 100644
--- a/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.ts
+++ b/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.ts
@@ -38,9 +38,10 @@
input:any;
onAddServicePath: Function;
onEditServicePath: Function;
+ isViewOnly: boolean;
constructor(private serviceService:ServiceServiceNg2) {
- this.headers = ['Path Name','Actions'];
+ this.headers = ['Flow Name','Actions'];
}
ngOnInit() {
@@ -52,6 +53,7 @@
});
this.onAddServicePath = this.input.onCreateServicePath;
this.onEditServicePath = this.input.onEditServicePath;
+ this.isViewOnly = this.input.isViewOnly;
}
deletePath = (id:string):void => {
diff --git a/catalog-ui/src/app/ng2/pipes/global-pipes.module.ts b/catalog-ui/src/app/ng2/pipes/global-pipes.module.ts
index 3761aa8..758a7e8 100644
--- a/catalog-ui/src/app/ng2/pipes/global-pipes.module.ts
+++ b/catalog-ui/src/app/ng2/pipes/global-pipes.module.ts
@@ -2,6 +2,7 @@
import {SearchFilterPipe} from "./searchFilter.pipe";
import {KeysPipe} from "./keys.pipe";
import {GroupByPipe} from "./groupBy.pipe";
+import {ResourceNamePipe} from "./resource-name.pipe";
import {NgModule} from "@angular/core";
import {SafeUrlSanitizerPipe} from "./safeUrlSanitizer.pipe";
@@ -10,15 +11,17 @@
ContentAfterLastDotPipe,
GroupByPipe,
KeysPipe,
+ SafeUrlSanitizerPipe,
SearchFilterPipe,
- SafeUrlSanitizerPipe
+ ResourceNamePipe
],
exports: [
ContentAfterLastDotPipe,
GroupByPipe,
KeysPipe,
+ SafeUrlSanitizerPipe,
SearchFilterPipe,
- SafeUrlSanitizerPipe
+ ResourceNamePipe
]
})
diff --git a/catalog-ui/src/app/filters/catalog-status-filter.ts b/catalog-ui/src/app/ng2/pipes/resource-name.pipe.ts
similarity index 66%
copy from catalog-ui/src/app/filters/catalog-status-filter.ts
copy to catalog-ui/src/app/ng2/pipes/resource-name.pipe.ts
index 3c0389d..fdf9526 100644
--- a/catalog-ui/src/app/filters/catalog-status-filter.ts
+++ b/catalog-ui/src/app/ng2/pipes/resource-name.pipe.ts
@@ -7,9 +7,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,21 +18,17 @@
* ============LICENSE_END=========================================================
*/
-/**
- * Created by obarda on 19/08/2015.
- */
-export class CatalogStatusFilter {
- constructor() {
- let filter = <CatalogStatusFilter>( (statuses:any) => {
- let filtered = [];
- angular.forEach(statuses, function (status) {
- filtered.push(status);
- });
- return filtered;
- });
+import { Pipe, PipeTransform } from '@angular/core';
- return filter;
+@Pipe({name: 'resourceName'})
+export class ResourceNamePipe implements PipeTransform {
+ transform(value) : any {
+ if (value) {
+ //newName = _.last(newName.split('.'));
+ const newName:string =
+ _.last(value.split(/tosca\.nodes\..*network\..*relationships\..*org\.openecomp\..*resource\.nfv\..*nodes\.module\..*cp\..*vl\./));
+ return (newName) ? newName : value;
+ }
}
}
-
diff --git a/catalog-ui/src/app/ng2/services/archive.service.ts b/catalog-ui/src/app/ng2/services/archive.service.ts
new file mode 100644
index 0000000..83f1c50
--- /dev/null
+++ b/catalog-ui/src/app/ng2/services/archive.service.ts
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import { Injectable, Inject } from "@angular/core";
+import { Observable } from "rxjs/Observable";
+import { HttpService } from "./http.service";
+import { SdcConfigToken, ISdcConfig } from "../config/sdc-config.config";
+import { Component } from "../../models";
+import { ComponentFactory } from 'app/utils/component-factory';
+
+
+@Injectable()
+export class ArchiveService {
+ protected baseUrl;
+
+ constructor(private http: HttpService, @Inject(SdcConfigToken) sdcConfig:ISdcConfig, private componentFactory:ComponentFactory/*, @Inject(ComponentFactory) componentFactory */) {
+ this.baseUrl = sdcConfig.api.root ;
+ }
+
+ public getArchiveCatalog() {
+ let archiveCatalogItems:Component[] = [];
+ let archiveCatalogResourceItems:Component[] = [];
+ let archiveCatalogServiceItems:Component[] = [];
+
+ return this.http.get(this.baseUrl + '/v1/catalog/archive/', {}).map(res => {
+ let archiveCatalogObject = res.json();
+ if (archiveCatalogObject.resources) archiveCatalogResourceItems = this.getResourceItems(archiveCatalogObject.resources);
+ if (archiveCatalogObject.services) archiveCatalogServiceItems = this.getServiceItems(archiveCatalogObject.services);
+ archiveCatalogItems = [].concat(archiveCatalogResourceItems, archiveCatalogServiceItems);
+
+ return archiveCatalogItems;
+ });
+ }
+
+
+ private getResourceItems(resources){
+ let resourceItems = resources.map((resource)=>{
+ return this.componentFactory.createResource(resource)
+ })
+ return resourceItems;
+ }
+
+ private getServiceItems(services){
+ let serviceItems = services.map((service)=>{
+ return this.componentFactory.createService(service)
+ })
+ return serviceItems;
+ }
+
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/services/component-instance-services/component-instance.service.ts b/catalog-ui/src/app/ng2/services/component-instance-services/component-instance.service.ts
index 0947b2a..1575002 100644
--- a/catalog-ui/src/app/ng2/services/component-instance-services/component-instance.service.ts
+++ b/catalog-ui/src/app/ng2/services/component-instance-services/component-instance.service.ts
@@ -92,4 +92,32 @@
return res.json().map((resInput) => new PropertyBEModel(resInput));
});
}
+
+ getComponentGroupInstanceProperties(component: Component, groupInstanceId: string): Observable<Array<PropertyBEModel>> {
+ return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/groups/' + groupInstanceId + '/properties')
+ .map((res: Response) => {
+ return CommonUtils.initBeProperties(res.json());
+ });
+ }
+
+ updateComponentGroupInstanceProperties(component: Component, groupInstanceId: string, properties: PropertyBEModel[]): Observable<Array<PropertyBEModel>> {
+ return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/groups/' + groupInstanceId + '/properties', properties)
+ .map((res: Response) => {
+ return res.json().map((resProperty) => new PropertyBEModel(resProperty));
+ });
+ }
+
+ getComponentPolicyInstanceProperties(component: Component, policyInstanceId: string): Observable<Array<PropertyBEModel>> {
+ return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/policies/' + policyInstanceId + '/properties')
+ .map((res: Response) => {
+ return CommonUtils.initBeProperties(res.json());
+ });
+ }
+
+ updateComponentPolicyInstanceProperties(component: Component, policyInstanceId: string, properties: PropertyBEModel[]): Observable<Array<PropertyBEModel>> {
+ return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/policies/' + policyInstanceId + '/properties', properties)
+ .map((res: Response) => {
+ return res.json().map((resProperty) => new PropertyBEModel(resProperty));
+ });
+ }
}
diff --git a/catalog-ui/src/app/ng2/services/component-services/component.service.ts b/catalog-ui/src/app/ng2/services/component-services/component.service.ts
index 381995d..3546ebd 100644
--- a/catalog-ui/src/app/ng2/services/component-services/component.service.ts
+++ b/catalog-ui/src/app/ng2/services/component-services/component.service.ts
@@ -25,6 +25,7 @@
import 'rxjs/add/operator/toPromise';
import {Response, URLSearchParams} from '@angular/http';
import { Component, InputBEModel, InstancePropertiesAPIMap, FilterPropertiesAssignmentData, OperationModel, CreateOperationResponse} from "app/models";
+import {downgradeInjectable} from '@angular/upgrade/static';
import {COMPONENT_FIELDS} from "app/utils";
import {ComponentGenericResponse} from "../responses/component-generic-response";
import {InstanceBePropertiesMap} from "../../../models/properties-inputs/property-fe-map";
@@ -32,6 +33,9 @@
import { ComponentType, ServerTypeUrl } from "../../../utils/constants";
import { HttpService } from '../http.service';
import {SdcConfigToken, ISdcConfig} from "../../config/sdc-config.config";
+import {IDependenciesServerResponse} from "../responses/dependencies-server-response";
+import {AutomatedUpgradeGenericResponse} from "../responses/automated-upgrade-response";
+import {IAutomatedUpgradeRequestObj} from "../../pages/automated-upgrade/automated-upgrade.service";
declare var angular:angular.IAngularStatic;
@@ -83,7 +87,11 @@
}
getComponentCompositionData(component:Component):Observable<ComponentGenericResponse> {
- return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_RELATION, COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_POLICIES, COMPONENT_FIELDS.COMPONENT_GROUPS]);
+ return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_RELATION, COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_POLICIES, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_GROUPS]);
+ }
+
+ getComponentResourcePropertiesData(component:Component):Observable<ComponentGenericResponse> {
+ return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_POLICIES, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_GROUPS]);
}
getComponentResourceInstances(component:Component):Observable<ComponentGenericResponse> {
@@ -171,6 +179,15 @@
})
}
+ restoreComponent(componentType:string, componentId:string){
+ return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/restore', {})
+ }
+
+ archiveComponent(componentType:string, componentId:string){
+ return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/archive', {})
+ }
+
+
deleteInput(component:Component, input:InputBEModel):Observable<InputBEModel> {
return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/delete/' + input.uniqueId + '/input')
@@ -198,5 +215,19 @@
return res.json();
});
}
+
+ getDependencies(componentType:string, componentId: string):Observable<Array<IDependenciesServerResponse>> {
+ return this.http.get(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/dependencies')
+ .map((res:Response) => {
+ return res.json();
+ });
+ }
+
+ automatedUpgrade(componentType:string, componentId: string, componentsIdsToUpgrade:Array<IAutomatedUpgradeRequestObj>):Observable<AutomatedUpgradeGenericResponse> {
+ return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/automatedupgrade', componentsIdsToUpgrade)
+ .map((res:Response) => {
+ return res.json();
+ });
+ }
}
diff --git a/catalog-ui/src/app/ng2/services/component-services/service.service.ts b/catalog-ui/src/app/ng2/services/component-services/service.service.ts
index 0439f20..15e624b 100644
--- a/catalog-ui/src/app/ng2/services/component-services/service.service.ts
+++ b/catalog-ui/src/app/ng2/services/component-services/service.service.ts
@@ -126,7 +126,7 @@
}
getComponentCompositionData(component:Component):Observable<ComponentGenericResponse> {
- return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_RELATION, COMPONENT_FIELDS.COMPONENT_INSTANCES, SERVICE_FIELDS.FORWARDING_PATHS]);
+ return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_RELATION, COMPONENT_FIELDS.COMPONENT_INSTANCES, SERVICE_FIELDS.FORWARDING_PATHS, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_POLICIES, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_GROUPS]);
}
protected analyzeComponentDataResponse(res: Response):ComponentGenericResponse {
diff --git a/catalog-ui/src/app/ng2/services/config.service.ts b/catalog-ui/src/app/ng2/services/config.service.ts
index a9a4e86..1774a66 100644
--- a/catalog-ui/src/app/ng2/services/config.service.ts
+++ b/catalog-ui/src/app/ng2/services/config.service.ts
@@ -38,7 +38,7 @@
constructor(private http: Http, @Inject(SdcConfigToken) private sdcConfig:ISdcConfig) {
this.api = this.sdcConfig.api;
- this.baseUrl = this.sdcConfig.api.root + this.sdcConfig.api.component_api_root;
+ this.baseUrl = this.api.root + this.sdcConfig.api.component_api_root;
}
loadValidationConfiguration(): Promise<ValidationConfiguration> {
diff --git a/catalog-ui/src/app/ng2/services/groups.service.ts b/catalog-ui/src/app/ng2/services/groups.service.ts
new file mode 100644
index 0000000..e3b3d85
--- /dev/null
+++ b/catalog-ui/src/app/ng2/services/groups.service.ts
@@ -0,0 +1,78 @@
+import {IZoneInstanceAssignment} from '../../models/graph/zones/zone-instance';
+import {Injectable, Inject} from "@angular/core";
+import {Observable} from "rxjs/Observable";
+import {HttpService} from "./http.service";
+import {SdcConfigToken, ISdcConfig} from "../config/sdc-config.config";
+import {GroupInstance} from '../../models/graph/zones/group-instance';
+import {UiBaseObject} from "../../models/ui-models/ui-base-object";
+import {IZoneService} from "../../models/graph/zones/zone";
+
+@Injectable()
+export class GroupsService implements IZoneService {
+
+ protected baseUrl;
+
+ private mapApiDirections = {
+ 'RESOURCE': 'resources',
+ 'SERVICE': 'services'
+ }
+
+ constructor(private http:HttpService, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) {
+ this.baseUrl = sdcConfig.api.root;
+ }
+
+ public createGroupInstance(componentType:string, componentUniqueId:string, groupType:string) {
+ return this.http.post(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[componentType.toUpperCase()] + '/' + componentUniqueId + '/groups/' + groupType, {}).map(resp => {
+ return resp.json();
+ });
+ };
+
+ public addGroupMember(topologyTemplateType:string, topologyTemplateId:string, group:GroupInstance, memberId:string) {
+ let members:Array<string> = Object.assign({}, group.members);
+ members.push(memberId);
+ return this.updateGroupMembers(topologyTemplateType, topologyTemplateId, group.uniqueId, members);
+ }
+
+ public deleteGroupMember(topologyTemplateType:string, topologyTemplateId:string, group:GroupInstance, memberId:string) {
+ let _members:Array<string> = angular.copy(group.members);
+ _members =_.without(_members, memberId);
+ return this.updateGroupMembers(topologyTemplateType, topologyTemplateId, group.uniqueId, _members);
+ }
+
+ public updateGroupMembers(topologyTemplateType:string, topologyTemplateId:string, groupId:string, members:Array<string>):Observable<Array<string>> {
+ return this.http.post(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/groups/' + groupId + '/members', members)
+ .map(response => response.json());
+ }
+
+ public updateMembers(topologyTemplateType:string, topologyTemplateId:string, groupId:string, members:Array<UiBaseObject>):Observable<Array<string>> {
+ let membersIds:Array<string> = members.map(member => member.uniqueId);
+ return this.updateGroupMembers(topologyTemplateType, topologyTemplateId, groupId, membersIds);
+ }
+
+ public getSpecificGroup(topologyTemplateType:string, topologyTemplateId:string, groupId:string):Observable<GroupInstance> {
+ return this.http.get(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/groups/' + groupId)
+ .map(res => {
+ return new GroupInstance(res.json());
+ });
+ }
+
+ public updateName(topologyTemplateType:string, topologyTemplateId:string, groupId:string, newName:string):Observable<GroupInstance> {
+ return this.http.put(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/groups/' + groupId, {name: newName}).map(resp => {
+ return resp.json();
+ });
+ };
+
+ public deleteGroup(topologyTemplateType:string, topologyTemplateId:string, groupId:string) {
+ return this.http.delete(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/groups/' + groupId).map(resp => {
+ return resp.json();
+ });
+ };
+
+ public updateZoneInstanceAssignments(topologyTemplateType:string, topologyTemplateId:string, policyId:string, members:Array<IZoneInstanceAssignment>):Observable<any> {
+ return this.updateMembers(topologyTemplateType, topologyTemplateId, policyId, members);
+ };
+
+ public deleteZoneInstance(topologyTemplateType:string, topologyTemplateId:string, policyId:string):Observable<any> {
+ return this.deleteGroup(topologyTemplateType, topologyTemplateId, policyId);
+ };
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/services/modal.service.ts b/catalog-ui/src/app/ng2/services/modal.service.ts
index 4e86d6a..a8f1b99 100644
--- a/catalog-ui/src/app/ng2/services/modal.service.ts
+++ b/catalog-ui/src/app/ng2/services/modal.service.ts
@@ -24,6 +24,10 @@
this.createCustomModal(modalModel).instance.open();
}
+ public openErrorModal = (closeButtonText?: string, errorMessage?: string):void => {
+ let errorModal = this.createErrorModal(closeButtonText, errorMessage);
+ errorModal.instance.open();
+ };
/**
* Shortcut method to open a basic modal with title, message, and an action button with callback, as well as close button.
@@ -77,7 +81,7 @@
return wizardInstance;
}
-
+
public closeCurrentModal = () => {
if (!this.currentModal) return;
this.currentModal.instance.close();
@@ -102,3 +106,5 @@
}
+
+
diff --git a/catalog-ui/src/app/ng2/services/policies.service.ts b/catalog-ui/src/app/ng2/services/policies.service.ts
index 2b564b8..3675a7b 100644
--- a/catalog-ui/src/app/ng2/services/policies.service.ts
+++ b/catalog-ui/src/app/ng2/services/policies.service.ts
@@ -18,32 +18,107 @@
* ============LICENSE_END=========================================================
*/
-import { Injectable, Inject } from "@angular/core";
-import { Headers } from "@angular/http";
-import { Observable } from "rxjs/Observable";
-import { HttpService } from "./http.service";
-import { Cookie2Service } from "./cookie.service";
+import {Injectable, Inject} from "@angular/core";
+import {Observable} from "rxjs/Observable";
+import {HttpService} from "./http.service";
import {SdcConfigToken, ISdcConfig} from "../config/sdc-config.config";
+import {PolicyInstance, PolicyTargetsRequest} from '../../models/graph/zones/policy-instance';
+import {IZoneInstanceAssignment} from "../../models/graph/zones/zone-instance";
+import {IZoneService} from "../../models/graph/zones/zone";
+import {TargetUiObject} from "../../models/ui-models/ui-target-object";
+import {TargetOrMemberType} from "../../utils/constants";
@Injectable()
-export class PoliciesService {
+export class PoliciesService implements IZoneService {
protected baseUrl;
private mapApiDirections = {
- 'RESOURCE':'resources',
- 'SERVICE':'services'
+ 'RESOURCE': 'resources',
+ 'SERVICE': 'services'
}
- constructor(private http: HttpService, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) {
- this.baseUrl = sdcConfig.api.root ;
+ constructor(private http:HttpService, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) {
+ this.baseUrl = sdcConfig.api.root;
}
- public createPolicyInstance(entityType:string, id:string, policyType:string) {
- return this.http.post(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[entityType] + '/' + id +'/policies/' + policyType, {}).map(resp => {
- return resp.json();
+ public createPolicyInstance(topologyTemplateType:string, topologyTemplateId:string, policyType:string) {
+ return this.http.post(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/policies/' + policyType, {}).map(resp => {
+ return resp.json();
});
}
+ public addPolicyTarget(topologyTemplateType:string, topologyTemplateId:string, policy:PolicyInstance, targetId:string, targetType:TargetOrMemberType) {
+ let _targets:Array<string>;
+ let _members:Array<string>;
+
+ if (targetType === TargetOrMemberType.COMPONENT_INSTANCES) {
+ _targets = angular.copy(policy.targets.COMPONENT_INSTANCES);
+ _targets.push(targetId);
+ } else if (targetType === TargetOrMemberType.GROUPS) {
+ _members = angular.copy(policy.targets.GROUPS);
+ _members.push(targetId);
+ }
+ let policyTargetRequest:PolicyTargetsRequest = new PolicyTargetsRequest(_members, _targets);
+ return this.updatePolicyTargets(topologyTemplateType, topologyTemplateId, policy.uniqueId, policyTargetRequest);
+ }
+
+ public deletePolicyTarget(topologyTemplateType:string, topologyTemplateId:string, policy:PolicyInstance, targetId:string, targetType:TargetOrMemberType): Observable<PolicyInstance> {
+ let _targets:Array<string> = angular.copy(policy.targets.COMPONENT_INSTANCES);
+ let _members:Array<string> = angular.copy(policy.targets.GROUPS);
+ if (targetType === TargetOrMemberType.COMPONENT_INSTANCES) {
+ _targets = _.without(_targets, targetId);
+ } else if (targetType === TargetOrMemberType.GROUPS) {
+ _members = _.without(_members, targetId);
+ }
+ let policyTargetRequest:PolicyTargetsRequest = new PolicyTargetsRequest(_members, _targets);
+ return this.updatePolicyTargets(topologyTemplateType, topologyTemplateId, policy.uniqueId, policyTargetRequest);
+ }
+
+ public updatePolicyTargets(topologyTemplateType:string, topologyTemplateId:string, policyId:string, targets:PolicyTargetsRequest): Observable<PolicyInstance> {
+ return this.http.post(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/policies/' + policyId + '/targets', targets.requestItems)
+ .map(response => new PolicyInstance(response.json()));
+ }
+
+ public updateTargets(topologyTemplateType:string, topologyTemplateId:string, policyId:string, targets:Array<TargetUiObject>):Observable<PolicyInstance> {
+ let instances:Array<string> = _.filter(targets, (target:TargetUiObject)=> {
+ return target.type === TargetOrMemberType.COMPONENT_INSTANCES;
+ }).map(target => target.uniqueId);
+
+ let groups:Array<string> = _.filter(targets, (target:TargetUiObject)=> {
+ return target.type === TargetOrMemberType.GROUPS;
+ }).map(target => target.uniqueId);
+
+ let policyTargetRequest:PolicyTargetsRequest = new PolicyTargetsRequest(groups, instances);
+ return this.updatePolicyTargets(topologyTemplateType, topologyTemplateId, policyId, policyTargetRequest);
+ }
+
+ public getSpecificPolicy(topologyTemplateType:string, topologyTemplateId:string, policyId:string):Observable<PolicyInstance> {
+ return this.http.get(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/policies/' + policyId)
+ .map(res => {
+ return new PolicyInstance(res.json());
+ });
+ }
+
+ public updateName(topologyTemplateType:string, topologyTemplateId:string, policyId:string, newName:string):Observable<any> {
+ return this.http.put(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/policies/' + policyId, {name: newName}).map(res => {
+ return res.json();
+ });
+ };
+
+ public deletePolicy(topologyTemplateType:string, topologyTemplateId:string, policyId:string) {
+ return this.http.delete(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/policies/' + policyId).map(resp => {
+ return resp.json();
+ });
+ };
+
+ public updateZoneInstanceAssignments(topologyTemplateType:string, topologyTemplateId:string, policyId:string, targets:Array<IZoneInstanceAssignment>):Observable<PolicyInstance>{
+ return this.updateTargets(topologyTemplateType, topologyTemplateId, policyId, targets);
+ };
+
+ public deleteZoneInstance(topologyTemplateType:string, topologyTemplateId:string, policyId:string):Observable<any> {
+ return this.deletePolicy(topologyTemplateType, topologyTemplateId, policyId);
+ };
+
}
diff --git a/catalog-ui/src/app/ng2/services/responses/automated-upgrade-response.ts b/catalog-ui/src/app/ng2/services/responses/automated-upgrade-response.ts
new file mode 100644
index 0000000..feac868
--- /dev/null
+++ b/catalog-ui/src/app/ng2/services/responses/automated-upgrade-response.ts
@@ -0,0 +1,16 @@
+/**
+ * Created by ob0695 on 4/29/2018.
+ */
+
+export class AutomatedUpgradeStatusResponse {
+ name:string;
+ status:string;
+ uniqueId:string;
+ version:string;
+}
+
+export class AutomatedUpgradeGenericResponse {
+ error:string;
+ status:string;
+ componentToUpgradeStatus:Array<AutomatedUpgradeStatusResponse>;
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/services/responses/component-generic-response.ts b/catalog-ui/src/app/ng2/services/responses/component-generic-response.ts
index 5036a10..a77133e 100644
--- a/catalog-ui/src/app/ng2/services/responses/component-generic-response.ts
+++ b/catalog-ui/src/app/ng2/services/responses/component-generic-response.ts
@@ -28,6 +28,7 @@
import {Serializable} from "../utils/serializable";
import {PropertyBEModel} from "../../../models/properties-inputs/property-be-model";
import { PolicyInstance } from "app/models/graph/zones/policy-instance";
+import { GroupInstance } from "../../../models/graph/zones/group-instance";
export class ComponentGenericResponse implements Serializable<ComponentGenericResponse> {
@@ -45,7 +46,8 @@
public properties:Array<PropertyModel>;
public attributes:Array<AttributeModel>;
public policies:Array<PolicyInstance>;
- public groups:Array<Module>;
+ public groupInstances: Array<GroupInstance>;
+ public modules:Array<Module>;
public interfaces:any;
public interfaceOperations:Array<OperationModel>;
public additionalInformation:any;
@@ -96,7 +98,8 @@
this.metadata = new ComponentMetadata().deserialize(response.metadata);
}
if(response.groups) {
- this.groups = CommonUtils.initModules(response.groups);
+ this.modules = CommonUtils.initModules(response.groups);
+ this.groupInstances = CommonUtils.initGroups(response.groups)
}
if(response.policies) {
this.policies = CommonUtils.initPolicies(response.policies);
diff --git a/catalog-ui/src/app/ng2/services/responses/dependencies-server-response.ts b/catalog-ui/src/app/ng2/services/responses/dependencies-server-response.ts
new file mode 100644
index 0000000..be8aaea
--- /dev/null
+++ b/catalog-ui/src/app/ng2/services/responses/dependencies-server-response.ts
@@ -0,0 +1,14 @@
+import { state } from '@angular/core';
+/**
+ * Created by ob0695 on 4/23/2018.
+ */
+export interface IDependenciesServerResponse {
+ icon: string;
+ name: string;
+ type: string;
+ uniqueId: string;
+ version: string;
+ state: string;
+ dependencies: Array<IDependenciesServerResponse>;
+ instanceNames: Array<string>;
+}
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/services/responses/properties.response.ts b/catalog-ui/src/app/ng2/services/responses/properties.response.ts
deleted file mode 100644
index a1c0660..0000000
--- a/catalog-ui/src/app/ng2/services/responses/properties.response.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-export class PropertiesResponse {
- properties: Array<Property>;
-}
-
-class Property {
- name: string
-}
diff --git a/catalog-ui/src/app/ng2/services/window.service.ts b/catalog-ui/src/app/ng2/services/window.service.ts
new file mode 100644
index 0000000..0a11166
--- /dev/null
+++ b/catalog-ui/src/app/ng2/services/window.service.ts
@@ -0,0 +1,8 @@
+import {Injectable} from "@angular/core";
+
+@Injectable()
+export class WindowRef {
+ get nativeWindow(): any {
+ return window;
+ }
+}
diff --git a/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.html b/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.html
new file mode 100644
index 0000000..c9f59f0
--- /dev/null
+++ b/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.html
@@ -0,0 +1,6 @@
+<div class="multiline-ellipsis-container" [ngClass]="className" [ngStyle]="stylesContainer" #multilineEllipsisContainer>
+ <div class="multiline-ellipsis-content" [ngStyle]="stylesContent" #multilineEllipsisContent>
+ <ng-content></ng-content>
+ <div class="multiline-ellipsis-dots" [ngStyle]="stylesDots"></div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.less b/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.less
new file mode 100644
index 0000000..c616d37
--- /dev/null
+++ b/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.less
@@ -0,0 +1,25 @@
+.multiline-ellipsis-container {
+ position: relative;
+ display: block;
+ overflow: hidden;
+ white-space: normal;
+ //max-height: @num_lines * @line_height;
+
+ .multiline-ellipsis-content {
+ word-break: break-all;
+ position: relative;
+ //max-height: (@num_lines + 1) * @line_height;
+
+ .multiline-ellipsis-dots {
+ display: block;
+ position: absolute;
+ right: 0;
+ //top: calc(#{@num_lines * 2} - 100%);
+
+ &::before {
+ display: block;
+ content: '...';
+ }
+ }
+ }
+}
diff --git a/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.ts b/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.ts
new file mode 100644
index 0000000..68cfedb
--- /dev/null
+++ b/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.ts
@@ -0,0 +1,58 @@
+import {Component, OnChanges, AfterViewChecked, ViewChild, ElementRef, Input, Output, SimpleChanges, EventEmitter} from "@angular/core";
+import {WindowRef} from "../../services/window.service";
+
+@Component({
+ selector: 'multiline-ellipsis',
+ templateUrl: 'multiline-ellipsis.component.html',
+ styleUrls: ['multiline-ellipsis.component.less']
+})
+export class MultilineEllipsisComponent implements OnChanges, AfterViewChecked {
+
+ @Input() public lines: number;
+ @Input() public lineHeight: string;
+ @Input() public className: string;
+ @Output() public hasEllipsisChanged: EventEmitter<boolean>;
+
+ @ViewChild('multilineEllipsisContainer') public elmContainer: ElementRef;
+ @ViewChild('multilineEllipsisContent') public elmContent: ElementRef;
+
+ public stylesContainer: {[key: string]: string};
+ public stylesContent: {[key: string]: string};
+ public stylesDots: {[key: string]: string};
+
+ private hasEllipsis: boolean;
+
+ public constructor(private windowRef: WindowRef) {
+ this.hasEllipsisChanged = new EventEmitter<boolean>();
+ }
+
+ public ngOnChanges(changes: SimpleChanges) {
+ this.prepareStyles()
+ }
+
+ public ngAfterViewChecked() {
+ const hasEllipsis = (this.elmContainer.nativeElement.offsetHeight < this.elmContent.nativeElement.offsetHeight);
+ if (hasEllipsis !== this.hasEllipsis) {
+ this.hasEllipsis = hasEllipsis;
+ this.hasEllipsisChanged.emit(this.hasEllipsis);
+ }
+ }
+
+ private prepareStyles() {
+ const lineHeight = this.lineHeight || this.getLineHeight();
+ this.stylesContainer = {
+ 'max-height': `calc(${this.lines} * ${lineHeight})`
+ };
+ this.stylesContent = {
+ 'max-height': `calc(${this.lines + 1} * ${lineHeight})`
+ };
+ this.stylesDots = {
+ 'top': `calc(${2 * this.lines} * ${lineHeight} - 100%)`
+ };
+ }
+
+ private getLineHeight() {
+ return this.windowRef.nativeWindow.getComputedStyle(this.elmContainer.nativeElement)['line-height'];
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.module.ts b/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.module.ts
new file mode 100644
index 0000000..24ed7b3
--- /dev/null
+++ b/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.module.ts
@@ -0,0 +1,11 @@
+import {NgModule} from '@angular/core';
+import {CommonModule} from '@angular/common';
+import {MultilineEllipsisComponent} from './multiline-ellipsis.component';
+
+@NgModule({
+ declarations: [MultilineEllipsisComponent],
+ imports: [CommonModule],
+ exports: [MultilineEllipsisComponent],
+ entryComponents: [MultilineEllipsisComponent]
+})
+export class MultilineEllipsisModule {}
diff --git a/catalog-ui/src/app/ng2/utils/ng1-upgraded-provider.ts b/catalog-ui/src/app/ng2/utils/ng1-upgraded-provider.ts
index c005efc..fcb21c0 100644
--- a/catalog-ui/src/app/ng2/utils/ng1-upgraded-provider.ts
+++ b/catalog-ui/src/app/ng2/utils/ng1-upgraded-provider.ts
@@ -21,12 +21,14 @@
/**
* Created by rc2122 on 4/6/2017.
*/
-import {DataTypesService} from "../../services/data-types-service";
+import { DataTypesService } from "../../services/data-types-service";
import ICacheObject = angular.ICacheObject;
-import {SharingService} from "../../services/sharing-service";
-import {CookieService} from "../../services/cookie-service";
-import {CacheService} from "../../services/cache-service";
-import {EventListenerService} from "app/services/event-listener-service";
+import { SharingService } from "../../services/sharing-service";
+import { CookieService } from "../../services/cookie-service";
+import { CacheService } from "../../services/cache-service";
+import {ComponentFactory} from "../../utils/component-factory"
+import { EventListenerService } from "app/services/event-listener-service";
+import { ModalsHandler } from "app/utils";
import IScope = angular.IScope;
/** Services we need to upgrade from angular1 to angular2 - in the future we need to rewrite them all to angular2 **/
@@ -39,6 +41,10 @@
return cacheObj.get('Sdc.Services.SharingService');
}
+export function componentServiceFactory(cacheObj: ICacheObject) {
+ return cacheObj.get('Sdc.Services.ComponentFactory');
+}
+
export function cookieServiceFactory(cacheObj: ICacheObject) {
return cacheObj.get('Sdc.Services.CookieService');
}
@@ -47,14 +53,14 @@
return cacheObj.get('$state');
}
-export function scopeServiceFactory(cacheObj: ICacheObject) {
- return cacheObj.get('$scope');
-}
-
export function stateParamsServiceFactory(cacheObj: ICacheObject) {
return cacheObj.get('$stateParams');
}
+export function scopeServiceFactory(cacheObj: ICacheObject) {
+ return cacheObj.get('$scope');
+}
+
export function cacheServiceFactory(cacheObj: ICacheObject) {
return cacheObj.get('Sdc.Services.CacheService');
}
@@ -67,6 +73,18 @@
return cacheObj.get('Notification');
}
+
+export const ComponentFactoryProvider = {
+ provide: ComponentFactory,
+ useFactory: componentServiceFactory,
+ deps: ['$injector']
+};
+
+
+export function ModalsHandlerFactory(cacheObj: ICacheObject) {
+ return cacheObj.get('ModalsHandler');
+}
+
export const DataTypesServiceProvider = {
provide: DataTypesService,
useFactory: dataTypesServiceFactory,
@@ -93,7 +111,7 @@
deps: ['$injector']
};
-export const ScopeServiceFactory= {
+export const ScopeServiceFactory = {
provide: '$scope',
useFactory: scopeServiceFactory,
deps: ['$injector']
@@ -104,7 +122,6 @@
useFactory: stateParamsServiceFactory,
deps: ['$injector']
};
-
export const CacheServiceProvider = {
provide: CacheService,
useFactory: cacheServiceFactory,
@@ -122,3 +139,9 @@
useFactory: notificationServiceFactory,
deps: ['$injector']
};
+
+export const ModalsHandlerProvider = {
+ provide: ModalsHandler,
+ useFactory: ModalsHandlerFactory,
+ deps: ['$injector']
+}
diff --git a/catalog-ui/src/app/services/components/component-service.ts b/catalog-ui/src/app/services/components/component-service.ts
index 0b68c8b..25203e7 100644
--- a/catalog-ui/src/app/services/components/component-service.ts
+++ b/catalog-ui/src/app/services/components/component-service.ts
@@ -7,9 +7,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -107,7 +107,7 @@
};
public getComponent = (id:string):ng.IPromise<Component> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Component>();
this.restangular.one(id).get().then((response:Component) => {
let component:Component = this.createComponentObject(response);
//console.log("Component Loaded successfully : ", component);
@@ -141,7 +141,7 @@
};
private updateService = (component:Component):ng.IPromise<Component> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Component>();
this.restangular.one(component.uniqueId).one("metadata").customPUT(JSON.stringify(component)).then((response:Component) => {
let component:Component = this.createComponentObject(response);
deferred.resolve(component);
@@ -152,7 +152,7 @@
};
private updateResource = (component:Component):ng.IPromise<Component> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Component>();
this.restangular.one(component.uniqueId).customPUT(JSON.stringify(component)).then((response:Component) => {
let component:Component = this.createComponentObject(response);
deferred.resolve(component);
@@ -163,7 +163,7 @@
};
private updateResourceMetadata = (component:Component):ng.IPromise<Component> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Component>();
this.restangular.one(component.uniqueId).one('metadata').customPUT(JSON.stringify(component)).then((response:Component) => {
let component:Component = this.createComponentObject(response);
deferred.resolve(component);
@@ -179,7 +179,7 @@
* @returns {IPromise<T>}
*/
private updateResourceWithPayload = (resource:Resource):ng.IPromise<Component> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Component>();
resource.payloadData = resource.importedFile.base64;
resource.payloadName = resource.importedFile.filename;
@@ -196,7 +196,7 @@
};
public createComponent = (component:Component):ng.IPromise<Component> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Component>();
let headerObj = this.getHeaderMd5(component);
this.restangular.customPOST(JSON.stringify(component), '', {}, headerObj).then((response:Component) => {
let component:Component = this.createComponentObject(response);
@@ -208,7 +208,7 @@
};
public validateName = (newName:string, subtype?:string):ng.IPromise<IValidate> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<IValidate>();
this.restangular.one("validate-name").one(newName).get({'subtype': subtype}).then((response:any) => {
deferred.resolve(response.plain());
}, (err)=> {
@@ -218,7 +218,7 @@
};
public changeLifecycleState = (component:Component, state:string, userRemarks:any):ng.IPromise<ComponentMetadata> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ComponentMetadata>();
this.restangular.one(component.uniqueId).one(state).customPOST(userRemarks).then((response:ComponentMetadata) => {
this.sharingService.addUuidValue(response.uniqueId, response.uuid);
let component:ComponentMetadata = new ComponentMetadata().deserialize(response);
@@ -226,13 +226,12 @@
}, (err)=> {
deferred.reject(err);
});
-
return deferred.promise;
};
// ------------------------------------------------ Artifacts API --------------------------------------------------//
public addOrUpdateArtifact = (componentId:string, artifact:ArtifactModel):ng.IPromise<ArtifactModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ArtifactModel>();
let headerObj = {};
if (artifact.payloadData) {
headerObj = this.getHeaderMd5(artifact);
@@ -246,7 +245,7 @@
};
public downloadArtifact = (componentId:string, artifactId:string):ng.IPromise<IFileDownload> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<IFileDownload>();
this.restangular.one(componentId).one("artifacts").one(artifactId).get().then((response:any) => {
deferred.resolve(response.plain());
}, (err)=> {
@@ -256,7 +255,7 @@
};
public deleteArtifact = (componentId:string, artifactId:string, artifactLabel:string):ng.IPromise<ArtifactModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ArtifactModel>();
this.restangular.one(componentId).one("artifacts").one(artifactId).remove({'operation': artifactLabel}).then((response:ArtifactModel) => {
deferred.resolve(response);
}, (err)=> {
@@ -266,7 +265,7 @@
};
public getArtifactByGroupType = (componentId:string, artifactGroupType:string):ng.IPromise<ArtifactGroupModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ArtifactGroupModel>();
this.restangular.one(componentId).one("artifactsByType").one(artifactGroupType).get().then((response:any) => {
var artifacts:ArtifactGroupModel = new ArtifactGroupModel(response.plain());
deferred.resolve(artifacts);
@@ -277,7 +276,7 @@
};
public getComponentInstanceArtifactsByGroupType = (componentId:string, componentInstanceId:string, artifactGroupType:string):ng.IPromise<ArtifactGroupModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ArtifactGroupModel>();
this.restangular.one(componentId).one("resourceInstances").one(componentInstanceId).one("artifactsByType").one(artifactGroupType).get().then((response:any) => {
var artifacts:ArtifactGroupModel = new ArtifactGroupModel(response.plain());
deferred.resolve(artifacts);
@@ -290,7 +289,7 @@
// ------------------------------------------------ Properties API --------------------------------------------------//
public addProperty = (componentId:string, property:PropertyModel):ng.IPromise<PropertyModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<PropertyModel>();
this.restangular.one(componentId).one("properties").customPOST(property.convertToServerObject()).then((response:any) => {
let property:PropertyModel = new PropertyModel(response[Object.keys(response)[0]]);
deferred.resolve(property);
@@ -301,7 +300,7 @@
};
public updateProperty = (componentId:string, property:PropertyModel):ng.IPromise<PropertyModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<PropertyModel>();
this.restangular.one(componentId).one("properties").one(property.uniqueId).customPUT(property.convertToServerObject()).then((response:any) => {
let property:PropertyModel = new PropertyModel(response[Object.keys(response)[0]]);
deferred.resolve(property);
@@ -312,7 +311,7 @@
};
public deleteProperty = (componentId:string, propertyId:string):ng.IPromise<PropertyModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<PropertyModel>();
this.restangular.one(componentId).one("properties").one(propertyId).remove().then((response:any) => {
deferred.resolve(response);
}, (err)=> {
@@ -323,7 +322,7 @@
// ------------------------------------------------ Attributes API --------------------------------------------------//
public addAttribute = (componentId:string, attribute:AttributeModel):ng.IPromise<AttributeModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<AttributeModel>();
this.restangular.one(componentId).one("attributes").customPOST(attribute.convertToServerObject()).then((response:any) => {
let attribute:AttributeModel = new AttributeModel(response);
deferred.resolve(attribute);
@@ -334,7 +333,7 @@
};
public updateAttribute = (componentId:string, attribute:AttributeModel):ng.IPromise<AttributeModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<AttributeModel>();
this.restangular.one(componentId).one("attributes").one(attribute.uniqueId).customPUT(attribute.convertToServerObject()).then((response:any) => {
let attribute:AttributeModel = new AttributeModel(response);
deferred.resolve(attribute);
@@ -345,7 +344,7 @@
};
public deleteAttribute = (componentId:string, attributeId:string):ng.IPromise<AttributeModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<AttributeModel>();
this.restangular.one(componentId).one("attributes").one(attributeId).remove().then((response:any) => {
deferred.resolve(response);
}, (err)=> {
@@ -357,7 +356,7 @@
// ------------------------------------------------ Component Instances API --------------------------------------------------//
public createComponentInstance = (componentId:string, componentInstance:ComponentInstance):ng.IPromise<ComponentInstance> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ComponentInstance>();
this.restangular.one(componentId).one("resourceInstance").customPOST(JSON.stringify(componentInstance)).then((response:any) => {
let componentInstance:ComponentInstance = ComponentInstanceFactory.createComponentInstance(response);
console.log("Component Instance created", componentInstance);
@@ -370,7 +369,7 @@
};
public updateComponentInstance = (componentId:string, componentInstance:ComponentInstance):ng.IPromise<ComponentInstance> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ComponentInstance>();
this.restangular.one(componentId).one("resourceInstance").one(componentInstance.uniqueId).customPOST(JSON.stringify(componentInstance)).then((response:any) => {
let componentInstance:ComponentInstance = ComponentInstanceFactory.createComponentInstance(response);
console.log("Component Instance was updated", componentInstance);
@@ -383,7 +382,7 @@
};
public updateMultipleComponentInstances = (componentId:string, instances:Array<ComponentInstance>):ng.IPromise<Array<ComponentInstance>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<ComponentInstance>>();
this.restangular.one(componentId).one("resourceInstance/multipleComponentInstance").customPOST(JSON.stringify(instances)).then((response:any) => {
console.log("Multiple Component Instances was updated", response);
let updateInstances:Array<ComponentInstance> = new Array<ComponentInstance>();
@@ -400,7 +399,7 @@
};
public deleteComponentInstance = (componentId:string, componentInstanceId:string):ng.IPromise<ComponentInstance> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ComponentInstance>();
this.restangular.one(componentId).one("resourceInstance").one(componentInstanceId).remove().then(() => {
console.log("Component Instance was deleted");
deferred.resolve();
@@ -412,7 +411,7 @@
};
public checkResourceInstanceVersionChange = (componentId:string, componentInstanceId:string, componentUid:string):ng.IPromise<ComponentInstance> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ComponentInstance>();
this.restangular.one(componentId).one("resourceInstance").one(componentInstanceId).one(componentUid).one("checkForwardingPathOnVersionChange").get().then((response:any) => {
deferred.resolve(response);
}, err => {
@@ -422,7 +421,7 @@
};
public changeResourceInstanceVersion = (componentId:string, componentInstanceId:string, componentUid:string):ng.IPromise<ComponentInstance> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ComponentInstance>();
this.restangular.one(componentId).one("resourceInstance").one(componentInstanceId).one("changeVersion").customPOST({'componentUid': componentUid}).then((response:any) => {
let componentInstance:ComponentInstance = ComponentInstanceFactory.createComponentInstance(response);
deferred.resolve(componentInstance);
@@ -433,7 +432,7 @@
};
public downloadInstanceArtifact = (componentId:string, instanceId:string, artifactId:string):ng.IPromise<IFileDownload> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<IFileDownload>();
this.restangular.one(componentId).one("resourceInstances").one(instanceId).one("artifacts").one(artifactId).get().then((response:any) => {
deferred.resolve(response.plain());
}, (err)=> {
@@ -443,7 +442,7 @@
};
public updateInstanceArtifact = (componentId:string, instanceId:string, artifact:ArtifactModel):ng.IPromise<ArtifactModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ArtifactModel>();
let headerObj = {};
if (artifact.payloadData) {
headerObj = this.getHeaderMd5(artifact);
@@ -458,7 +457,7 @@
};
public addInstanceArtifact = (componentId:string, instanceId:string, artifact:ArtifactModel):ng.IPromise<ArtifactModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ArtifactModel>();
let headerObj = {};
if (artifact.payloadData) {
headerObj = this.getHeaderMd5(artifact);
@@ -473,7 +472,7 @@
};
public deleteInstanceArtifact = (componentId:string, instanceId:string, artifactId:string, artifactLabel:string):ng.IPromise<ArtifactModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ArtifactModel>();
this.restangular.one(componentId).one("resourceInstance").one(instanceId).one("artifacts").one(artifactId).remove({'operation': artifactLabel}).then((response:ArtifactModel) => {
deferred.resolve(response);
}, (err)=> {
@@ -483,7 +482,7 @@
};
public uploadInstanceEnvFile = (componentId:string, instanceId:string, artifact:ArtifactModel):ng.IPromise<ArtifactModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<ArtifactModel>();
let headerObj = {};
if (artifact.payloadData) {
headerObj = this.getHeaderMd5(artifact);
@@ -514,7 +513,7 @@
};
public updateInstanceAttribute = (componentId:string, attribute:AttributeModel):ng.IPromise<AttributeModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<AttributeModel>();
let instanceId = attribute.resourceInstanceUniqueId;
this.restangular.one(componentId).one("resourceInstance").one(instanceId).one("attribute").customPOST(JSON.stringify(attribute)).then((response:any) => {
let newAttribute = new AttributeModel(response);
@@ -528,7 +527,7 @@
};
public createRelation = (componentId:string, link:RelationshipModel):ng.IPromise<RelationshipModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<RelationshipModel>();
const linkPayload:RelationshipModel = new RelationshipModel(link);
linkPayload.relationships.forEach((rel) => {
delete rel.capability;
@@ -546,7 +545,7 @@
};
public deleteRelation = (componentId:string, link:RelationshipModel):ng.IPromise<RelationshipModel> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<RelationshipModel>();
const linkPayload:RelationshipModel = new RelationshipModel(link);
linkPayload.relationships.forEach((rel) => {
delete rel.capability;
@@ -589,7 +588,7 @@
};
public getModuleForDisplay = (componentId:string, moduleId:string):ng.IPromise<DisplayModule> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<DisplayModule>();
this.restangular.one(componentId).one("groups").one(moduleId).get().then((response:any) => {
console.log("module loaded successfully: ", response);
let module:DisplayModule = new DisplayModule(response);
@@ -601,8 +600,8 @@
return deferred.promise;
};
- public getComponentInstanceModule = (componentId:string, componentInstanceId:string, moduleId:string):ng.IPromise<Module> => {
- let deferred = this.$q.defer();
+ public getComponentInstanceModule = (componentId:string, componentInstanceId:string, moduleId:string):ng.IPromise<DisplayModule> => {
+ let deferred = this.$q.defer<DisplayModule>();
this.restangular.one(componentId).one("resourceInstance").one(componentInstanceId).one("groupInstance").one(moduleId).get().then((response:any) => {
console.log("module loaded successfully: ", response);
let module:DisplayModule = new DisplayModule(response);
@@ -615,7 +614,7 @@
};
public getComponentInstancesFilteredByInputsAndProperties = (componentId:string, searchText?:string):ng.IPromise<Array<ComponentInstance>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<ComponentInstance>>();
this.restangular.one(componentId).one("componentInstances").get({'searchText': searchText}).then((response:any) => {
console.log("component instances return successfully: ", response);
let componentInstances:Array<ComponentInstance> = CommonUtils.initComponentInstances(response);
@@ -630,7 +629,7 @@
public getComponentInstanceInputs = (componentId:string, instanceId:string, originComponentUid):ng.IPromise<Array<InputModel>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<InputModel>>();
this.restangular.one(componentId).one("componentInstances").one(instanceId).one(originComponentUid).one("inputs").get().then((response:any) => {
console.log("component instance input return successfully: ", response);
let inputsArray:Array<InputModel> = new Array<InputModel>();
@@ -648,7 +647,7 @@
public getComponentInputs = (componentId:string):ng.IPromise<Array<InputModel>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<InputModel>>();
this.restangular.one(componentId).one("inputs").get().then((response:any) => {
console.log("component inputs return successfully: ", response);
let inputsArray:Array<InputModel> = new Array<InputModel>();
@@ -666,7 +665,7 @@
public getComponentInstanceInputProperties = (componentId:string, instanceId:string, inputId:string):ng.IPromise<Array<PropertyModel>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<PropertyModel>>();
this.restangular.one(componentId).one("componentInstances").one(instanceId).one(inputId).one("properties").get().then((response:any) => {
console.log("component instance input properties return successfully: ", response);
let propertiesArray:Array<PropertyModel> = new Array<PropertyModel>();
@@ -685,7 +684,7 @@
public getComponentInstanceProperties = (componentId:string, instanceId:string):ng.IPromise<Array<PropertyModel>> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Array<PropertyModel>>();
this.restangular.one(componentId).one("componentInstances").one(instanceId).one("properties").get().then((response:any) => {
console.log("component instance properties return successfully: ", response);
let propertiesArray:Array<PropertyModel> = new Array<PropertyModel>();
@@ -703,7 +702,7 @@
public updateGroupMetadata = (componentId:string, group:Module):ng.IPromise<Module> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Module>();
this.restangular.one(componentId).one("groups").one(group.uniqueId).one("metadata").customPUT(JSON.stringify(group)).then((response:Module) => {
console.log("group metadata updated successfully: ", response);
let updatedGroup:Module = new Module(response);
@@ -718,7 +717,7 @@
};
public getComponentInputInputsAndProperties = (serviceId:string, inputId:string):ng.IPromise<InputsAndProperties> => {
- let defer = this.$q.defer<any>();
+ let defer = this.$q.defer<InputsAndProperties>();
this.restangular.one(serviceId).one("inputs").one(inputId).get().then((response:InputsAndProperties) => {
let inputsArray:Array<InputModel> = new Array<InputModel>();
@@ -740,7 +739,7 @@
};
createInputsFromInstancesInputsProperties = (resourceId:string, instancePropertyMap:InstancesInputsPropertiesMap):ng.IPromise<Array<PropertyModel>> => {
- let defer = this.$q.defer<any>();
+ let defer = this.$q.defer<Array<PropertyModel>>();
this.restangular.one(resourceId).one("create/properties").customPOST(instancePropertyMap).then((response:any) => {
let inputsArray:Array<PropertyModel> = new Array<PropertyModel>();
_.forEach(response, (inputObj:PropertyModel) => {
@@ -755,7 +754,7 @@
};
createInputsFromInstancesInputs = (serviceId:string, instancesMap:InstancesInputsPropertiesMap):ng.IPromise<Array<InputModel>> => {
- let defer = this.$q.defer<any>();
+ let defer = this.$q.defer<Array<InputModel>>();
this.restangular.one(serviceId).one("create/inputs").customPOST(instancesMap).then((response:any) => {
let inputsArray:Array<InputModel> = new Array<InputModel>();
_.forEach(response, (inputObj:InputModel) => {
@@ -770,7 +769,7 @@
};
deleteComponentInput = (serviceId:string, inputId:string):ng.IPromise<InputModel> => {
- let defer = this.$q.defer();
+ let defer = this.$q.defer<InputModel>();
this.restangular.one(serviceId).one("delete").one(inputId).one("input").remove().then((response:any) => {
let inputToDelete = new InputModel(response);
defer.resolve(inputToDelete);
diff --git a/catalog-ui/src/app/services/components/resource-service.ts b/catalog-ui/src/app/services/components/resource-service.ts
index 15ef51e..cb30107 100644
--- a/catalog-ui/src/app/services/components/resource-service.ts
+++ b/catalog-ui/src/app/services/components/resource-service.ts
@@ -7,9 +7,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/catalog-ui/src/app/services/components/service-service.ts b/catalog-ui/src/app/services/components/service-service.ts
index cce0759..f258c7b 100644
--- a/catalog-ui/src/app/services/components/service-service.ts
+++ b/catalog-ui/src/app/services/components/service-service.ts
@@ -7,9 +7,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/catalog-ui/src/app/services/components/utils/composition-left-palette-service.ts b/catalog-ui/src/app/services/components/utils/composition-left-palette-service.ts
index 2ed995c..99be788 100644
--- a/catalog-ui/src/app/services/components/utils/composition-left-palette-service.ts
+++ b/catalog-ui/src/app/services/components/utils/composition-left-palette-service.ts
@@ -33,17 +33,6 @@
import {PolicyMetadata, PolicyTpes} from "app/models/policy-metadata";
import {Resource} from "app/models/components/resource";
-// export class LeftPaletteDataObject {
-// displayLeftPanelComponents:Array<LeftPaletteComponent>;
-// onFinishLoadingEvent:string;
-
-// constructor(onFinishEventListener:string) {
-
-// this.displayLeftPanelComponents = new Array<LeftPaletteComponent>();
-// this.onFinishLoadingEvent = onFinishEventListener;
-// }
-// }
-
export class LeftPaletteLoaderService {
static '$inject' = [
@@ -65,56 +54,39 @@
}
- // private serviceLeftPaletteData:LeftPaletteDataObject;
- // private resourceLeftPaletteData:LeftPaletteDataObject;
- // private resourcePNFLeftPaletteData:LeftPaletteDataObject;
- // private vlData:LeftPaletteDataObject;
leftPanelComponents:Array<LeftPaletteComponent>;
public loadLeftPanel = (component:Component):void => {
- // this.serviceLeftPaletteData = new LeftPaletteDataObject(EVENTS.SERVICE_LEFT_PALETTE_UPDATE_EVENT);
- // this.resourceLeftPaletteData = new LeftPaletteDataObject(EVENTS.RESOURCE_LEFT_PALETTE_UPDATE_EVENT);
- // this.resourcePNFLeftPaletteData = new LeftPaletteDataObject(EVENTS.RESOURCE_PNF_LEFT_PALETTE_UPDATE_EVENT);
this.leftPanelComponents = [];
this.updateLeftPaletteForTopologyTemplate(component);
}
- // private getResourceLeftPaletteDataByResourceType = (resourceType:string):LeftPaletteDataObject => {
- // if(resourceType == ResourceType.PNF) {
- // return this.resourcePNFLeftPaletteData;
- // }
- // return this.resourceLeftPaletteData;
- // }
-
private updateLeftPalette = (componentInternalType:string):void => {
/* add components */
- this.restangular.one("resources").one('/latestversion/notabstract/metadata').get({'internalComponentType': componentInternalType}).then((leftPaletteComponentMetadata:Array<ComponentMetadata>) => {
+ this.restangular.one("resources").one('/latestversion/notabstract/metadata').get({'internalComponentType': componentInternalType}).then((leftPaletteComponentMetadata:Array<ComponentMetadata>) => {
_.forEach(leftPaletteComponentMetadata, (componentMetadata:ComponentMetadata) => {
this.leftPanelComponents.push(new LeftPaletteComponent(LeftPaletteMetadataTypes.Component, componentMetadata));
});
- this.EventListenerService.notifyObservers(EVENTS.LEFT_PALETTE_UPDATE_EVENT);
+
+ /* add groups */
+ this.restangular.one('/groupTypes').get({'internalComponentType': componentInternalType}).then((leftPaletteGroupTypes:GroupTpes) => {
+ _.forEach(leftPaletteGroupTypes, (groupMetadata: GroupMetadata) => {
+ this.leftPanelComponents.push(new LeftPaletteComponent(LeftPaletteMetadataTypes.Group, groupMetadata));
+ });
+ this.EventListenerService.notifyObservers(EVENTS.LEFT_PALETTE_UPDATE_EVENT);
+ });
+
+ /* add policies */
+ this.restangular.one('/policyTypes').get({'internalComponentType': componentInternalType}).then((leftPalettePolicyTypes:PolicyTpes) => {
+ _.forEach(leftPalettePolicyTypes, (policyMetadata: PolicyMetadata) => {
+ this.leftPanelComponents.push(new LeftPaletteComponent(LeftPaletteMetadataTypes.Policy, policyMetadata));
+ });
+ this.EventListenerService.notifyObservers(EVENTS.LEFT_PALETTE_UPDATE_EVENT);
+ });
});
- /* add groups */
- //TODO: In backend implement like this:
- //this.restangular.one("groups").one('/latestversion/notabstract/metadata').get({'internalComponentType': componentInternalType}).then((leftPaletteComponentMetadata:Array<ComponentMetadata>) => {
- this.restangular.one('/groupTypes').get().then((leftPaletteGroupTypes:GroupTpes) => {
- _.forEach(leftPaletteGroupTypes.groupTypes, (groupMetadata: GroupMetadata) => {
- this.leftPanelComponents.push(new LeftPaletteComponent(LeftPaletteMetadataTypes.Group, groupMetadata));
- });
- this.EventListenerService.notifyObservers(EVENTS.LEFT_PALETTE_UPDATE_EVENT);
- });
- /* add policies */
- //TODO: In backend implement like this:
- //this.restangular.one("policies").one('/latestversion/notabstract/metadata').get({'internalComponentType': componentInternalType}).then((leftPaletteComponentMetadata:Array<ComponentMetadata>) => {
- this.restangular.one('/policyTypes').get().then((leftPalettePolicyTypes:PolicyTpes) => {
- _.forEach(leftPalettePolicyTypes.policyTypes, (policyMetadata: PolicyMetadata) => {
- this.leftPanelComponents.push(new LeftPaletteComponent(LeftPaletteMetadataTypes.Policy, policyMetadata));
- });
- this.EventListenerService.notifyObservers(EVENTS.LEFT_PALETTE_UPDATE_EVENT);
- });
}
public getLeftPanelComponentsForDisplay = (component:Component):Array<LeftPaletteComponent> => {
diff --git a/catalog-ui/src/app/services/entity-service.ts b/catalog-ui/src/app/services/entity-service.ts
index b7ac880..2e7b2e1 100644
--- a/catalog-ui/src/app/services/entity-service.ts
+++ b/catalog-ui/src/app/services/entity-service.ts
@@ -19,6 +19,7 @@
*/
'use strict';
+import * as _ from "lodash";
import { Service, IApi, IAppConfigurtaion, Resource, Component} from "../models";
import {SharingService} from "./sharing-service";
import {ComponentFactory} from "../utils/component-factory";
@@ -26,7 +27,7 @@
import {ResourceType} from "app/utils";
interface IEntityService {
- getAllComponents():ng.IPromise<Array<Component>>;
+ getAllComponents(smallObjects?:boolean):ng.IPromise<Array<Component>>;
}
interface IComponentsArray {
@@ -36,6 +37,7 @@
export class EntityService implements IEntityService {
static '$inject' = ['$http', '$q', 'sdcConfig', 'Sdc.Services.SharingService', 'ComponentFactory', 'Sdc.Services.CacheService'];
+ private _smallObjectAttributes = ['uniqueId', 'name', 'componentType', 'resourceType', 'lastUpdateDate', 'lifecycleState', 'distributionStatus', 'icon', 'version'];
private api:IApi;
constructor(private $http:ng.IHttpService,
@@ -66,7 +68,6 @@
this.sharingService.addUuidValue(component.uniqueId, component.uuid);
});
- this.cacheService.set('breadcrumbsComponents', componentsList);
defer.resolve(componentsList);
},(responce) => {
defer.reject(responce);
@@ -74,7 +75,7 @@
return defer.promise;
};
- getAllComponents = ():ng.IPromise<Array<Component>> => {
+ getAllComponents = (smallObjects?:boolean):ng.IPromise<Array<Component>> => {
let defer = this.$q.defer<Array<Component>>();
this.$http.get(this.api.root + this.api.GET_element)
.then((response:any) => {
@@ -82,18 +83,19 @@
let componentsList:Array<Component> = [];
componentResponse.services && componentResponse.services.forEach((serviceResponse:Service) => {
+ serviceResponse = (smallObjects) ? _.pick(serviceResponse, this._smallObjectAttributes) : serviceResponse;
let component:Service = this.ComponentFactory.createService(serviceResponse);
componentsList.push(component);
this.sharingService.addUuidValue(component.uniqueId, component.uuid);
});
componentResponse.resources && componentResponse.resources.forEach((resourceResponse:Resource) => {
+ resourceResponse = (smallObjects) ? _.pick(resourceResponse, this._smallObjectAttributes) : resourceResponse;
let component:Resource = this.ComponentFactory.createResource(resourceResponse);
componentsList.push(component);
this.sharingService.addUuidValue(component.uniqueId, component.uuid);
});
- this.cacheService.set('breadcrumbsComponents', componentsList);
defer.resolve(componentsList);
});
diff --git a/catalog-ui/src/app/services/http-error-interceptor.ts b/catalog-ui/src/app/services/http-error-interceptor.ts
index b1aa16a..cef8c30 100644
--- a/catalog-ui/src/app/services/http-error-interceptor.ts
+++ b/catalog-ui/src/app/services/http-error-interceptor.ts
@@ -92,7 +92,7 @@
// Format the message %1 %2
text = text.format(variables);
- // Need to inject the MessageService manually to prevent circular dependencies (because MessageService use $templateCache that use $http).
+ // Need to inject the MessageService manually to prevent circular componentsToUpgrade (because MessageService use $templateCache that use $http).
data = {
title: 'Error',
message: text,
@@ -101,7 +101,7 @@
severity: SEVERITY.ERROR
};
} else {
- // Need to inject the MessageService manually to prevent circular dependencies (because MessageService use $templateCache that use $http).
+ // Need to inject the MessageService manually to prevent circular componentsToUpgrade (because MessageService use $templateCache that use $http).
data = {
title: 'Error',
message: rejection.status !== -1 ? rejection.statusText : "Error getting response from server",
diff --git a/catalog-ui/src/app/utils/common-utils.ts b/catalog-ui/src/app/utils/common-utils.ts
index 1868550..d215183 100644
--- a/catalog-ui/src/app/utils/common-utils.ts
+++ b/catalog-ui/src/app/utils/common-utils.ts
@@ -23,6 +23,7 @@
import {ComponentInstanceFactory} from "./component-instance-factory";
import {InputBEModel, PropertyBEModel, RelationshipModel} from "app/models";
import { PolicyInstance } from "app/models/graph/zones/policy-instance";
+import { GroupInstance } from "../models/graph/zones/group-instance";
export class CommonUtils {
@@ -126,6 +127,17 @@
return policies;
}
+ static initGroups = (groupsObj: Array<GroupInstance>):Array<GroupInstance> => {
+ let groups = new Array<GroupInstance>();
+
+ if(groupsObj) {
+ _.forEach(groupsObj, (group: GroupInstance):void => {
+ groups.push(new GroupInstance(group));
+ });
+ }
+
+ return groups;
+ }
static initInterfaceOperations(interfaces: any): Array<OperationModel> {
diff --git a/catalog-ui/src/app/utils/component-factory.ts b/catalog-ui/src/app/utils/component-factory.ts
index bf4f23b..bdcfc2c 100644
--- a/catalog-ui/src/app/utils/component-factory.ts
+++ b/catalog-ui/src/app/utils/component-factory.ts
@@ -73,9 +73,11 @@
public updateComponentFromCsar = (csarComponent:Resource, oldComponent:Resource):Component => {
_.pull(oldComponent.tags, oldComponent.name);
- oldComponent.name = csarComponent.name;
- oldComponent.selectedCategory = csarComponent.selectedCategory;
- oldComponent.categories = csarComponent.categories;
+ if (!oldComponent.isAlreadyCertified()) {
+ oldComponent.name = csarComponent.name;
+ oldComponent.categories = csarComponent.categories;
+ oldComponent.selectedCategory = csarComponent.selectedCategory;
+ }
oldComponent.vendorName = csarComponent.vendorName;
oldComponent.vendorRelease = csarComponent.vendorRelease;
oldComponent.csarUUID = csarComponent.csarUUID;
@@ -177,7 +179,7 @@
};
public getComponentWithMetadataFromServer = (componentType:string, componentId:string):ng.IPromise<Component> => {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<Component>();
let component = this.createEmptyComponent(componentType);
component.setUniqueId(componentId);
this.ComponentServiceNg2.getComponentMetadata(component).subscribe((response:ComponentGenericResponse) => {
diff --git a/catalog-ui/src/app/utils/constants.ts b/catalog-ui/src/app/utils/constants.ts
index 9665999..b0f22ac 100644
--- a/catalog-ui/src/app/utils/constants.ts
+++ b/catalog-ui/src/app/utils/constants.ts
@@ -25,6 +25,13 @@
export let DEFAULT_ICON = 'defaulticon';
export let CP_END_POINT = 'CpEndPoint';
export let CHANGE_COMPONENT_CSAR_VERSION_FLAG = 'changeComponentCsarVersion';
+export let PREVIOUS_CSAR_COMPONENT = 'previousCsarComponent'
+
+
+export class GeneralStatus {
+ static OK = 'OK';
+ static GENERAL_ERROR = 'GENERAL_ERROR';
+}
export class ComponentType {
static SERVICE = 'SERVICE';
@@ -144,6 +151,11 @@
VIEW
}
+export class instantiationType {
+ public static MACRO = 'Macro';
+ public static A_LA_CARTE = 'A-la-carte';
+}
+
export class WorkspaceMode {
public static CREATE = 'create';
public static EDIT = 'edit';
@@ -159,6 +171,9 @@
public static SELECTED_CP_INSTANCE = '/assets/styles/images/resource-icons/selectedCPInstance.png';
public static SELECTED_VL_INSTANCE = '/assets/styles/images/resource-icons/selectedVLInstance.png';
public static CANVAS_PLUS_ICON = '/assets/styles/images/resource-icons/canvasPlusIcon.png';
+ public static CANVAS_TAG_ICON = '/assets/styles/images/canvas-tagging-icons/indication.svg';
+ public static CANVAS_POLICY_TAGGED_ICON = '/assets/styles/images/canvas-tagging-icons/policy_added.svg';
+ public static CANVAS_GROUP_TAGGED_ICON = '/assets/styles/images/canvas-tagging-icons/group_added.svg';
public static MODULE_ICON = '/assets/styles/images/resource-icons/module.png';
public static OPEN_MODULE_ICON = '/assets/styles/images/resource-icons/openModule.png';
public static OPEN_MODULE_HOVER_ICON = '/assets/styles/images/resource-icons/openModuleHover.png';
@@ -166,6 +181,14 @@
public static CLOSE_MODULE_HOVER_ICON = '/assets/styles/images/resource-icons/closeModuleHover.png';
}
+
+export class CanvasHandleTypes {
+ public static ADD_EDGE = 'add-edge';
+ public static TAG_AVAILABLE = 'tag-available';
+ public static TAGGED_POLICY = 'tagged-policy';
+ public static TAGGED_GROUP = 'tagged-group';
+}
+
export class ModalType {
static STANDARD = 'standard';
static ERROR = 'error';
@@ -247,22 +270,21 @@
}
export class EVENTS {
- // static RESOURCE_LEFT_PALETTE_UPDATE_EVENT = "resourceLeftPanelUpdateEvent";
- // static RESOURCE_PNF_LEFT_PALETTE_UPDATE_EVENT = "resourcePNFLeftPanelUpdateEvent";
- // static SERVICE_LEFT_PALETTE_UPDATE_EVENT = "serviceLeftPanelUpdateEvent";
- //static VL_LEFT_PALETTE_UPDATE_EVENT = "vlLeftPanelUdateEvent";
static LEFT_PALETTE_UPDATE_EVENT = "leftPanelUpdateEvent";
static ON_CSAR_LOADING = "onCsarLoading";
static DOWNLOAD_ARTIFACT_FINISH_EVENT = "downloadArtifactFinishEvent";
static ON_WORKSPACE_SAVE_BUTTON_CLICK = "onWorkspaceSaveButtonClick";
static ON_WORKSPACE_SAVE_BUTTON_SUCCESS = "onWorkspaceSaveButtonSuccess";
static ON_WORKSPACE_SAVE_BUTTON_ERROR = "onWorkspaceSaveButtonError";
+ static ON_WORKSPACE_UNSAVED_CHANGES = "onWorkspaceUnsavedChanges";
static ON_CHECKOUT = "onCheckout";
- static ON_REVERT = "onRevert";
+ static ON_LIFECYCLE_CHANGE_WITH_SAVE = "onLifecycleChangeWithSave";
+ static ON_LIFECYCLE_CHANGE = "onCheckout";
//Loader events
static SHOW_LOADER_EVENT = "showLoaderEvent";
static HIDE_LOADER_EVENT = "hideLoaderEvent";
+ static UPDATE_PANEL = 'updatePanel';
}
@@ -282,6 +304,7 @@
static ON_COMPOSITION_GRAPH_DATA_LOADED = 'onCompositionGraphDataLoaded';
static ON_DEPLOYMENT_GRAPH_DATA_LOADED = 'onDeploymentGraphDataLoaded';
static ON_NODE_SELECTED = "onNodeSelected";
+ static ON_ZONE_INSTANCE_SELECTED = "onZoneInstanceSelected";
static ON_GRAPH_BACKGROUND_CLICKED = "onGraphBackgroundClicked";
static ON_PALETTE_COMPONENT_HOVER_IN = 'onPaletteComponentHoverIn';
static ON_PALETTE_COMPONENT_HOVER_OUT = 'onPaletteComponentHoverOut';
@@ -290,16 +313,20 @@
static ON_PALETTE_COMPONENT_SHOW_POPUP_PANEL = 'onPaletteComponentShowPopupPanel';
static ON_PALETTE_COMPONENT_HIDE_POPUP_PANEL = 'onPaletteComponentHidePopupPanel';
static ON_COMPONENT_INSTANCE_NAME_CHANGED = 'onComponentInstanceNameChanged';
+ static ON_ZONE_INSTANCE_NAME_CHANGED = 'onZoneInstanceNameChanged';
static ON_DELETE_COMPONENT_INSTANCE = 'onDeleteComponentInstance';
- static ON_DELETE_MULTIPLE_COMPONENTS = 'onDeleteMultipleComponents';
+ static ON_DELETE_ZONE_INSTANCE = 'onDeleteZoneInstance';
+ static ON_DELETE_COMPONENT_INSTANCE_SUCCESS = 'onDeleteComponentInstanceSuccess';
static ON_DELETE_EDGE = 'onDeleteEdge';
static ON_INSERT_NODE_TO_UCPE = 'onInsertNodeToUCPE';
static ON_REMOVE_NODE_FROM_UCPE = 'onRemoveNodeFromUCPE';
static ON_VERSION_CHANGED = 'onVersionChanged';
static ON_CREATE_COMPONENT_INSTANCE = 'onCreateComponentInstance';
- static ON_ADD_COMPONENT_INSTANCE_ZONE_START = 'onCreateComponentInstanceZone';
- static ON_FINISH_ANIMATION_ZONE = 'onFinishAnimationZone';
- static ON_ZONE_SIZE_CHANGE = 'onZoneSizeChange';
+ static ON_ADD_ZONE_INSTANCE_FROM_PALETTE = 'onAddZoneInstanceFromPalette';
+ static ON_CANVAS_TAG_START = 'onCanvasTagStart';
+ static ON_CANVAS_TAG_END = 'onCanvasTagEnd';
+ static ON_POLICY_INSTANCE_UPDATE = 'onPolicyInstanceUpdate';
+ static ON_GROUP_INSTANCE_UPDATE = 'onGroupInstanceUpdate';
}
@@ -320,6 +347,8 @@
static COMPONENT_POLICIES = "policies";
static COMPONENT_GROUPS = "groups";
static COMPONENT_INTERFACE_OPERATIONS = "interfaces";
+ static COMPONENT_NON_EXCLUDED_GROUPS = "nonExcludedGroups";
+ static COMPONENT_NON_EXCLUDED_POLICIES = "nonExcludedPolicies";
}
export class SERVICE_FIELDS {
@@ -329,3 +358,15 @@
export class API_QUERY_PARAMS {
static INCLUDE = "include";
}
+
+export enum TargetOrMemberType {
+ COMPONENT_INSTANCES,
+ GROUPS
+}
+
+export class CANVAS_TAG_MODE {
+ static POLICY_TAGGING = "policy-tagging";
+ static POLICY_TAGGING_HOVER = "policy-tagging-hover";
+ static GROUP_TAGGING = "group-tagging";
+ static GROUP_TAGGING_HOVER= "group-tagging-hover";
+}
diff --git a/catalog-ui/src/app/utils/menu-handler.ts b/catalog-ui/src/app/utils/menu-handler.ts
index fc6eb20..4c25a02 100644
--- a/catalog-ui/src/app/utils/menu-handler.ts
+++ b/catalog-ui/src/app/utils/menu-handler.ts
@@ -65,7 +65,10 @@
}
public updateSelectedMenuItemText(newText:string) {
- this.menuItems[this.selectedIndex].text = newText;
+ const selectedMenuItem = this.menuItems[this.selectedIndex];
+ if (selectedMenuItem) {
+ this.menuItems[this.selectedIndex].text = newText;
+ }
}
}
@@ -112,7 +115,7 @@
// If not found search by name (name is unique).
if (selectedItemIdx === -1) {
selectedItemIdx = _.findIndex(components, (item:Component) => {
- return item.name === selected.name;
+ return item.name === selected.name && item.componentType === selected.componentType;
});
}
@@ -144,6 +147,22 @@
// menuItem.text = component.name;
result.menuItems.push(menuItem);
});
+
+ result.selectedIndex = this.findBreadcrumbComponentIndex(components, selected);
+
+ // if component does not exist, then add a temporary menu item for the current component
+ if (result.selectedIndex === -1) {
+ let menuItem = new MenuItem(
+ // component.name,
+ selected.getComponentSubType() + ': ' + this.$filter('resourceName')(selected.name),
+ clickItemCallback,
+ null,
+ null,
+ [selected]
+ );
+ result.menuItems.unshift(menuItem);
+ result.selectedIndex = 0;
+ }
}
return result;
};
diff --git a/catalog-ui/src/app/utils/modals-handler.ts b/catalog-ui/src/app/utils/modals-handler.ts
index 48ce487..001d35d 100644
--- a/catalog-ui/src/app/utils/modals-handler.ts
+++ b/catalog-ui/src/app/utils/modals-handler.ts
@@ -36,7 +36,7 @@
openServerMessageModal(data:IServerMessageModalModel):ng.IPromise<any>;
openClientMessageModal(data:IClientMessageModalModel):ng.IPromise<ng.ui.bootstrap.IModalServiceInstance>;
openArtifactModal(artifact:ArtifactModel, component:Component):ng.IPromise<any>;
- openEditPropertyModal(property:PropertyModel, component:Component, filteredProperties:Array<PropertyModel>, isPropertyOwnValue:boolean):ng.IPromise<any>;
+ openEditPropertyModal(property:PropertyModel, component:Component, filteredProperties:Array<PropertyModel>, isPropertyOwnValue:boolean, propertyOwnerType:string, propertyOwnerId:string):ng.IPromise<any>;
}
export class ModalsHandler implements IModalsHandler {
@@ -166,7 +166,7 @@
return deferred.promise;
};
- openOnboadrdingModal = (okButtonText:string, currentCsarUUID?:string):ng.IPromise<any> => {
+ openOnboadrdingModal = (okButtonText:string, currentCsarUUID?:string, currentCsarVersion?:string):ng.IPromise<any> => {
let deferred = this.$q.defer();
let modalOptions:ng.ui.bootstrap.IModalSettings = {
templateUrl: '../view-models/modals/onboarding-modal/onboarding-modal-view.html',
@@ -179,6 +179,9 @@
},
currentCsarUUID: ():string=> {
return currentCsarUUID || null;
+ },
+ currentCsarVersion: ():string=> {
+ return currentCsarVersion || null;
}
}
};
@@ -279,7 +282,7 @@
* @param isPropertyValueOwner - boolean telling if the component is eligible of editing the property
* @returns {IPromise<T>} - Promise telling if the modal has opened or not
*/
- openEditPropertyModal = (property:PropertyModel, component:Component, filteredProperties:Array<PropertyModel>, isPropertyValueOwner:boolean):ng.IPromise<any> => {
+ openEditPropertyModal = (property:PropertyModel, component:Component, filteredProperties:Array<PropertyModel>, isPropertyValueOwner:boolean, propertyOwnerType:string, propertyOwnerId:string):ng.IPromise<any> => {
let deferred = this.$q.defer();
let modalOptions:ng.ui.bootstrap.IModalSettings = {
@@ -300,6 +303,12 @@
},
isPropertyValueOwner: ():boolean => {
return isPropertyValueOwner;
+ },
+ propertyOwnerType: ():string => {
+ return propertyOwnerType;
+ },
+ propertyOwnerId: ():string => {
+ return propertyOwnerId;
}
}
};
diff --git a/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.html b/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.html
index a9df3e6..2196aed 100644
--- a/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.html
+++ b/catalog-ui/src/app/view-models/admin-dashboard/add-category-modal/add-category-modal-view.html
@@ -1,4 +1,4 @@
-<sdc-modal modal="modalInstance"
+<ng1-modal modal="modalInstance"
type="classic"
class="i-sdc-admin-add-category-modal modal-type-confirmation"
header-translate="CREATE_CATEGORY_MODAL_HEADER"
@@ -38,4 +38,4 @@
</form>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/catalog/catalog-view-model.ts b/catalog-ui/src/app/view-models/catalog/catalog-view-model.ts
index 2296aa7..8840afd 100644
--- a/catalog-ui/src/app/view-models/catalog/catalog-view-model.ts
+++ b/catalog-ui/src/app/view-models/catalog/catalog-view-model.ts
@@ -20,11 +20,13 @@
'use strict';
import * as _ from "lodash";
-import {Component, IMainCategory, IGroup, IConfigStatuses, IAppMenu, IAppConfigurtaion, IUserProperties, ISubCategory} from "app/models";
+import {Component, IMainCategory, IGroup, IConfigStatuses, IAppMenu, IAppConfigurtaion, IUserProperties, ISubCategory, ICategoryBase} from "app/models";
import {EntityService, CacheService} from "app/services";
import {ComponentFactory, ResourceType, MenuHandler, ChangeLifecycleStateHandler} from "app/utils";
import {UserService} from "../../ng2/services/user.service";
-
+import {ArchiveService} from "../../ng2/services/archive.service";
+import { ICatalogSelector, CatalogSelectorTypes } from "../../models/catalogSelector";
+import {IConfigStatus} from "../../models/app-config";
interface Checkboxes {
componentTypes:Array<string>;
@@ -38,16 +40,32 @@
// Categories
selectedCategoriesModel:Array<string>;
// Statuses
- selectedStatuses:Array<string>;
+ selectedStatuses:Array<Array<string>>;
}
interface Gui {
isLoading:boolean;
- onResourceSubTypesClick:Function;
+ onComponentSubTypesClick:Function;
onComponentTypeClick:Function;
onCategoryClick:Function;
- onSubcategoryClick:Function;
- onGroupClick:Function;
+ onStatusClick:Function;
+ changeFilterTerm:Function;
+}
+
+interface IFilterParams {
+ components: string[];
+ categories: string[];
+ statuses: (string)[];
+ order: [string, boolean];
+ term: string;
+ active: boolean;
+}
+
+interface ICategoriesMap {
+ [key: string]: {
+ category: ICategoryBase,
+ parent: ICategoryBase
+ }
}
export interface ICatalogViewModelScope extends ng.IScope {
@@ -71,13 +89,22 @@
//this is for UI paging
numberOfItemToDisplay:number;
isAllItemDisplay:boolean;
-
+ catalogFilteredItemsNum:number;
changeLifecycleState(entity:any, state:string):void;
sectionClick (section:string):void;
order(sortBy:string):void;
- getNumOfElements(num:number):string;
+ getElementFoundTitle(num:number):string;
goToComponent(component:Component):void;
raiseNumberOfElementToDisplay():void;
+
+ selectedCatalogItem: ICatalogSelector;
+ catalogSelectorItems: Array<ICatalogSelector>;
+ showCatalogSelector: boolean;
+ catalogAllItems:Array<Component>; /* fake data */
+ elementFoundTitle: string;
+ elementTypeTitle: string;
+
+ selectLeftSwitchItem (item: ICatalogSelector): void;
}
export class CatalogViewModel {
@@ -93,9 +120,20 @@
'Sdc.Services.CacheService',
'ComponentFactory',
'ChangeLifecycleStateHandler',
- 'MenuHandler'
+ 'MenuHandler',
+ 'ArchiveServiceNg2'
];
+ private defaultFilterParams:IFilterParams = {
+ components: [],
+ categories: [],
+ statuses: [],
+ order: ['lastUpdateDate', true],
+ term: '',
+ active: true
+ };
+ private categoriesMap:ICategoriesMap;
+
constructor(private $scope:ICatalogViewModelScope,
private $filter:ng.IFilterService,
private EntityService:EntityService,
@@ -107,64 +145,112 @@
private cacheService:CacheService,
private ComponentFactory:ComponentFactory,
private ChangeLifecycleStateHandler:ChangeLifecycleStateHandler,
- private MenuHandler:MenuHandler) {
+ private MenuHandler:MenuHandler,
+ private ArchiveService:ArchiveService
+ ) {
+ this.initLeftSwitch();
this.initScopeMembers();
+ this.loadFilterParams();
this.initCatalogData(); // Async task to get catalog from server.
this.initScopeMethods();
}
- private initCatalogData = ():void => {
- let onSuccess = (followedResponse:Array<Component>):void => {
- this.$scope.catalogFilterdItems = followedResponse;
- this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.catalogFilterdItems.length;
- this.$scope.categories = this.cacheService.get('serviceCategories').concat(this.cacheService.get('resourceCategories'));
- this.$scope.gui.isLoading = false;
- };
- let onError = ():void => {
- console.info('Failed to load catalog CatalogViewModel::initCatalog');
- this.$scope.gui.isLoading = false;
- };
- this.EntityService.getCatalog().then(onSuccess, onError);
+ private initLeftSwitch = ():void => {
+ this.$scope.showCatalogSelector = false;
+
+ this.$scope.catalogSelectorItems = [
+ {value: CatalogSelectorTypes.Active, title: "Active Items", header: "Active"},
+ {value: CatalogSelectorTypes.Archive, title: "Archive", header: "Archived"}
+ ];
+ // set active items is default
+ this.$scope.selectedCatalogItem = this.$scope.catalogSelectorItems[0];
};
+ private initCatalogData = ():void => {
+ if(this.$scope.selectedCatalogItem.value === CatalogSelectorTypes.Archive){
+ this.getArchiveCatalogItems();
+ } else {
+ this.getActiveCatalogItems();
+ }
+ };
private initScopeMembers = ():void => {
// Gui init
this.$scope.gui = <Gui>{};
- this.$scope.gui.isLoading = true;
this.$scope.numberOfItemToDisplay = 0;
- //this.$scope.categories = this.cacheService.get('categoriesMap');
+ this.$scope.categories = this.cacheService.get('serviceCategories').concat(this.cacheService.get('resourceCategories')).map((cat) => <IMainCategory>cat);
this.$scope.sdcMenu = this.sdcMenu;
this.$scope.confStatus = this.sdcMenu.statuses;
this.$scope.expandedSection = ["type", "category", "status"];
this.$scope.user = this.userService.getLoggedinUser();
this.$scope.catalogMenuItem = this.sdcMenu.catalogMenuItem;
- this.$scope.version = this.cacheService.get('version');
- this.$scope.sortBy = 'lastUpdateDate';
- this.$scope.reverse = true;
-
// Checklist init
this.$scope.checkboxes = <Checkboxes>{};
this.$scope.checkboxes.componentTypes = ['Resource', 'Service'];
this.$scope.checkboxes.resourceSubTypes = ['VF', 'VFC', 'CR', 'PNF', 'CP', 'VL'];
+ this.categoriesMap = this.initCategoriesMap();
+ this.initCheckboxesFilter();
+ this.$scope.version = this.cacheService.get('version');
+ this.$scope.sortBy = 'lastUpdateDate';
+ this.$scope.reverse = true;
+
+ };
+
+ private initCheckboxesFilter() {
// Checkboxes filter init
this.$scope.checkboxesFilter = <CheckboxesFilter>{};
this.$scope.checkboxesFilter.selectedComponentTypes = [];
this.$scope.checkboxesFilter.selectedResourceSubTypes = [];
this.$scope.checkboxesFilter.selectedCategoriesModel = [];
this.$scope.checkboxesFilter.selectedStatuses = [];
+ }
- // this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.catalogFilterdItems.length;
- };
+ private initCategoriesMap(categoriesList?:(ICategoryBase)[], parentCategory:ICategoryBase=null): ICategoriesMap {
+ categoriesList = (categoriesList) ? categoriesList : this.$scope.categories;
+
+ // Init categories map
+ return categoriesList.reduce((acc, cat) => {
+ acc[cat.uniqueId] = {
+ category: cat,
+ parent: parentCategory
+ };
+ const catChildren = ((<IMainCategory>cat).subcategories)
+ ? (<IMainCategory>cat).subcategories
+ : (((<ISubCategory>cat).groupings)
+ ? (<ISubCategory>cat).groupings
+ : null);
+ if (catChildren) {
+ Object.assign(acc, this.initCategoriesMap(catChildren, cat));
+ }
+ return acc;
+ }, <ICategoriesMap>{});
+ }
private initScopeMethods = ():void => {
- this.$scope.sectionClick = (section:string):void => {
- let index:number = this.$scope.expandedSection.indexOf(section);
+ this.$scope.selectLeftSwitchItem = (item: ICatalogSelector): void => {
+
+ if (this.$scope.selectedCatalogItem.value !== item.value) {
+ this.$scope.selectedCatalogItem = item;
+ switch (item.value) {
+ case CatalogSelectorTypes.Active:
+ this.getActiveCatalogItems(true);
+ break;
+
+ case CatalogSelectorTypes.Archive:
+ this.getArchiveCatalogItems(true);
+ break;
+ }
+ this.changeFilterParams({active: (item.value === CatalogSelectorTypes.Active)})
+ }
+ };
+
+ this.$scope.sectionClick = (section: string): void => {
+ let index: number = this.$scope.expandedSection.indexOf(section);
if (index !== -1) {
this.$scope.expandedSection.splice(index, 1);
} else {
@@ -173,13 +259,16 @@
};
- this.$scope.order = (sortBy:string):void => {//default sort by descending last update. default for alphabetical = ascending
- this.$scope.reverse = (this.$scope.sortBy === sortBy) ? !this.$scope.reverse : (sortBy === 'lastUpdateDate') ? true : false;
- this.$scope.sortBy = sortBy;
+ this.$scope.order = (sortBy: string): void => {//default sort by descending last update. default for alphabetical = ascending
+ this.changeFilterParams({
+ order: (this.$scope.filterParams.order[0] === sortBy)
+ ? [sortBy, !this.$scope.filterParams.order[1]]
+ : [sortBy, sortBy === 'lastUpdateDate']
+ });
};
- this.$scope.goToComponent = (component:Component):void => {
+ this.$scope.goToComponent = (component: Component): void => {
this.$scope.gui.isLoading = true;
this.$state.go('workspace.general', {id: component.uniqueId, type: component.componentType.toLowerCase()});
};
@@ -188,11 +277,11 @@
// Will print the number of elements found in catalog
this.$scope.getNumOfElements = (num:number):string => {
if (!num || num === 0) {
- return "No Elements found";
+ return `No <b>${this.$scope.selectedCatalogItem.header}</b> Elements found`;
} else if (num === 1) {
- return "1 Element found";
+ return `1 <b>${this.$scope.selectedCatalogItem.header}</b> Element found`;
} else {
- return num + " Elements found";
+ return num + ` <b>${this.$scope.selectedCatalogItem.header}</b> Elements found`;
}
};
@@ -200,124 +289,392 @@
* Select | unselect sub resource when resource is clicked | unclicked.
* @param type
*/
- this.$scope.gui.onComponentTypeClick = (type:string):void => {
- if (type === 'Resource') {
- if (this.$scope.checkboxesFilter.selectedComponentTypes.indexOf('Resource') === -1) {
- // If the resource was not selected, unselect all childs.
- this.$scope.checkboxesFilter.selectedResourceSubTypes = [];
- } else {
- // If the resource was selected, select all childs
- this.$scope.checkboxesFilter.selectedResourceSubTypes = angular.copy(this.$scope.checkboxes.resourceSubTypes);
- }
+ this.$scope.gui.onComponentTypeClick = (compType: string, checked?: boolean): void => {
+ let components = angular.copy(this.$scope.filterParams.components);
+ const compIdx = components.indexOf(compType);
+ checked = (checked !== undefined) ? checked : compIdx === -1;
+ if (checked && compIdx === -1) {
+ components.push(compType);
+ components = this.cleanSubsFromList(components);
+ } else if (!checked && compIdx !== -1) {
+ components.splice(compIdx, 1);
}
+ this.changeFilterParams({
+ components: components
+ });
};
/**
* Selecting | unselect resources when sub resource is clicked | unclicked.
*/
- this.$scope.gui.onResourceSubTypesClick = ():void => {
- if (this.$scope.checkboxesFilter.selectedResourceSubTypes && this.$scope.checkboxesFilter.selectedResourceSubTypes.length === this.$scope.checkboxes.resourceSubTypes.length) {
- this.$scope.checkboxesFilter.selectedComponentTypes.push('Resource');
- } else {
- this.$scope.checkboxesFilter.selectedComponentTypes = _.without(this.$scope.checkboxesFilter.selectedComponentTypes, 'Resource');
+ this.$scope.gui.onComponentSubTypesClick = (compSubType: string, compType: string, checked?: boolean): void => {
+ const componentSubTypesCheckboxes = this.$scope.checkboxes[compType.toLowerCase() + 'SubTypes'];
+ if (componentSubTypesCheckboxes) {
+ let components = angular.copy(this.$scope.filterParams.components);
+ let componentSubTypes = components.filter((st) => st.startsWith(compType + '.'));
+
+ const compSubTypeValue = compType + '.' + compSubType;
+ const compSubTypeValueIdx = components.indexOf(compSubTypeValue);
+ checked = (checked !== undefined) ? checked : compSubTypeValueIdx === -1;
+ if (checked && compSubTypeValueIdx === -1) {
+ components.push(compSubTypeValue);
+ componentSubTypes.push(compSubTypeValue);
+
+ // if all sub types are checked, then check the main component type
+ if (componentSubTypes.length === componentSubTypesCheckboxes.length) {
+ this.$scope.gui.onComponentTypeClick(compType, true);
+ return;
+ }
+ } else if (!checked) {
+ const compIdx = components.indexOf(compType);
+ // if sub type exists, then remove it
+ if (compSubTypeValueIdx !== -1) {
+ components.splice(compSubTypeValueIdx, 1);
+ }
+ // else, if sub type doesn't exists, but its parent main component type exists,
+ // then remove the main type and push all sub types except the current
+ else if (compIdx !== -1) {
+ components.splice(compIdx, 1);
+ componentSubTypesCheckboxes.forEach((st) => {
+ if (st !== compSubType) {
+ components.push(compType + '.' + st);
+ }
+ });
+ }
+ }
+
+ this.changeFilterParams({
+ components
+ });
}
};
- this.$scope.gui.onCategoryClick = (category:IMainCategory):void => {
- // Select | Unselect all childs
- if (this.isCategorySelected(category.uniqueId)) {
- this.$scope.checkboxesFilter.selectedCategoriesModel = this.$scope.checkboxesFilter.selectedCategoriesModel.concat(angular.copy(_.map(category.subcategories, (item) => {
- return item.uniqueId;
- })));
- if (category.subcategories) {
- category.subcategories.forEach((sub:ISubCategory)=> { // Loop on all selected subcategories and mark the childrens
- this.$scope.checkboxesFilter.selectedCategoriesModel = this.$scope.checkboxesFilter.selectedCategoriesModel.concat(angular.copy(_.map(sub.groupings, (item) => {
- return item.uniqueId;
- })));
- });
+ this.$scope.gui.onCategoryClick = (category: ICategoryBase, checked?: boolean): void => {
+ let categories: string[] = angular.copy(this.$scope.filterParams.categories);
+ let parentCategory: ICategoryBase = this.categoriesMap[category.uniqueId].parent;
+
+ // add the category to selected categories list
+ const categoryIdx = categories.indexOf(category.uniqueId);
+ checked = (checked !== undefined) ? checked : categoryIdx === -1;
+ if (checked && categoryIdx === -1) {
+ categories.push(category.uniqueId);
+
+ // check if all parent category children are checked, then check the parent category
+ if (parentCategory) {
+ if (this.getParentCategoryChildren(parentCategory).every((ch) => categories.indexOf(ch.uniqueId) !== -1)) {
+ this.$scope.gui.onCategoryClick(parentCategory, true);
+ return;
+ }
}
- } else {
- this.$scope.checkboxesFilter.selectedCategoriesModel = _.difference(this.$scope.checkboxesFilter.selectedCategoriesModel, _.map(category.subcategories, (item) => {
- return item.uniqueId;
- }));
- if (category.subcategories) {
- category.subcategories.forEach((sub:ISubCategory)=> { // Loop on all selected subcategories and un mark the childrens
- this.$scope.checkboxesFilter.selectedCategoriesModel = _.difference(this.$scope.checkboxesFilter.selectedCategoriesModel, _.map(sub.groupings, (item) => {
- return item.uniqueId;
- }));
- });
+
+ categories = this.cleanSubsFromList(categories);
+ } else if (!checked) {
+ // if category exists, then remove it
+ if (categoryIdx !== -1) {
+ categories.splice(categoryIdx, 1);
+ }
+ // else, if category doesn't exists, but one of its parent categories exists,
+ // then remove that parent category and push all its children categories except the current
+ else {
+ let prevParentCategory: ICategoryBase = category;
+ let additionalCategories: string[] = [];
+ while (parentCategory) {
+ // add parent category children to list for replacing the parent category (if will be found later)
+ additionalCategories = additionalCategories.concat(
+ this.getParentCategoryChildren(parentCategory)
+ .filter((ch) => ch.uniqueId !== prevParentCategory.uniqueId)
+ .map((ch) => ch.uniqueId));
+
+ const parentCategoryIdx = categories.indexOf(parentCategory.uniqueId);
+ if (parentCategoryIdx !== -1) {
+ categories.splice(parentCategoryIdx, 1);
+ categories = categories.concat(additionalCategories);
+ break;
+ } else {
+ prevParentCategory = parentCategory;
+ parentCategory = this.categoriesMap[parentCategory.uniqueId].parent;
+ }
+ }
}
}
+
+ this.changeFilterParams({
+ categories
+ });
};
- this.$scope.gui.onSubcategoryClick = (category:IMainCategory, subCategory:ISubCategory):void => {
- // Select | Unselect all childs
- if (this.isCategorySelected(subCategory.uniqueId)) {
- this.$scope.checkboxesFilter.selectedCategoriesModel = this.$scope.checkboxesFilter.selectedCategoriesModel.concat(angular.copy(_.map(subCategory.groupings, (item) => {
- return item.uniqueId;
- })));
- } else {
- this.$scope.checkboxesFilter.selectedCategoriesModel = _.difference(this.$scope.checkboxesFilter.selectedCategoriesModel, _.map(subCategory.groupings, (item) => {
- return item.uniqueId;
- }));
+ this.$scope.gui.onStatusClick = (statusKey: string, status: IConfigStatus, checked?: boolean) => {
+ const statuses = angular.copy(this.$scope.filterParams.statuses);
+
+ // add the status key to selected statuses list
+ const statusIdx = statuses.indexOf(statusKey);
+ checked = (checked !== undefined) ? checked : statusIdx === -1;
+ if (checked && statusIdx === -1) {
+ statuses.push(statusKey);
+ } else if (!checked && statusIdx !== -1) {
+ statuses.splice(statusIdx, 1);
}
- // Mark | Un mark the parent when all childs selected.
- if (this.areAllCategoryChildsSelected(category)) {
- // Add the category to checkboxesFilter.selectedCategoriesModel
- this.$scope.checkboxesFilter.selectedCategoriesModel.push(category.uniqueId);
- } else {
- this.$scope.checkboxesFilter.selectedCategoriesModel = _.without(this.$scope.checkboxesFilter.selectedCategoriesModel, category.uniqueId);
- }
-
+ this.changeFilterParams({
+ statuses
+ });
};
- this.$scope.raiseNumberOfElementToDisplay = ():void => {
+ this.$scope.gui.changeFilterTerm = (filterTerm: string) => {
+ this.changeFilterParams({
+ term: filterTerm
+ });
+ };
+
+ this.$scope.raiseNumberOfElementToDisplay = (): void => {
this.$scope.numberOfItemToDisplay = this.$scope.numberOfItemToDisplay + 35;
if (this.$scope.catalogFilterdItems) {
this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.catalogFilterdItems.length;
}
};
- this.$scope.gui.onGroupClick = (subCategory:ISubCategory):void => {
- // Mark | Un mark the parent when all childs selected.
- if (this.areAllSubCategoryChildsSelected(subCategory)) {
- // Add the category to checkboxesFilter.selectedCategoriesModel
- this.$scope.checkboxesFilter.selectedCategoriesModel.push(subCategory.uniqueId);
- } else {
- this.$scope.checkboxesFilter.selectedCategoriesModel = _.without(this.$scope.checkboxesFilter.selectedCategoriesModel, subCategory.uniqueId);
+ }
+
+ private getAllCategoryChildrenIdsFlat(category:ICategoryBase) {
+ let catChildrenIds = [];
+ if ((<IMainCategory>category).subcategories) {
+ catChildrenIds = (<IMainCategory>category).subcategories.reduce((acc, scat) => {
+ return acc.concat(this.getAllCategoryChildrenIdsFlat(scat));
+ }, (<IMainCategory>category).subcategories.map((scat) => scat.uniqueId));
+ }
+ else if ((<ISubCategory>category).groupings) {
+ catChildrenIds = (<ISubCategory>category).groupings.map((g) => g.uniqueId);
+ }
+ return catChildrenIds;
+ }
+
+ private getParentCategoryChildren(parentCategory:ICategoryBase): ICategoryBase[] {
+ if ((<IMainCategory>parentCategory).subcategories) {
+ return (<IMainCategory>parentCategory).subcategories;
+ } else if ((<ISubCategory>parentCategory).groupings) {
+ return (<ISubCategory>parentCategory).groupings;
+ }
+ return [];
+ }
+
+ private cleanSubsFromList(list:Array<string>, delimiter:string='.', removeSubsList?:Array<string>) {
+ let curRemoveSubsList = (removeSubsList || list).slice().sort(); // by default remove any children of any item in list
+ while (curRemoveSubsList.length) {
+ const curRemoveSubItem = curRemoveSubsList.shift();
+ const removeSubListFilter = (x) => !x.startsWith(curRemoveSubItem + delimiter);
+ list = list.filter(removeSubListFilter);
+ curRemoveSubsList = curRemoveSubsList.filter(removeSubListFilter);
+ }
+ return list;
+ }
+
+ private applyFilterParamsToView(filterParams:IFilterParams) {
+ // reset checkboxes filter
+ this.initCheckboxesFilter();
+
+ this.applyFilterParamsComponents(filterParams);
+ this.applyFilterParamsCategories(filterParams);
+ this.applyFilterParamsStatuses(filterParams);
+ this.applyFilterParamsOrder(filterParams);
+ this.applyFilterParamsTerm(filterParams);
+ }
+
+ private applyFilterParamsComponents(filterParams:IFilterParams) {
+ const componentList = [];
+ const componentSubTypesLists = {};
+ filterParams.components.forEach((compStr) => {
+ const compWithSub = compStr.split('.', 2);
+ const mainComp = compWithSub[0];
+ const subComp = compWithSub[1];
+ if (!subComp) { // main component type
+ componentList.push(mainComp);
+
+ // if component type has sub types list, then add all component sub types
+ const checkboxesSubTypeKey = mainComp.toLowerCase() + 'SubTypes';
+ if (this.$scope.checkboxes.hasOwnProperty(checkboxesSubTypeKey)) {
+ componentSubTypesLists[mainComp] = angular.copy(this.$scope.checkboxes[checkboxesSubTypeKey]);
+ }
+ } else { // sub component type
+ // init component sub types list
+ if (!componentSubTypesLists.hasOwnProperty(mainComp)) {
+ componentSubTypesLists[mainComp] = [];
+ }
+ // add sub type to list if not exist
+ if (componentSubTypesLists[mainComp].indexOf(subComp) === -1) {
+ componentSubTypesLists[mainComp].push(subComp);
+ }
}
+ });
+ this.$scope.checkboxesFilter.selectedComponentTypes = componentList;
+ Object.keys(componentSubTypesLists).forEach((tKey) => {
+ const compSelectedSubTypeKey = 'selected' + tKey + 'SubTypes';
+ if (this.$scope.checkboxesFilter.hasOwnProperty(compSelectedSubTypeKey)) {
+ this.$scope.checkboxesFilter[compSelectedSubTypeKey] = componentSubTypesLists[tKey];
+ }
+ });
+
+ let selectedCatalogIndex = filterParams.active ? CatalogSelectorTypes.Active : CatalogSelectorTypes.Archive;
+ this.$scope.selectedCatalogItem = this.$scope.catalogSelectorItems[selectedCatalogIndex];
+
+ }
+
+ private applyFilterParamsCategories(filterParams:IFilterParams) {
+ this.$scope.checkboxesFilter.selectedCategoriesModel = filterParams.categories.reduce((acc, c) => {
+ acc.push(c);
+ const cat = this.categoriesMap[c].category;
+ if (cat) {
+ acc = acc.concat(this.getAllCategoryChildrenIdsFlat(cat));
+ }
+ return acc;
+ }, []);
+ }
+
+ private getActiveCatalogItems(forceReload?: boolean): void {
+
+ if (forceReload || this.componentShouldReload()) {
+ this.$scope.gui.isLoading = true;
+ let onSuccess = (followedResponse:Array<Component>):void => {
+ this.updateCatalogItems(followedResponse);
+ this.$scope.gui.isLoading = false;
+ this.cacheService.set('breadcrumbsComponentsState', this.$state.current.name); //catalog
+ this.cacheService.set('breadcrumbsComponents', followedResponse);
+ };
+
+ let onError = ():void => {
+ console.info('Failed to load catalog CatalogViewModel::getActiveCatalogItems');
+ this.$scope.gui.isLoading = false;
+ };
+ this.EntityService.getCatalog().then(onSuccess, onError);
+ } else {
+ let cachedComponents = this.cacheService.get('breadcrumbsComponents');
+ this.updateCatalogItems(cachedComponents);
+ }
+ }
+
+ private getArchiveCatalogItems(forceReload?: boolean): void {
+ if(forceReload || !this.cacheService.contains("archiveComponents")) {
+ this.$scope.gui.isLoading = true;
+ let onSuccess = (followedResponse:Array<Component>):void => {
+ this.cacheService.set("archiveComponents", followedResponse);
+ this.updateCatalogItems(followedResponse);
+ this.$scope.gui.isLoading = false;
+ };
+
+ let onError = ():void => {
+ console.info('Failed to load catalog CatalogViewModel::getArchiveCatalogItems');
+ this.$scope.gui.isLoading = false;
+ };
+
+ this.ArchiveService.getArchiveCatalog().subscribe(onSuccess, onError);
+ } else {
+ let archiveCache = this.cacheService.get("archiveComponents");
+ this.updateCatalogItems(archiveCache);
+ }
+
+ }
+
+ private updateCatalogItems = (items:Array<Component>):void => {
+ this.$scope.catalogFilterdItems = items;
+ this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.catalogFilterdItems.length;
+ this.$scope.categories = this.cacheService.get('serviceCategories').concat(this.cacheService.get('resourceCategories'));
+ }
+
+ private componentShouldReload = ():boolean => {
+ let breadcrumbsValid: boolean = (this.$state.current.name === this.cacheService.get('breadcrumbsComponentsState') && this.cacheService.contains('breadcrumbsComponents'));
+ return !breadcrumbsValid || this.isDefaultFilter();
+ }
+
+ private isDefaultFilter = (): boolean => {
+ return angular.equals(this.defaultFilterParams, this.$scope.filterParams);
+ }
+
+ private applyFilterParamsStatuses(filterParams: IFilterParams) {
+ this.$scope.checkboxesFilter.selectedStatuses = filterParams.statuses.reduce((acc, stKey:string) => {
+ const status = this.$scope.confStatus[stKey];
+ if (status) {
+ acc.push(status.values);
+ }
+ return acc;
+ }, []);
+ }
+
+ private applyFilterParamsOrder(filterParams: IFilterParams) {
+ this.$scope.sortBy = filterParams.order[0];
+ this.$scope.reverse = filterParams.order[1];
+ }
+
+ private applyFilterParamsTerm(filterParams: IFilterParams) {
+ this.$scope.search = {
+ filterTerm: filterParams.term
};
+ }
-
- };
-
- private areAllCategoryChildsSelected = (category:IMainCategory):boolean => {
- if (!category.subcategories) {
- return false;
- }
- let allIds = _.map(category.subcategories, (sub:ISubCategory)=> {
- return sub.uniqueId;
+ private loadFilterParams() {
+ const params = this.$state.params;
+ this.$scope.filterParams = angular.copy(this.defaultFilterParams);
+ Object.keys(params).forEach((k) => {
+ if (!angular.isUndefined(params[k])) {
+ let newVal;
+ let filterKey = k.substr('filter.'.length);
+ switch (k) {
+ case 'filter.components':
+ case 'filter.categories':
+ newVal = _.uniq(params[k].split(','));
+ newVal = this.cleanSubsFromList(newVal);
+ break;
+ case 'filter.statuses':
+ newVal = _.uniq(params[k].split(','));
+ break;
+ case 'filter.order':
+ newVal = params[k].startsWith('-') ? [params[k].substr(1), true] : [params[k], false];
+ break;
+ case 'filter.term':
+ newVal = params[k];
+ break;
+ case 'filter.active':
+ newVal = (params[k] === "true" || params[k] === true);
+ break;
+ default:
+ // unknown filter key
+ filterKey = null;
+ }
+ if (filterKey) {
+ this.$scope.filterParams[filterKey] = newVal;
+ }
+ }
});
- let total = _.intersection(this.$scope.checkboxesFilter.selectedCategoriesModel, allIds);
- return total.length === category.subcategories.length ? true : false;
- };
+ // re-set filter params with valid values
+ this.applyFilterParamsToView(this.$scope.filterParams);
- private areAllSubCategoryChildsSelected = (subCategory:ISubCategory):boolean => {
- if (!subCategory.groupings) {
- return false;
- }
- let allIds = _.map(subCategory.groupings, (group:IGroup)=> {
- return group.uniqueId;
+ }
+
+ private changeFilterParams(changedFilterParams) {
+ const newParams = {};
+ Object.keys(changedFilterParams).forEach((k) => {
+ let newVal;
+ switch (k) {
+ case 'components':
+ case 'categories':
+ case 'statuses':
+ newVal = changedFilterParams[k] && changedFilterParams[k].length ? changedFilterParams[k].join(',') : null;
+ break;
+ case 'order':
+ newVal = (changedFilterParams[k][1] ? '-' : '') + changedFilterParams[k][0];
+ break;
+ case 'term':
+ newVal = changedFilterParams[k] ? changedFilterParams[k] : null;
+ break;
+ case 'active':
+ newVal = changedFilterParams[k];
+ break;
+ default:
+ return;
+ }
+ this.$scope.filterParams[k] = changedFilterParams[k];
+ newParams['filter.' + k] = newVal;
});
- let total = _.intersection(this.$scope.checkboxesFilter.selectedCategoriesModel, allIds);
- return total.length === subCategory.groupings.length ? true : false;
- };
-
- private isCategorySelected = (uniqueId:string):boolean => {
- if (this.$scope.checkboxesFilter.selectedCategoriesModel.indexOf(uniqueId) !== -1) {
- return true;
- }
- return false;
- };
+ this.$state.go('.', newParams, {location: 'replace', notify: false}).then(() => {
+ this.applyFilterParamsToView(this.$scope.filterParams);
+ });
+ }
}
diff --git a/catalog-ui/src/app/view-models/catalog/catalog-view.html b/catalog-ui/src/app/view-models/catalog/catalog-view.html
index 76f2357..0546db3 100644
--- a/catalog-ui/src/app/view-models/catalog/catalog-view.html
+++ b/catalog-ui/src/app/view-models/catalog/catalog-view.html
@@ -7,10 +7,31 @@
<div class="w-sdc-main-container">
- <!-- LEFT SIDE -->
- <perfect-scrollbar scroll-y-margin-offset="0" class="sdc-catalog-body-container w-sdc-left-sidebar" include-padding="true">
- <div class="sdc-catalog-leftbar-container">
+ <div
+ class="i-sdc-designer-leftbar-section-left-switch-header"
+ data-tests-id="catalog-selector-button"
+ data-ng-click="showCatalogSelector=!showCatalogSelector">
+ <div class="i-sdc-designer-leftbar-section-left-switch-header-text">
+ {{selectedCatalogItem.title}}
+ </div>
+ <div class="i-sdc-designer-leftbar-section-left-switch-header-icon sprite-new arrow-up-small"> </div>
+ <div
+ class="sdc-catalog-selector-wrapper"
+ data-ng-show="showCatalogSelector">
+ <div
+ class="sdc-catalog-selector-item"
+ data-ng-repeat="leftSwitchItem in catalogSelectorItems track by $index"
+ data-tests-id="catalog-selector-{{leftSwitchItem.value}}"
+ data-ng-click="selectLeftSwitchItem(leftSwitchItem)">
+ <span>{{leftSwitchItem.title}}</span>
+ </div>
+ </div>
+ </div>
+
+ <!-- LEFT SIDE -->
+ <perfect-scrollbar scroll-y-margin-offset="0" class="sdc-catalog-body-container w-sdc-left-sidebar i-sdc-designer-left-sidebar" include-padding="true">
+ <div class="sdc-catalog-leftbar-container">
<div class="sdc-catalog-type-filter-container">
<div
class="i-sdc-designer-leftbar-section-title pointer"
@@ -23,20 +44,20 @@
<ul class="list-unstyled i-sdc-designer-leftbar-section-content-ul">
<li class="i-sdc-designer-leftbar-section-content-ul-li" data-ng-repeat="type in checkboxes.componentTypes">
- <sdc-checkbox elem-id="checkbox-{{type | lowercase | clearWhiteSpaces}}"
+ <ng1-checkbox elem-id="checkbox-{{type | lowercase | clearWhiteSpaces}}"
sdc-checklist-model="checkboxesFilter.selectedComponentTypes"
sdc-checklist-value="type"
- data-ng-click="gui.onComponentTypeClick(type)"
- text="{{type}}"></sdc-checkbox>
+ sdc-checked-change="gui.onComponentTypeClick(type, checked)"
+ text="{{type}}"></ng1-checkbox>
<ul class="list-unstyled i-sdc-catalog-subcategories-checkbox" data-ng-if="type==='Resource'">
<li data-ng-repeat="subType in checkboxes.resourceSubTypes">
- <sdc-checkbox elem-id="checkbox-{{subType | lowercase | clearWhiteSpaces}}"
+ <ng1-checkbox elem-id="checkbox-{{subType | lowercase | clearWhiteSpaces}}"
sdc-checklist-model="checkboxesFilter.selectedResourceSubTypes"
sdc-checklist-value="subType"
- data-ng-click="gui.onResourceSubTypesClick()"
- text="{{subType}}"></sdc-checkbox>
+ sdc-checked-change="gui.onComponentSubTypesClick(subType, type, checked)"
+ text="{{subType}}"></ng1-checkbox>
</li>
</ul>
@@ -59,33 +80,33 @@
<li class="i-sdc-designer-leftbar-section-content-ul-li"
data-ng-repeat="category in categories | categoryTypeFilter:checkboxesFilter.selectedComponentTypes:checkboxesFilter.selectedResourceSubTypes | orderBy: category">
- <sdc-checkbox elem-id="checkbox-{{category.uniqueId | lowercase | clearWhiteSpaces}}"
+ <ng1-checkbox elem-id="checkbox-{{category.uniqueId | lowercase | clearWhiteSpaces}}"
sdc-checklist-model="checkboxesFilter.selectedCategoriesModel"
sdc-checklist-value="category.uniqueId"
+ sdc-checked-change="gui.onCategoryClick(category, checked)"
data-tests-id="{{category.uniqueId}}"
- data-ng-click="gui.onCategoryClick(category)"
- text="{{category.name}}"></sdc-checkbox>
+ text="{{category.name}}"></ng1-checkbox>
<!-- SUB CATEGORY CHECKBOX -->
<ul class="list-unstyled i-sdc-catalog-subcategories-checkbox" data-ng-if="category.subcategories && category.subcategories.length>0">
<li ng-repeat="subcategory in category.subcategories track by subcategory.uniqueId | orderBy:'name'">
- <sdc-checkbox elem-id="checkbox-{{subcategory.uniqueId | lowercase | clearWhiteSpaces}}"
+ <ng1-checkbox elem-id="checkbox-{{subcategory.uniqueId | lowercase | clearWhiteSpaces}}"
sdc-checklist-model="checkboxesFilter.selectedCategoriesModel"
sdc-checklist-value="subcategory.uniqueId"
+ sdc-checked-change="gui.onCategoryClick(subcategory, checked)"
data-tests-id="{{subcategory.uniqueId}}"
- data-ng-click="gui.onSubcategoryClick($parent.category, subcategory)"
- text="{{subcategory.name}}"></sdc-checkbox>
+ text="{{subcategory.name}}"></ng1-checkbox>
<!-- GROUPING CHECKBOX -->
<ul class=" list-unstyled i-sdc-catalog-grouping-checkbox" data-ng-if="subcategory.groupings && subcategory.groupings.length>0">
<li ng-repeat="grouping in subcategory.groupings track by grouping.uniqueId | orderBy:'name'">
- <sdc-checkbox elem-id="checkbox-{{grouping.uniqueId | lowercase | clearWhiteSpaces}}"
+ <ng1-checkbox elem-id="checkbox-{{grouping.uniqueId | lowercase | clearWhiteSpaces}}"
sdc-checklist-model="checkboxesFilter.selectedCategoriesModel"
sdc-checklist-value="grouping.uniqueId"
- data-ng-click="gui.onGroupClick($parent.subcategory)"
- text="{{grouping.name}}"></sdc-checkbox>
+ sdc-checked-change="gui.onCategoryClick(grouping, checked)"
+ text="{{grouping.name}}"></ng1-checkbox>
</li>
</ul>
@@ -112,15 +133,15 @@
<!--li data-ng-repeat="(key, value) in confStatus" -->
<li class="i-sdc-designer-leftbar-section-content-ul-li"
- data-ng-repeat="(key, state) in confStatus | catalogStatusFilter">
+ data-ng-repeat="(key, state) in confStatus">
- <sdc-checkbox elem-id="checkbox-{{key | lowercase | clearWhiteSpaces}}"
+ <ng1-checkbox elem-id="checkbox-{{key | lowercase | clearWhiteSpaces}}"
sdc-checklist-model="checkboxesFilter.selectedStatuses"
sdc-checklist-value="state.values"
- text="{{state.name}}"></sdc-checkbox>
+ sdc-checked-change="gui.onStatusClick(key, state, checked)"
+ text="{{state.name}}"></ng1-checkbox>
<div class="i-sdc-categories-list-item-icon"></div>
- </label>
</li>
</ul>
</div>
@@ -134,66 +155,39 @@
<!-- HEADER -->
<div>
- <div class="w-sdc-dashboard-catalog-header">
- {{getNumOfElements((catalogFilterdItems| entityFilter:checkboxesFilter | filter:search).length)}}
- </div>
+ <div class="w-sdc-dashboard-catalog-items-header"
+ ng-bind-html="getNumOfElements((catalogFilterdItems| entityFilter:checkboxesFilter | filter:search).length)"
+ ></div>
<div class="w-sdc-dashboard-catalog-header-right">
- <span class="w-sdc-dashboard-catalog-header-order" translate="SORT_CAPTION"></span>
+ <span class="w-sdc-dashboard-catalog-header-order1" translate="SORT_CAPTION"></span>
<a class="w-sdc-dashboard-catalog-sort" data-tests-id="sort-by-last-update" data-ng-class="{'blue' : sortBy==='lastUpdateDate'}"
ng-click="order('lastUpdateDate')" translate="SORT_BY_UPDATE_DATE"></a>
<span data-ng-show="sortBy === 'lastUpdateDate'" class="w-sdc-catalog-sort-arrow" data-ng-class="{'down': reverse, 'up':!reverse}"></span>
|
<a class="w-sdc-dashboard-catalog-sort" data-tests-id="sort-by-alphabetical" data-ng-class="{'blue' : sortBy!=='lastUpdateDate'}"
- ng-click="order('name | resourceName')" translate="SORT_ALPHABETICAL"></a>
+ ng-click="order('name|resourceName')" translate="SORT_ALPHABETICAL"></a>
<span data-ng-show="sortBy !== 'lastUpdateDate'" class="w-sdc-catalog-sort-arrow" data-ng-class="{'down': reverse, 'up':!reverse}"></span>
</div>
</div>
- <div infinite-scroll-disabled='isAllItemDisplay' infinite-scroll="raiseNumberOfElementToDisplay()" infinite-scroll-container="'#catalog-main-scroll'" infinite-scroll-parent>
+ <div infinite-scroll-disabled='isAllItemDisplay' infinite-scroll="raiseNumberOfElementToDisplay()" infinite-scroll-container="'#catalog-main-scroll'" infinite-scroll-distance="'0.2'" infinite-scroll-parent>
<div class='w-sdc-row-flex-items'>
-
+
<!-- Tile new -->
- <div data-ng-init="component.filterTerm = component.name + ' ' + component.description + ' ' + component.tags.toString() + ' ' + component.version"
- class="sdc-tile sdc-tile-fix-width"
- data-ng-repeat="component in catalogFilterdItems| entityFilter:checkboxesFilter | filter:search | orderBy:sortBy:reverse | limitTo:numberOfItemToDisplay"
- >
-
- <div class='sdc-tile-header' data-ng-class="{'purple': component.isResource(), 'blue': !component.isResource()}">
- <div data-ng-if="component.isResource()" data-tests-id="asset-type">{{component.getComponentSubType()}}</div>
- <div data-ng-if="component.isService()">S</div>
- </div>
-
- <div class='sdc-tile-content' data-ng-click="gui.isLoading || goToComponent(component)">
- <div class='sdc-tile-content-icon centered'>
- <div class="{{component.iconSprite}} {{component.icon}}"
- data-ng-class="{'sprite-resource-icons': component.isResource(), 'sprite-services-icons': component.isService()}"
- data-tests-id="{{component.name}}"></div>
- </div>
- <div class='sdc-tile-content-info'>
- <div class="sdc-tile-info-line title" data-tests-id="{{component.name | resourceName}}" sdc-smart-tooltip>{{component.name | resourceName}}</div>
- <div class="sdc-tile-info-line subtitle" data-tests-id="{{component.name}}Version">
- V {{component.version}}
- </div>
- </div>
- </div>
- <div class='sdc-tile-footer'>
- <div class="sdc-tile-footer-content">
- <div class='sdc-tile-footer-text'>{{component.getStatus(sdcMenu)}}</div>
- </div>
- </div>
-
- </div>
+ <ng2-ui-tile data-ng-repeat="component in catalogFilterdItems| entityFilter:checkboxesFilter | filter:search | orderBy:sortBy:reverse | limitTo:numberOfItemToDisplay"
+ data-ng-init="component.filterTerm = component.name + ' ' + component.description + ' ' + component.tags.toString() + ' ' + component.version;"
+ [component]="component" (on-tile-click)="gui.isLoading || goToComponent(component)"></ng2-ui-tile>
<!-- Tile new -->
-
+
</div>
-
+
</div>
</perfect-scrollbar>
</div>
- <top-nav [top-lvl-selected-index]="1" [search-term]="search.filterTerm" (search-term-change)="search.filterTerm=$event" [version]="version"></top-nav>
+ <top-nav [top-lvl-selected-index]="1" [search-term]="search.filterTerm" (search-term-change)="gui.changeFilterTerm($event)" [version]="version"></top-nav>
</div>
diff --git a/catalog-ui/src/app/view-models/catalog/catalog.less b/catalog-ui/src/app/view-models/catalog/catalog.less
index 1f473c9..4555603 100644
--- a/catalog-ui/src/app/view-models/catalog/catalog.less
+++ b/catalog-ui/src/app/view-models/catalog/catalog.less
@@ -145,29 +145,29 @@
color: #000;
width: 300px;
}
-
- // .magnification {
- // .sprite;
- // .sprite.magnification-glass;
- // .hand;
- // position: absolute;
- // top: 40px;
- // right: 42px;
- // }
}
.w-sdc-catalog-main {
padding: 10px 12px;
}
- .w-sdc-dashboard-catalog-header {
+ .w-sdc-dashboard-catalog-items-header {
.b_3;
+ color: @main_color_m;
+ font-family: OpenSans-Regular, sans-serif;
+ font-size: 14px;
display: inline-block;
- font-style: italic;
- font-weight: bold;
- padding-left: 10px;
+ font-style: normal;
+ margin-left: 11px;
+ b {
+ font-family: OpenSans-Bold, sans-serif;
+ color: @main_color_l;
+ font-weight: bold;
+ }
+ font-weight: normal;
+ /* padding-left: 10px; */
}
- .w-sdc-dashboard-catalog-header-order {
+ .w-sdc-dashboard-catalog-header-order1 {
.b_3;
font-weight: 800;
}
@@ -207,8 +207,6 @@
}
-
-
.w-sdc-dashboard-catalog-header-right{
float: right;
display: inline-block;
@@ -248,6 +246,39 @@
margin-left: 20px;
}
+ /* added Michael */
+ .i-sdc-designer-left-sidebar {
+ margin-top: 43px;
+ }
+ .i-sdc-designer-leftbar-section-left-switch-header {
+ text-transform: uppercase;
+ .l_14_m;
+ line-height: 40px;
+ width: 243px;
+
+ font-family: OpenSans-Bold, sans-serif;
+ font-size: 14px;
+
+ color: @main_color_a;
+ background-color: @tlv_color_t;
+ border: solid 1px fade(@main_color_t, 40%);
+ cursor: pointer;
+ opacity: 1;
+ z-index: 9999;
+ position: relative;
+ //box-shadow: 1px 0 2px #00000036;
+ }
+ .i-sdc-designer-leftbar-section-left-switch-header-text {
+ display: inline-block;
+ width: 180px;
+ margin-left: 20px;
+ }
+ .i-sdc-designer-leftbar-section-left-switch-header-icon {
+ display: inline-block;
+ vertical-align: middle;
+ }
+
+
.seperator-left,
.seperator-right {
border-right: solid 1px @color_m;
@@ -299,3 +330,33 @@
.hand;
}
}
+
+/* added Michael */
+.sdc-catalog-selector-wrapper {
+ position: absolute;
+ left: 0px;
+ top: 42px;
+ width: 241px;
+ height: auto;
+ cursor: pointer;
+ opacity: 1;
+ z-index: 1000;
+ box-shadow: 1px 2px 3px #b1b1b1;
+}
+
+.sdc-catalog-selector-item {
+ text-transform: none;
+ line-height: 40px;
+ font-family: OpenSans-Bold, sans-serif;
+ font-size: 14px;
+ color: @main_color_l;
+ background-color: @main_color_p;
+ padding-left: 20px;
+}
+
+.sdc-catalog-selector-item:hover {
+ color: @main_color_a;
+ background-color: @tlv_color_v;
+}
+
+
diff --git a/catalog-ui/src/app/view-models/dashboard/dashboard-view-model.ts b/catalog-ui/src/app/view-models/dashboard/dashboard-view-model.ts
index 4262860..4d08404 100644
--- a/catalog-ui/src/app/view-models/dashboard/dashboard-view-model.ts
+++ b/catalog-ui/src/app/view-models/dashboard/dashboard-view-model.ts
@@ -21,13 +21,15 @@
'use strict';
import {IConfigRoles, IAppConfigurtaion, IAppMenu, IUserProperties, Component} from "app/models";
import {EntityService, SharingService, CacheService} from "app/services";
-import {ComponentType, ResourceType, MenuHandler, ModalsHandler, ChangeLifecycleStateHandler, SEVERITY, ComponentFactory} from "app/utils";
+import {ComponentType, ResourceType, MenuHandler, ModalsHandler, ChangeLifecycleStateHandler, SEVERITY, ComponentFactory, CHANGE_COMPONENT_CSAR_VERSION_FLAG} from "app/utils";
import {IClientMessageModalModel} from "../modals/message-modal/message-client-modal/client-message-modal-view-model";
import {UserService} from "../../ng2/services/user.service";
+
export interface IDashboardViewModelScope extends ng.IScope {
isLoading:boolean;
+ numberOfItemToDisplay:number;
components:Array<Component>;
folders:FoldersMenu;
roles:IConfigRoles;
@@ -38,10 +40,11 @@
showTutorial:boolean;
isFirstTime:boolean;
version:string;
- checkboxesFilter:CheckboxesFilter;
+ filterParams:DashboardFilter;
vfcmtType:string;
-
+ changeFilterParams():void;
+ updateSearchTerm(newTerm:string):void;
onImportVfc(file:any):void;
onImportVf(file:any):void;
openCreateModal(componentType:ComponentType, importedFile:any):void;
@@ -52,11 +55,12 @@
getCurrentFolderDistributed():Array<Component>;
changeLifecycleState(entity:any, data:any):void;
goToComponent(component:Component):void;
+ raiseNumberOfElementToDisplay():void;
wizardDebugEdit:Function;
notificationIconCallback:Function;
}
-interface CheckboxesFilter {
+interface ICheckboxesFilter {
// Statuses
selectedStatuses:Array<string>;
// distributed
@@ -76,6 +80,35 @@
states:Array<any>;
}
+export interface IQueryFilterParams {
+ 'filter.term': string;
+ 'filter.distributed': string;
+ 'filter.status': string
+}
+
+
+export class DashboardFilter {
+ searchTerm: string;
+ checkboxes: ICheckboxesFilter;
+
+ constructor(params = {}) {
+ this.searchTerm = params['filter.term'] || "";
+ this.checkboxes = {
+ selectedStatuses : params['filter.status']? params['filter.status'].split(',') : [],
+ distributed : params['filter.distributed']? params['filter.distributed'].split(',') : []
+ };
+ }
+
+ public toParam = ():IQueryFilterParams => {
+ return {
+ 'filter.term': this.searchTerm,
+ 'filter.distributed': this.checkboxes && this.checkboxes.distributed.join(',') || null,
+ 'filter.status': this.checkboxes && this.checkboxes.selectedStatuses.join(',') || null
+ };
+ }
+
+}
+
export class FoldersMenu {
private _folders:Array<FoldersItemsMenu> = [];
@@ -190,7 +223,7 @@
private $http:ng.IHttpService,
private sdcConfig:IAppConfigurtaion,
private sdcMenu:IAppMenu,
- private $state:any,
+ private $state:ng.ui.IStateService,
private $stateParams:any,
private userService:UserService,
private sharingService:SharingService,
@@ -202,7 +235,7 @@
private MenuHandler:MenuHandler) {
this.initScope();
this.initFolders();
- this.initEntities(true);
+ this.initEntities();
if (this.$stateParams) {
@@ -237,6 +270,7 @@
this.$scope.version = this.cacheService.get('version');
this.$scope.sharingService = this.sharingService;
+ this.$scope.numberOfItemToDisplay = 0;
this.$scope.isLoading = false;
this.$scope.sdcConfig = this.sdcConfig;
this.$scope.sdcMenu = this.sdcMenu;
@@ -245,21 +279,26 @@
this.$scope.showTutorial = false;
this.$scope.isFirstTime = false;
this.$scope.vfcmtType = ResourceType.VFCMT;
+ this.$scope.filterParams = new DashboardFilter(this.$state.params);
// Open onboarding modal
this.$scope.notificationIconCallback = ():void => {
- this.ModalsHandler.openOnboadrdingModal('Import').then(()=> {
- // OK
+ this.ModalsHandler.openOnboadrdingModal('Import').then((result)=> {
+ //OK
+ if(!result.previousComponent || result.previousComponent.csarVersion != result.componentCsar.csarVersion) {
+ this.cacheService.set(CHANGE_COMPONENT_CSAR_VERSION_FLAG, result.componentCsar.csarVersion);
+ }
+
+ this.$state.go('workspace.general', {
+ id: result.previousComponent && result.previousComponent.uniqueId,
+ componentCsar: result.componentCsar,
+ type: result.type
+ });
}, ()=> {
// ERROR
});
};
- // Checkboxes filter init
- this.$scope.checkboxesFilter = <CheckboxesFilter>{};
- this.$scope.checkboxesFilter.selectedStatuses = [];
- this.$scope.checkboxesFilter.distributed = [];
-
this.$scope.onImportVf = (file:any):void => {
if (file && file.filename) {
// Check that the file has valid extension.
@@ -367,6 +406,20 @@
this.$state.go('workspace.general', {id: component.uniqueId, type: component.componentType.toLowerCase()});
};
+ this.$scope.raiseNumberOfElementToDisplay = ():void => {
+ this.$scope.numberOfItemToDisplay = this.$scope.numberOfItemToDisplay + 35;
+ if (this.$scope.components) {
+ this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.components.length;
+ }
+ };
+
+ this.$scope.updateSearchTerm = (newTerm: string):void => {
+ this.$scope.filterParams.searchTerm = newTerm;
+ };
+
+ this.$scope.changeFilterParams = ():void => {
+ this.$state.go('.', this.$scope.filterParams.toParam(), {location: 'replace', notify: false});
+ };
};
private _getTotalCounts(tmpFolder, self):number {
@@ -393,16 +446,38 @@
}
}
- private initEntities = (reload:boolean):void => {
- this.$scope.isLoading = reload;
- this.entityService.getAllComponents().then(
- (components:Array<Component>) => {
- this.components = components;
- this.$scope.components = components;
- this.$scope.isLoading = false;
- });
+ private initEntities = (forceReload?:boolean):void => {
+
+ if(forceReload || this.componentShouldReload()){
+ this.$scope.isLoading = true;
+ this.entityService.getAllComponents(true).then(
+ (components:Array<Component>) => {
+ this.cacheService.set('breadcrumbsComponentsState', this.$state.current.name); //dashboard
+ this.cacheService.set('breadcrumbsComponents', components);
+ this.components = components;
+ this.$scope.components = components;
+ this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.components.length;
+ this.$scope.isLoading = false;
+ });
+ } else {
+ this.components = this.cacheService.get('breadcrumbsComponents');
+ this.$scope.components = this.components;
+ this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.components.length;
+
+ }
+
};
+ private isDefaultFilter = (): boolean => {
+ let defaultFilter = new DashboardFilter();
+ return angular.equals(defaultFilter, this.$scope.filterParams);
+ }
+
+ private componentShouldReload = ():boolean => {
+ let breadcrumbsValid: boolean = (this.$state.current.name === this.cacheService.get('breadcrumbsComponentsState') && this.cacheService.contains('breadcrumbsComponents'));
+ return !breadcrumbsValid || this.isDefaultFilter();
+ }
+
private getEntitiesByStateDist = (state:string, dist:string):Array<Component> => {
let gObj:Array<Component>;
if (this.components && (state || dist)) {
diff --git a/catalog-ui/src/app/view-models/dashboard/dashboard-view.html b/catalog-ui/src/app/view-models/dashboard/dashboard-view.html
index bddcbcd..8279232 100644
--- a/catalog-ui/src/app/view-models/dashboard/dashboard-view.html
+++ b/catalog-ui/src/app/view-models/dashboard/dashboard-view.html
@@ -8,74 +8,53 @@
<div class="w-sdc-main-container">
- <perfect-scrollbar include-padding="true" class="w-sdc-main-right-container">
+ <perfect-scrollbar id="dashboard-main-scroll" include-padding="true" class="w-sdc-main-right-container">
- <div class='w-sdc-row-flex-items'>
+ <div infinite-scroll-disabled='isAllItemDisplay' infinite-scroll="raiseNumberOfElementToDisplay()" infinite-scroll-container="'#dashboard-main-scroll'" infinite-scroll-distance="'0.2'" infinite-scroll-parent>
- <!-- ADD Component -->
- <div ng-if="user.role === 'DESIGNER'" class="w-sdc-dashboard-card-new"
- data-ng-mouseleave="displayActions = false"
- data-ng-mouseover="displayActions = true"
- data-ng-init="displayActions = false">
- <div class="w-sdc-dashboard-card-new-content" data-tests-id="AddButtonsArea">
- <div class="w-sdc-dashboard-card-new-content-plus" data-ng-show="!displayActions"></div>
- <div class="sdc-dashboard-create-element-container" data-ng-show="displayActions">
- <button data-ng-if="roles[user.role].dashboard.showCreateNew" data-tests-id="createResourceButton" class="tlv-btn outline blue" data-ng-click="openCreateModal('RESOURCE')">Add VF</button>
- <button data-ng-if="roles[user.role].dashboard.showCreateNew" data-tests-id="createCRButton" class="tlv-btn outline blue" data-ng-click="createCR()">Add CR</button>
- <button data-ng-if="roles[user.role].dashboard.showCreateNew" data-tests-id="createPNFButton" class="tlv-btn outline blue" data-ng-click="createPNF()">Add PNF</button>
- <button data-ng-if="roles[user.role].dashboard.showCreateNew" data-tests-id="createServiceButton" class="tlv-btn outline blue" data-ng-click="openCreateModal('SERVICE')">Add Service</button>
- </div>
- </div>
- </div>
+ <div class='w-sdc-row-flex-items'>
- <!-- Import Component -->
- <div ng-if="user.role === 'DESIGNER'" class="w-sdc-dashboard-card-new"
- data-ng-mouseleave="displayActions = false"
- data-ng-mouseover="displayActions = true"
- data-ng-init="displayActions = false">
- <div class="w-sdc-dashboard-card-new-content" data-tests-id="importButtonsArea" >
- <div class="w-sdc-dashboard-card-import-content-plus" data-ng-show="!displayActions"></div>
- <div class="sdc-dashboard-import-element-container" data-ng-show="displayActions">
- <div data-ng-if="roles[user.role].dashboard.showCreateNew" class="tlv-btn outline blue">Import VFC
- <file-opener on-file-upload="onImportVfc(file)" data-tests-id="importVFCbutton" extensions="{{sdcConfig.toscaFileExtension}}" data-ng-click="displayActions=false"></file-opener>
- </div>
- <div data-ng-if="roles[user.role].dashboard.showCreateNew" class="tlv-btn outline blue" data-ng-click="notificationIconCallback()">Import VSP</div>
- <div data-ng-if="roles[user.role].dashboard.showCreateNew" class="tlv-btn outline blue import-dcae">Import DCAE asset
- <file-opener on-file-upload="onImportVf(file)" data-tests-id="importVFbutton" extensions="{{sdcConfig.csarFileExtension}}" data-ng-click="displayActions=false"></file-opener>
+ <!-- ADD Component -->
+ <div ng-if="user.role === 'DESIGNER'" class="w-sdc-dashboard-card-new"
+ data-ng-mouseleave="displayActions = false"
+ data-ng-mouseover="displayActions = true"
+ data-ng-init="displayActions = false">
+ <div class="w-sdc-dashboard-card-new-content" data-tests-id="AddButtonsArea">
+ <div class="w-sdc-dashboard-card-new-content-plus" data-ng-show="!displayActions"></div>
+ <div class="sdc-dashboard-create-element-container" data-ng-show="displayActions">
+ <button data-ng-if="roles[user.role].dashboard.showCreateNew" data-tests-id="createResourceButton" class="tlv-btn outline blue" data-ng-click="openCreateModal('RESOURCE')">Add VF</button>
+ <button data-ng-if="roles[user.role].dashboard.showCreateNew" data-tests-id="createCRButton" class="tlv-btn outline blue" data-ng-click="createCR()">Add CR</button>
+ <button data-ng-if="roles[user.role].dashboard.showCreateNew" data-tests-id="createPNFButton" class="tlv-btn outline blue" data-ng-click="createPNF()">Add PNF</button>
+ <button data-ng-if="roles[user.role].dashboard.showCreateNew" data-tests-id="createServiceButton" class="tlv-btn outline blue" data-ng-click="openCreateModal('SERVICE')">Add Service</button>
</div>
</div>
</div>
- </div>
- <!-- Tile new -->
- <div class="sdc-tile sdc-tile-fix-width" data-ng-repeat="component in components | filter:{resourceType:('!'+vfcmtType)} | entityFilter:checkboxesFilter | filter:search">
-
- <div class='sdc-tile-header' data-ng-class="{'purple': component.isResource(), 'blue': !component.isResource()}">
- <div data-ng-if="component.isResource()" data-tests-id="asset-type">{{component.getComponentSubType()}}</div>
- <div data-ng-if="component.isService()">S</div>
- </div>
-
- <div class='sdc-tile-content' data-tests-id="dashboard-Elements" data-ng-click="goToComponent(component)">
- <div class='sdc-tile-content-icon'>
- <div class="{{component.iconSprite}} {{component.icon}}"
- data-ng-class="{'sprite-resource-icons': component.isResource(), 'sprite-services-icons': component.isService()}"
- data-tests-id="{{component.name}}"></div>
- </div>
-
- <div class='sdc-tile-content-info'>
- <div class="sdc-tile-info-line title" data-tests-id="{{component.name | resourceName}}" sdc-smart-tooltip>{{component.name | resourceName}}</div>
- <div class="sdc-tile-info-line subtitle" data-tests-id="{{component.name}}Version">V {{component.version}}</div>
+ <!-- Import Component -->
+ <div ng-if="user.role === 'DESIGNER'" class="w-sdc-dashboard-card-new"
+ data-ng-mouseleave="displayActions = false"
+ data-ng-mouseover="displayActions = true"
+ data-ng-init="displayActions = false">
+ <div class="w-sdc-dashboard-card-new-content" data-tests-id="importButtonsArea" >
+ <div class="w-sdc-dashboard-card-import-content-plus" data-ng-show="!displayActions"></div>
+ <div class="sdc-dashboard-import-element-container" data-ng-show="displayActions">
+ <div data-ng-if="roles[user.role].dashboard.showCreateNew" class="tlv-btn outline blue">Import VFC
+ <file-opener on-file-upload="onImportVfc(file)" data-tests-id="importVFCbutton" extensions="{{sdcConfig.toscaFileExtension}}" data-ng-click="displayActions=false"></file-opener>
+ </div>
+ <div data-ng-if="roles[user.role].dashboard.showCreateNew" class="tlv-btn outline blue" data-ng-click="notificationIconCallback()">Import VSP</div>
+ <div data-ng-if="roles[user.role].dashboard.showCreateNew" class="tlv-btn outline blue import-dcae">Import DCAE asset
+ <file-opener on-file-upload="onImportVf(file)" data-tests-id="importVFbutton" extensions="{{sdcConfig.csarFileExtension}}" data-ng-click="displayActions=false"></file-opener>
+ </div>
+ </div>
</div>
</div>
- <div class='sdc-tile-footer'>
- <div class="sdc-tile-footer-content">
- <div class='sdc-tile-footer-text'>{{component.getStatus(sdcMenu)}}</div>
- </div>
- </div>
+ <!-- Tile new -->
+ <ng2-ui-tile data-ng-repeat="component in components | filter:{resourceType:('!'+vfcmtType)} | entityFilter:filterParams.checkboxes | filter:filterParams.searchTerm | limitTo:numberOfItemToDisplay"
+ [component]="component" (on-tile-click)="goToComponent(component)"></ng2-ui-tile>
+ <!-- Tile new -->
</div>
- <!-- Tile new -->
</div>
@@ -88,24 +67,26 @@
>
<span data-ng-if="folder.isGroup()">{{folder.text}}</span>
- <sdc-checkbox data-ng-if="!folder.isGroup() && !folder.dist"
+ <ng1-checkbox data-ng-if="!folder.isGroup() && !folder.dist"
elem-id="checkbox-{{folder.text | lowercase | clearWhiteSpaces}}"
- sdc-checklist-model="checkboxesFilter.selectedStatuses"
+ sdc-checklist-model="filterParams.checkboxes.selectedStatuses"
sdc-checklist-value="folder.state"
- text="{{folder.text}}"></sdc-checkbox>
+ sdc-checklist-change="changeFilterParams()"
+ text="{{folder.text}}"></ng1-checkbox>
- <sdc-checkbox data-ng-if="!folder.isGroup() && folder.dist"
+ <ng1-checkbox data-ng-if="!folder.isGroup() && folder.dist"
elem-id="checkbox-{{folder.text | lowercase | clearWhiteSpaces}}"
- sdc-checklist-model="checkboxesFilter.distributed"
+ sdc-checklist-model="filterParams.checkboxes.distributed"
sdc-checklist-value="folder.dist"
- text="{{folder.text}}"></sdc-checkbox>
+ sdc-checklist-change="changeFilterParams()"
+ text="{{folder.text}}"></ng1-checkbox>
<span class="i-sdc-left-sidebar-item-state-count">{{entitiesCount(folder)}}</span>
</div>
</div>
</div>
- <top-nav [top-lvl-selected-index]="0" [version]="version" [search-term]="search.filterTerm" (search-term-change)="search.filterTerm=$event" [notification-icon-callback]="notificationIconCallback"></top-nav>
+ <top-nav [top-lvl-selected-index]="0" [version]="version" [search-term]="filterParams.searchTerm" (search-term-change)="updateSearchTerm($event);changeFilterParams()" [notification-icon-callback]="notificationIconCallback"></top-nav>
</div>
<div data-ui-view=""></div>
diff --git a/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form-view.html b/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form-view.html
index 0984c68..59124a2 100644
--- a/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form-view.html
+++ b/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form-view.html
@@ -1,4 +1,4 @@
-<sdc-modal modal="modalInstanceArtifact" type="classic" class="sdc-add-artifact" buttons="footerButtons" header="{{getFormTitle()}}" show-close-button="true" get-close-modal-response="close" data-tests-id="sdc-add-artifact">
+<ng1-modal modal="modalInstanceArtifact" type="classic" class="sdc-add-artifact" buttons="footerButtons" header="{{getFormTitle()}}" show-close-button="true" get-close-modal-response="close" data-tests-id="sdc-add-artifact">
<loader data-display="isLoading"></loader>
@@ -165,5 +165,5 @@
</form>
</div>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/forms/attribute-form/attribute-form-view.html b/catalog-ui/src/app/view-models/forms/attribute-form/attribute-form-view.html
index daa7a90..eada5c9 100644
--- a/catalog-ui/src/app/view-models/forms/attribute-form/attribute-form-view.html
+++ b/catalog-ui/src/app/view-models/forms/attribute-form/attribute-form-view.html
@@ -1,4 +1,4 @@
-<sdc-modal modal="modalInstanceAttribute" type="classic" class="sdc-edit-attribute-container" buttons="footerButtons" header="{{isNew ? 'Add' : 'Update' }} Attribute" show-close-button="true">
+<ng1-modal modal="modalInstanceAttribute" type="classic" class="sdc-edit-attribute-container" buttons="footerButtons" header="{{isNew ? 'Add' : 'Update' }} Attribute" show-close-button="true">
<div class="sdc-edit-attribute-form-container" >
<form novalidate class="w-sdc-form two-columns" name="forms.editForm" >
@@ -149,4 +149,4 @@
</form>
</div>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.html b/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.html
index 5fd57f6..d211b4e 100644
--- a/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.html
+++ b/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.html
@@ -1,4 +1,4 @@
-<sdc-modal modal="envParametersModal" type="classic" class="sdc-env-form-container" buttons="buttons" header="{{artifactResource.artifactDisplayName}}" show-close-button="true">
+<ng1-modal modal="envParametersModal" type="classic" class="sdc-env-form-container" buttons="buttons" header="{{artifactResource.artifactDisplayName}}" show-close-button="true">
<div class="w-sdc-env-form-container">
<div class="w-sdc-env-search pull-left">
<input type="text" class="w-sdc-env-search-input" placeholder="Search" data-ng-model="searchText" data-tests-id="search-env-param-name"/>
@@ -46,8 +46,7 @@
<div class="i-sdc-form-item" data-ng-class="{error:(forms.editForm[parameter.name].$dirty && forms.editForm[parameter.name].$invalid), required: (parameter.defaultValue)}">
<span class="required-symbol">*</span>
<div class="input-parameter">
- <input class="i-sdc-form-input" data-ng-class="{error: (forms.editForm[parameter.name].$invalid),
- 'default-value':(parameter.defaultValue && parameter.currentValue === parameter.defaultValue)}"
+ <input class="i-sdc-form-input" data-ng-class="{error: (forms.editForm[parameter.name].$invalid)}"
data-ng-model-options="{ debounce: 200 }"
data-ng-model="parameter.currentValue"
value="{{parameter.currentValue}}"
@@ -90,4 +89,4 @@
</div>
</div>
</div>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.less b/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.less
index e797093..d89ab37 100644
--- a/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.less
+++ b/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.less
@@ -109,9 +109,6 @@
width: 100%;
display: inline-flex;
padding-right: 33px;
- &.default-value{
- border-color: @func_color_h;
- }
}
.action-button{
border-left: solid 1px @main_color_o;
diff --git a/catalog-ui/src/app/view-models/forms/input-form/input-form-view.html b/catalog-ui/src/app/view-models/forms/input-form/input-form-view.html
index 1bf6dc4..34532d1 100644
--- a/catalog-ui/src/app/view-models/forms/input-form/input-form-view.html
+++ b/catalog-ui/src/app/view-models/forms/input-form/input-form-view.html
@@ -1,4 +1,4 @@
-<sdc-modal modal="modalInstanceInput" type="classic" class="sdc-edit-input-container" buttons="footerButtons" header="Update Input" show-close-button="true">
+<ng1-modal modal="modalInstanceInput" type="classic" class="sdc-edit-input-container" buttons="footerButtons" header="Update Input" show-close-button="true">
<div class="sdc-edit-input-form-container" >
<form novalidate class="w-sdc-form two-columns" name="forms.editForm" >
@@ -122,4 +122,4 @@
</form>
</div>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/forms/property-forms/base-property-form/property-form-base-view.html b/catalog-ui/src/app/view-models/forms/property-forms/base-property-form/property-form-base-view.html
index 7cb05bf..248f143 100644
--- a/catalog-ui/src/app/view-models/forms/property-forms/base-property-form/property-form-base-view.html
+++ b/catalog-ui/src/app/view-models/forms/property-forms/base-property-form/property-form-base-view.html
@@ -1,4 +1,4 @@
-<sdc-modal modal="modalPropertyFormBase" type="classic" class="sdc-edit-property-container" buttons="footerButtons" header="{{isNew ? 'Add' : 'Update' }} Property" show-close-button="true" data-tests-id="sdc-edit-property-container">
+<ng1-modal modal="modalPropertyFormBase" type="classic" class="sdc-edit-property-container" buttons="footerButtons" header="{{isNew ? 'Add' : 'Update' }} Property" show-close-button="true" data-tests-id="sdc-edit-property-container">
<loader data-display="isLoading" relative="false" size="medium"></loader>
<div class="sdc-modal-top-bar" data-ng-if="!isNew">
<div class="sdc-modal-top-bar-buttons">
@@ -129,4 +129,4 @@
</perfect-scrollbar>
</div>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts
index 8ea2e8c..f5c057e 100644
--- a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts
+++ b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts
@@ -23,8 +23,9 @@
import {
PROPERTY_TYPES, ModalsHandler, ValidationUtils, PROPERTY_VALUE_CONSTRAINTS, FormState, PROPERTY_DATA} from "app/utils";
import {DataTypesService} from "app/services";
-import {PropertyModel, DataTypesMap, Component} from "app/models";
+import {PropertyModel, DataTypesMap, Component, GroupInstance, PolicyInstance, PropertyBEModel} from "app/models";
import {ComponentInstance} from "../../../../models/componentsInstances/componentInstance";
+import { ComponentInstanceServiceNg2 } from "app/ng2/services/component-instance-services/component-instance.service";
export interface IEditPropertyModel {
property:PropertyModel;
@@ -86,7 +87,10 @@
'ModalsHandler',
'filteredProperties',
'$timeout',
- 'isPropertyValueOwner'
+ 'isPropertyValueOwner',
+ 'propertyOwnerType',
+ 'propertyOwnerId',
+ 'ComponentInstanceServiceNg2'
];
private formState:FormState;
@@ -104,7 +108,10 @@
private ModalsHandler:ModalsHandler,
private filteredProperties:Array<PropertyModel>,
private $timeout:ng.ITimeoutService,
- private isPropertyValueOwner:boolean) {
+ private isPropertyValueOwner:boolean,
+ private propertyOwnerType:string,
+ private propertyOwnerId:string,
+ private ComponentInstanceServiceNg2: ComponentInstanceServiceNg2) {
this.formState = angular.isDefined(property.name) ? FormState.UPDATE : FormState.CREATE;
this.initScope();
@@ -194,15 +201,17 @@
this.$scope.isLastProperty = this.$scope.currentPropertyIndex == (this.filteredProperties.length - 1);
this.$scope.dataTypes = this.DataTypesService.getAllDataTypes();
this.$scope.isPropertyValueOwner = this.isPropertyValueOwner;
+ this.$scope.propertyOwnerType = this.propertyOwnerType;
this.initEditPropertyModel();
//check if property of VnfConfiguration
this.$scope.isVnfConfiguration = false;
- if(angular.isArray(this.component.componentInstances)) {
+ if(this.propertyOwnerType == "component" && angular.isArray(this.component.componentInstances)) {
+
var componentPropertyOwner:ComponentInstance = this.component.componentInstances.find((ci:ComponentInstance) => {
return ci.uniqueId === this.property.resourceInstanceUniqueId;
});
- if (componentPropertyOwner.componentName === 'vnfConfiguration') {
+ if (componentPropertyOwner && componentPropertyOwner.componentName === 'vnfConfiguration') {
this.$scope.isVnfConfiguration = true;
}
}
@@ -252,21 +261,30 @@
}
};
- //in case we have uniqueId we call update method
- if (this.$scope.isPropertyValueOwner) {
- if (!this.$scope.editPropertyModel.property.simpleType && !this.$scope.isSimpleType(property.type)) {
- let myValueString:string = JSON.stringify(this.$scope.myValue);
- property.value = myValueString;
- }
- this.component.updateInstanceProperties(property.resourceInstanceUniqueId, [property]).then((propertiesFromBE) => onPropertySuccess(propertiesFromBE[0]), onPropertyFaild);
+ //Not clean, but doing this as a temporary fix until we update the property right panel modals
+ if(this.propertyOwnerType == "group"){
+ this.ComponentInstanceServiceNg2.updateComponentGroupInstanceProperties(this.component, this.propertyOwnerId, [property])
+ .subscribe((propertiesFromBE) => { onPropertySuccess(<PropertyModel>propertiesFromBE[0])}, error => onPropertyFaild);
+ } else if(this.propertyOwnerType == "policy"){
+ this.ComponentInstanceServiceNg2.updateComponentPolicyInstanceProperties(this.component, this.propertyOwnerId, [property])
+ .subscribe((propertiesFromBE) => { onPropertySuccess(<PropertyModel>propertiesFromBE[0])}, error => onPropertyFaild);
} else {
- if (!this.$scope.editPropertyModel.property.simpleType && !this.$scope.isSimpleType(property.type)) {
- let myValueString:string = JSON.stringify(this.$scope.myValue);
- property.defaultValue = myValueString;
+ //in case we have uniqueId we call update method
+ if (this.$scope.isPropertyValueOwner) {
+ if (!this.$scope.editPropertyModel.property.simpleType && !this.$scope.isSimpleType(property.type)) {
+ let myValueString:string = JSON.stringify(this.$scope.myValue);
+ property.value = myValueString;
+ }
+ this.component.updateInstanceProperties(property.resourceInstanceUniqueId, [property]).then((propertiesFromBE) => onPropertySuccess(propertiesFromBE[0]), onPropertyFaild);
} else {
- this.$scope.editPropertyModel.property.defaultValue = this.$scope.editPropertyModel.property.value;
+ if (!this.$scope.editPropertyModel.property.simpleType && !this.$scope.isSimpleType(property.type)) {
+ let myValueString:string = JSON.stringify(this.$scope.myValue);
+ property.defaultValue = myValueString;
+ } else {
+ this.$scope.editPropertyModel.property.defaultValue = this.$scope.editPropertyModel.property.value;
+ }
+ this.component.addOrUpdateProperty(property).then(onPropertySuccess, onPropertyFaild);
}
- this.component.addOrUpdateProperty(property).then(onPropertySuccess, onPropertyFaild);
}
};
diff --git a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html
index 743de29..37a265a 100644
--- a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html
+++ b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html
@@ -1,8 +1,8 @@
-<sdc-modal modal="modalInstanceProperty" type="classic" class="sdc-edit-property-container" buttons="footerButtons" header="{{isNew ? 'Add' : 'Update' }} Property" show-close-button="true" data-tests-id="sdc-edit-property-container">
+<ng1-modal modal="modalInstanceProperty" type="classic" class="sdc-edit-property-container" buttons="footerButtons" header="{{isNew ? 'Add' : 'Update' }} Property" show-close-button="true" data-tests-id="sdc-edit-property-container">
<loader data-display="isLoading" relative="false" size="medium"></loader>
<div class="sdc-modal-top-bar" data-ng-if="!isNew">
<div class="sdc-modal-top-bar-buttons">
- <span ng-click="delete(editPropertyModel.property)" data-ng-class="{'disabled' : isPropertyValueOwner || editPropertyModel.property.readonly}" class="sprite-new delete-btn" data-tests-id="delete_property" sdc-smart-tooltip="">Delete</span>
+ <span ng-click="delete(editPropertyModel.property)" data-ng-class="{'disabled' : isPropertyValueOwner || editPropertyModel.property.readonly || propertyOwnerType == 'group' || propertyOwnerType == 'policy'}" class="sprite-new delete-btn" data-tests-id="delete_property" sdc-smart-tooltip="">Delete</span>
<span class="delimiter"></span>
<span data-ng-click="getPrev()" data-ng-class="{'disabled' : !currentPropertyIndex }" class="sprite-new left-arrow" data-tests-id="get-prev" sdc-smart-tooltip="">Previous</span>
<span data-ng-click="getNext()" data-ng-class="{'disabled' : isLastProperty }" class="sprite-new right-arrow" data-tests-id="get-next" sdc-smart-tooltip="">Next</span>
@@ -198,4 +198,4 @@
</perfect-scrollbar>
</div>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/forms/property-forms/module-property-modal/module-property-model.ts b/catalog-ui/src/app/view-models/forms/property-forms/module-property-modal/module-property-model.ts
index 510814b..2437f46 100644
--- a/catalog-ui/src/app/view-models/forms/property-forms/module-property-modal/module-property-model.ts
+++ b/catalog-ui/src/app/view-models/forms/property-forms/module-property-modal/module-property-model.ts
@@ -71,7 +71,7 @@
save(isNeedToCloseModal):ng.IPromise<boolean> {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<boolean>();
let onSuccess = (properties:Array<PropertyModel>):void => {
deferred.resolve(true);
diff --git a/catalog-ui/src/app/view-models/forms/property-forms/select-datatype-modal/select-datatype-modal-view-model.ts b/catalog-ui/src/app/view-models/forms/property-forms/select-datatype-modal/select-datatype-modal-view-model.ts
index 8d5c30a..ab4b033 100644
--- a/catalog-ui/src/app/view-models/forms/property-forms/select-datatype-modal/select-datatype-modal-view-model.ts
+++ b/catalog-ui/src/app/view-models/forms/property-forms/select-datatype-modal/select-datatype-modal-view-model.ts
@@ -67,7 +67,7 @@
//scope methods
save(isNeedToCloseModal):ng.IPromise<boolean> {
- let deferred = this.$q.defer();
+ let deferred = this.$q.defer<boolean>();
this.$scope.property.propertiesName = this.DataTypesService.selectedPropertiesName;
this.$scope.property.input = this.DataTypesService.selectedInput;
this.$scope.property.isAlreadySelected = true;
diff --git a/catalog-ui/src/app/view-models/forms/resource-instance-name-form/resource-instance-name-view.html b/catalog-ui/src/app/view-models/forms/resource-instance-name-form/resource-instance-name-view.html
index e04343a..969d1d9 100644
--- a/catalog-ui/src/app/view-models/forms/resource-instance-name-form/resource-instance-name-view.html
+++ b/catalog-ui/src/app/view-models/forms/resource-instance-name-form/resource-instance-name-view.html
@@ -1,4 +1,4 @@
-<sdc-modal modal="modalInstanceName" type="classic" class="w-sdc-modal-resource-instance-name modal-type-confirmation" buttons="footerButtons" header="Instance Name" show-close-button="true">
+<ng1-modal modal="modalInstanceName" type="classic" class="w-sdc-modal-resource-instance-name modal-type-confirmation" buttons="footerButtons" header="Instance Name" show-close-button="true">
<form novalidate class="w-sdc-form" name="forms.editNameForm">
<div class="i-sdc-form-item" data-ng-class="{error:(editNameForm.componentInstanceName.$dirty && editNameForm.resourceInstanceName.$invalid)}">
@@ -25,7 +25,7 @@
</div>
</form>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/modals/confirmation-modal/confirmation-modal-view.html b/catalog-ui/src/app/view-models/modals/confirmation-modal/confirmation-modal-view.html
index 09c27f8..e6b31d5 100644
--- a/catalog-ui/src/app/view-models/modals/confirmation-modal/confirmation-modal-view.html
+++ b/catalog-ui/src/app/view-models/modals/confirmation-modal/confirmation-modal-view.html
@@ -1,4 +1,4 @@
-<sdc-modal modal="modalInstanceConfirmation" type="classic" class="w-sdc-modal-confirmation modal-type-{{confirmationModalModel.type}}" header="{{confirmationModalModel.title}}" show-close-button="true">
+<ng1-modal modal="modalInstanceConfirmation" type="classic" class="w-sdc-modal-confirmation modal-type-{{confirmationModalModel.type}}" header="{{confirmationModalModel.title}}" show-close-button="true">
<form novalidate class="w-sdc-form" name="editForm">
<label class="i-sdc-form-label required w-sdc-modal-label" data-ng-bind-html="confirmationModalModel.message"></label>
@@ -24,6 +24,6 @@
<div class="w-sdc-modal-footer classic">
<button class="tlv-btn {{okButtonColor}}" data-tests-id="OK" data-ng-click="ok()" data-ng-disabled="confirmationModalModel.showComment===true && (!comment.text || comment.text && comment.text.length===0)">OK</button>
<button class="tlv-btn grey" data-ng-if="hideCancelButton===false" data-tests-id="Cancel" data-ng-click="cancel()" >Cancel</button>
- <button class="tlv-btn blue add-property-add-another" data-ng-if="isNew" data-ng-click="saveAndAnother()" type="reset" data-ng-disabled="editForm.$invalid">Add Another</button>
+ <!--<button class="tlv-btn blue add-property-add-another" data-ng-if="isNew" data-ng-click="saveAndAnother()" type="reset" data-ng-disabled="editForm.$invalid">Add Another</button>-->
</div>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/modals/conformance-level-modal/conformance-level-modal-view.html b/catalog-ui/src/app/view-models/modals/conformance-level-modal/conformance-level-modal-view.html
index 3577e4d..59a13bc 100644
--- a/catalog-ui/src/app/view-models/modals/conformance-level-modal/conformance-level-modal-view.html
+++ b/catalog-ui/src/app/view-models/modals/conformance-level-modal/conformance-level-modal-view.html
@@ -1,4 +1,4 @@
-<sdc-modal modal="modalInstance"
+<ng1-modal modal="modalInstance"
type="classic"
class="w-sdc-modal modal-type-alert conformance-level-modal"
header="Warning"
@@ -19,4 +19,4 @@
</div>
</perfect-scrollbar>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/modals/email-modal/email-modal-view.html b/catalog-ui/src/app/view-models/modals/email-modal/email-modal-view.html
index bf65428..0354e62 100644
--- a/catalog-ui/src/app/view-models/modals/email-modal/email-modal-view.html
+++ b/catalog-ui/src/app/view-models/modals/email-modal/email-modal-view.html
@@ -1,4 +1,4 @@
-<sdc-modal modal="modalInstanceEmail" type="classic" class="w-sdc-modal-email modal-type-standard" header="{{emailModalModel.title}}" show-close-button="true">
+<ng1-modal modal="modalInstanceEmail" type="classic" class="w-sdc-modal-email modal-type-standard" header="{{emailModalModel.title}}" show-close-button="true">
<loader data-display="isLoading"></loader>
<form novalidate class="w-sdc-form" name="editForm">
@@ -74,4 +74,4 @@
<button class="tlv-btn blue" data-tests-id="OK" data-ng-click="submit()" data-ng-disabled="editForm.$invalid">OK</button>
<button class="tlv-btn grey" data-tests-id="Cancel" data-ng-click="cancel()" >Cancel</button>
</div>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/modals/error-modal/error-403-view.html b/catalog-ui/src/app/view-models/modals/error-modal/error-403-view.html
index 41b1c6d..08f3ef4 100644
--- a/catalog-ui/src/app/view-models/modals/error-modal/error-403-view.html
+++ b/catalog-ui/src/app/view-models/modals/error-modal/error-403-view.html
@@ -1,4 +1,4 @@
<div class="sdc-error-403-container" >
<div class="sdc-error-403-container-title" translate="GENERAL_ERROR_403_TITLE"></div>
- <div class="w-sdc-error-403-text w-sdc-form" translate="GENERAL_ERROR_403_DESCRIPTION" translate-values="{{ mailtoJson }}"></div>
+ <div class="w-sdc-error-403-text w-sdc-form" translate="GENERAL_ERROR_403_DESCRIPTION" translate-values="{'mailto': mailto }"></div>
</div>
diff --git a/catalog-ui/src/app/view-models/modals/error-modal/error.less b/catalog-ui/src/app/view-models/modals/error-modal/error.less
index 8297b50..1843ea3 100644
--- a/catalog-ui/src/app/view-models/modals/error-modal/error.less
+++ b/catalog-ui/src/app/view-models/modals/error-modal/error.less
@@ -1,10 +1,17 @@
.sdc-error-403-container {
.bg_n;
width: 700px;
- height: 400px;
margin: auto;
margin-top: 196px;
+ padding: 40px;
+ box-shadow: #999 2px 2px 10px;
+ text-align: center;
+ .sdc-error-403-container-title {
+ font-size: 24px;
+ text-transform: uppercase;
+ }
+
.w-sdc-error-403-text {
.q_11;
margin-top: 20px;
diff --git a/catalog-ui/src/app/view-models/modals/icons-modal/icons-modal-view.html b/catalog-ui/src/app/view-models/modals/icons-modal/icons-modal-view.html
index 4b89701..aa9230f 100644
--- a/catalog-ui/src/app/view-models/modals/icons-modal/icons-modal-view.html
+++ b/catalog-ui/src/app/view-models/modals/icons-modal/icons-modal-view.html
@@ -1,4 +1,4 @@
-<sdc-modal modal="modalIcons" type="classic" class="w-sdc-modal-icons" buttons="footerButtons" header="Choose Icon" show-close-button="true">
+<ng1-modal modal="modalIcons" type="classic" class="w-sdc-modal-icons" buttons="footerButtons" header="Choose Icon" show-close-button="true">
<div class="suggested-icons-container">
<div class ="suggested-icon-wrapper" data-ng-class="{'selected': selectedIcon == iconSrc}" data-ng-repeat="iconSrc in icons track by $index">
@@ -15,4 +15,4 @@
<button class="tlv-btn blue" data-tests-id="OK" data-ng-click="updateIcon()">OK</button>
<button class="tlv-btn grey" data-tests-id="Cancel" data-ng-click="cancel()" >Cancel</button>
</div>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/modals/message-modal/message-client-modal/client-message-modal-view.html b/catalog-ui/src/app/view-models/modals/message-modal/message-client-modal/client-message-modal-view.html
index cfb0a35..421391e 100644
--- a/catalog-ui/src/app/view-models/modals/message-modal/message-client-modal/client-message-modal-view.html
+++ b/catalog-ui/src/app/view-models/modals/message-modal/message-client-modal/client-message-modal-view.html
@@ -1,4 +1,4 @@
-<sdc-modal modal="modalInstanceError"
+<ng1-modal modal="modalInstanceError"
type="classic"
class="w-sdc-modal modal-type-alert"
header="{{messageModalModel.title}}"
@@ -13,4 +13,4 @@
<!--<div class="w-sdc-modal-body-content" data-ng-bind-html="messageModalModel.message"></div>-->
</perfect-scrollbar>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal-view-model.ts b/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal-view-model.ts
index e3c6ad1..b92069f 100644
--- a/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal-view-model.ts
+++ b/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal-view-model.ts
@@ -24,6 +24,8 @@
export interface IServerMessageModalModel extends IMessageModalModel {
status:string;
messageId:string;
+
+
}
export interface IServerMessageModalViewModelScope extends IMessageModalViewModelScope {
diff --git a/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal-view.html b/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal-view.html
index 294dc76..524551b 100644
--- a/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal-view.html
+++ b/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal-view.html
@@ -1,4 +1,4 @@
-<sdc-modal modal="modalInstanceError"
+<ng1-modal modal="modalInstanceError"
type="classic"
class="w-sdc-modal modal-type-error"
header="{{messageModalModel.title}}"
@@ -14,4 +14,4 @@
<div class="w-sdc-modal-body-content" data-ng-bind-html="messageModalModel.message" data-tests-id="message"></div>
</perfect-scrollbar>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal-view-model.ts b/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal-view-model.ts
index 1cc3690..46b258f 100644
--- a/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal-view-model.ts
+++ b/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal-view-model.ts
@@ -19,7 +19,7 @@
*/
'use strict';
-import {ComponentType, CHANGE_COMPONENT_CSAR_VERSION_FLAG, SEVERITY, FileUtils, ModalsHandler, ComponentFactory} from "app/utils";
+import {ComponentType, SEVERITY, FileUtils, ModalsHandler, ComponentFactory} from "app/utils";
import {OnboardingService, CacheService} from "app/services";
import {Component, IComponent, IUser, IAppConfigurtaion, Resource} from "app/models";
import {IServerMessageModalModel} from "../message-modal/message-server-modal/server-message-modal-view-model";
@@ -63,6 +63,7 @@
'Sdc.Services.OnboardingService',
'okButtonText',
'currentCsarUUID',
+ 'currentCsarVersion',
'Sdc.Services.CacheService',
'FileUtils',
'ComponentFactory',
@@ -77,6 +78,7 @@
private onBoardingService:OnboardingService,
private okButtonText:string,
private currentCsarUUID:string,
+ private currentCsarVersion:string,
private cacheService:CacheService,
private fileUtils:FileUtils,
private componentFactory:ComponentFactory,
@@ -107,28 +109,27 @@
// Dismiss the modal and pass the "mini" component to workspace general page
this.$scope.doImportCsar = ():void => {
- this.$uibModalInstance.dismiss();
- this.$state.go('workspace.general', {
- type: ComponentType.RESOURCE.toLowerCase(),
- componentCsar: this.$scope.selectedComponent
+
+ this.$uibModalInstance.close({
+ componentCsar: this.$scope.selectedComponent,
+ type: ComponentType.RESOURCE.toLowerCase()
});
};
this.$scope.doUpdateCsar = ():void => {
- // In case user select on update the checkin and submit for testing buttons (in general page) should be disabled.
- // to do that we need to pass to workspace.general state parameter to know to disable the buttons.
- this.$uibModalInstance.close();
+
// Change the component version to the CSAR version we want to update.
- /*(<Resource>this.$scope.componentFromServer).csarVersion = (<Resource>this.$scope.selectedComponent).csarVersion;
- let component:Components.Component = this.componentFactory.createComponent(this.$scope.componentFromServer);
- this.$state.go('workspace.general', {vspComponent: component, disableButtons: true });*/
- this.cacheService.set(CHANGE_COMPONENT_CSAR_VERSION_FLAG, (<Resource>this.$scope.selectedComponent).csarVersion);
- this.$state.go('workspace.general', {
- id: this.$scope.componentFromServer.uniqueId,
- componentCsar: this.$scope.selectedComponent,
- type: this.$scope.componentFromServer.componentType.toLowerCase(),
- disableButtons: true
- });
+ if(!this.currentCsarVersion || this.currentCsarVersion != (<Resource>this.$scope.selectedComponent).csarVersion) {
+ this.$uibModalInstance.close({
+ componentCsar: this.$scope.selectedComponent,
+ previousComponent: this.$scope.componentFromServer,
+ type: this.$scope.componentFromServer.componentType.toLowerCase()
+
+ });
+
+ } else {
+ this.$uibModalInstance.close();
+ }
};
this.$scope.downloadCsar = (packageId:string):void => {
diff --git a/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal-view.html b/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal-view.html
index b078a4b..a69d0a8 100644
--- a/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal-view.html
+++ b/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal-view.html
@@ -1,4 +1,4 @@
-<sdc-modal modal="modalOnboarding" class="w-sdc-modal-onboarding w-sdc-classic-top-line-modal" buttons="footerButtons" header="Import VF" show-close-button="true">
+<ng1-modal modal="modalOnboarding" class="w-sdc-modal-onboarding w-sdc-classic-top-line-modal" buttons="footerButtons" header="Import VF" show-close-button="true">
<info-tooltip class="general-info-button" info-message-translate="ON_BOARDING_GENERAL_INFO "></info-tooltip>
<div class="title-wrapper">
<div>
@@ -141,4 +141,4 @@
</div><!-- End table-container-flex -->
<div class="w-sdc-modal-footer classic"></div>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy-view-model.ts b/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy-view-model.ts
index c438c7a..f752e3d 100644
--- a/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy-view-model.ts
+++ b/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy-view-model.ts
@@ -23,6 +23,10 @@
import {PropertyModel, DisplayModule, Component, ComponentInstance, Tab, Module} from "app/models";
import {ExpandCollapseListData} from "app/directives/utils/expand-collapse-list-header/expand-collapse-list-header";
+interface IComponentInstancesMap {
+ [key:string]: ComponentInstance
+}
+
export interface IHierarchyScope extends ng.IScope {
component:Component;
selectedIndex:number;
@@ -32,8 +36,9 @@
expandCollapseArtifactsList:ExpandCollapseListData;
expandCollapsePropertiesList:ExpandCollapseListData;
selectedInstanceId:string;
+ componentInstancesMap:IComponentInstancesMap;
- onModuleSelected(moduleId:string, selectedIndex:number):void;
+ onModuleSelected(module:Module, selectedIndex:number, componentInstanceId?:string):void;
onModuleNameChanged(module:DisplayModule):void;
updateHeatName():void;
loadInstanceModules(instance:ComponentInstance):ng.IPromise<boolean>;
@@ -53,6 +58,7 @@
this.$scope.isLoading = false;
this.$scope.expandCollapseArtifactsList = new ExpandCollapseListData();
this.$scope.expandCollapsePropertiesList = new ExpandCollapseListData();
+ this.$scope.componentInstancesMap = <IComponentInstancesMap>{};
this.initScopeMethods();
}
@@ -65,7 +71,7 @@
this.$scope.expandCollapsePropertiesList.orderByField = "name";
};
- this.$scope.onModuleSelected = (moduleId:string, selectedIndex:number, componentInstanceId?:string):void => {
+ this.$scope.onModuleSelected = (module:Module, selectedIndex:number, componentInstanceId?:string):void => {
let onSuccess = (module:DisplayModule) => {
console.log("Module Loaded: ", module);
@@ -79,15 +85,25 @@
};
this.$scope.selectedIndex = selectedIndex;
- if (!this.$scope.selectedModule || (this.$scope.selectedModule && this.$scope.selectedModule.uniqueId != moduleId)) {
+ if (!this.$scope.selectedModule || (this.$scope.selectedModule && this.$scope.selectedModule.uniqueId != module.uniqueId)) {
this.$scope.isLoading = true;
if (this.$scope.component.isService()) {
this.$scope.selectedInstanceId = componentInstanceId;
- this.$scope.component.getModuleInstanceForDisplay(componentInstanceId, moduleId).then(onSuccess, onFailed);
+ this.$scope.component.getModuleInstanceForDisplay(componentInstanceId, module.uniqueId).then(onSuccess, onFailed);
} else {
- this.$scope.component.getModuleForDisplay(moduleId).then(onSuccess, onFailed);
+ this.$scope.component.getModuleForDisplay(module.uniqueId).then(onSuccess, onFailed);
}
}
+
+ const componentInstances: Array<ComponentInstance> = this.$scope.component.componentInstances || [];
+ (<string[]>_.values(module.members)).forEach((memberId) => {
+ if (!(memberId in this.$scope.componentInstancesMap)) {
+ const compInstance = componentInstances.find((c) => c.uniqueId === memberId);
+ if (compInstance) {
+ this.$scope.componentInstancesMap[compInstance.uniqueId] = compInstance;
+ }
+ }
+ });
};
this.$scope.updateHeatName = () => {
diff --git a/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy-view.html b/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy-view.html
index 3b7b5fc..7a3874e 100644
--- a/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy-view.html
+++ b/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy-view.html
@@ -11,8 +11,8 @@
<expand-collapse expanded-selector=".hierarchy-module-member-list.{{$index}}"
class="general-tab-expand-collapse" is-close-on-init="true"
data-tests-id="hierarchy-module-{{$index}}"
- data-ng-repeat-start="module in component.groups">
- <div class="expand-collapse-title first-level" data-tests-id="hierarchy-module-{{$index}}-title" ng-class="{'selected': selectedIndex === $index}" data-ng-click="onModuleSelected(module.uniqueId, $index)">
+ data-ng-repeat-start="module in component.modules">
+ <div class="expand-collapse-title first-level" data-tests-id="hierarchy-module-{{$index}}-title" ng-class="{'selected': selectedIndex === $index}" data-ng-click="onModuleSelected(module, $index)">
<div class="expand-collapse-title-icon"></div>
<span class="expand-collapse-title-text" data-ng-bind="module.name" tooltips
tooltip-content="{{module.name}}"></span>
@@ -21,8 +21,8 @@
</expand-collapse>
<div data-ng-repeat-end="" class="hierarchy-module-member-list {{$index}}">
- <div ng-repeat="(memberName, value) in ::module.members track by $index">
- <div class="expand-collapse-sub-title" tooltips tooltip-content="{{memberName}}">{{memberName}}</div>
+ <div ng-repeat="memberId in ::module.members track by $index">
+ <div class="expand-collapse-sub-title" tooltips tooltip-content="{{componentInstancesMap[memberId].name}}">{{componentInstancesMap[memberId].name}}</div>
</div>
</div>
</perfect-scrollbar>
@@ -48,7 +48,7 @@
class="general-tab-expand-collapse" is-close-on-init="true"
data-tests-id="hierarchy-module-{{$index}}"
data-ng-repeat-start="module in instance.groupInstances">
- <div class="expand-collapse-title second-level" data-tests-id="hierarchy-module-{{$index}}-title" ng-class="{'selected': selectedIndex === $index && selectedInstanceId === instance.uniqueId}" data-ng-click="onModuleSelected(module.uniqueId, $index, instance.uniqueId)">
+ <div class="expand-collapse-title second-level" data-tests-id="hierarchy-module-{{$index}}-title" ng-class="{'selected': selectedIndex === $index && selectedInstanceId === instance.uniqueId}" data-ng-click="onModuleSelected(module, $index, instance.uniqueId)">
<div class="expand-collapse-title-icon"></div>
<span class="expand-collapse-title-text" data-ng-bind="module.name" tooltips tooltip-content="{{module.name}}"></span>
@@ -56,8 +56,8 @@
</expand-collapse>
<div data-ng-repeat-end="" class="outer-index-{{$parent.$index}} hierarchy-module-member-list {{$index}}">
- <div ng-repeat="(memberName, value) in ::module.members track by $index">
- <div class="expand-collapse-sub-title" tooltips tooltip-content="{{memberName}}">{{memberName}}</div>
+ <div ng-repeat="memberId in ::module.members track by $index">
+ <div class="expand-collapse-sub-title" tooltips tooltip-content="{{componentInstancesMap[memberId].name}}">{{componentInstancesMap[memberId].name}}</div>
</div>
</div>
</div>
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 46c2d2e..a77377b 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<string>;
isLoading:boolean;
graphApi:any;
@@ -42,21 +54,24 @@
sdcMenu:IAppMenu;
version:string;
isViewOnly:boolean;
+ isCanvasTagging:boolean;
isLoadingRightPanel:boolean;
disabledTabs:boolean;
openVersionChangeModal(pathsToDelete:string[]):ng.IPromise<any>;
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 @@
'ChangeLifecycleStateHandler',
'LeftPaletteLoaderService',
'ModalsHandler',
+ 'ModalServiceSdcUI',
'EventListenerService',
- 'ComponentServiceFactoryNg2'
+ 'ComponentServiceFactoryNg2',
+ 'ComponentServiceNg2',
+ 'Notification'
];
constructor(private $scope:ICompositionViewModelScope,
@@ -93,8 +111,12 @@
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 @@
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()) {
(<Service> this.$scope.component).forwardingPaths = (<ServiceGenericResponse>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 @@
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<Component>;
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<any> => {
+ let deferred = new Promise<any>((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<Requirement>) => {
+ _.forEach(requirementsArray, (requirement:Requirement):void => {
+ requirement.ownerName = componentInstance.name;
+ });
+ });
+
+ _.forEach(this.$scope.currentComponent.selectedInstance.capabilities, (capabilitiesArray:Array<Capability>) => {
+ _.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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
modalText += `<p>The following service paths will be erased: ${pathNames}</p>`;
}
}
-
- this.ModalsHandler.openAlertModal(title, modalText).then(this.removeSelectedComponentInstance);
+ this.ModalServiceSdcUI.openAlertModal(title, modalText, "OK", this.removeSelectedComponentInstance, "deleteInstanceModal");
};
this.$scope.openVersionChangeModal = (pathsToDelete:string[]):ng.IPromise<any> => {
@@ -308,7 +475,7 @@
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 fceb73b..4cd33f3 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 @@
<loader data-display="isLoading"></loader>
<div class="w-sdc-designer-canvas" data-ng-class="{sidebaractive: displayDesignerRightSidebar}">
<palette current-component="currentComponent"
- is-view-only="isViewOnly"
+ is-view-only="isViewOnly || isCanvasTagging"
is-loading="isLoading"></palette>
<ng2-palette-popup-panel></ng2-palette-popup-panel>
@@ -19,86 +19,107 @@
<div class="w-sdc-designer-sidebar" data-ng-class="{'view-mode':isViewOnly}">
- <div class="w-sdc-designer-sidebar-head" data-tests-id="w-sdc-designer-sidebar-head">
- <div class="w-sdc-designer-sidebar-logo-ph">
- <div class="large {{selectedComponent.iconSprite}} {{selectedComponent.icon}}">
- <div ng-if="isComponentInstanceSelected()"
- data-ng-class="{'non-certified':'CERTIFIED' !== selectedComponent.lifecycleState}"
- tooltips tooltip-side="top" tooltip-content="Not certified"></div>
+ <div ng-if="!selectedZoneInstance">
+
+ <div class="w-sdc-designer-sidebar-head" data-tests-id="w-sdc-designer-sidebar-head">
+ <div class="w-sdc-designer-sidebar-logo-ph">
+ <div class=" large {{selectedComponent.iconSprite}} {{selectedComponent.icon}}"
+ ng-class="{'archive-component':selectedComponent.archived}">
+ <div ng-if="isComponentInstanceSelected()"
+ data-ng-class="{'non-certified':'CERTIFIED' !== selectedComponent.lifecycleState}"
+ tooltips tooltip-side="top" tooltip-content="Not certified"></div>
+ </div>
</div>
+
+ <div class="w-sdc-designer-sidebar-logo">
+ <span class="w-sdc-designer-sidebar-logo-title" data-tests-id="selectedCompTitle" tooltips
+ tooltip-class="tooltip-custom break-word-tooltip"
+ tooltip-content="​{{isComponentInstanceSelected() ? currentComponent.selectedInstance.name : currentComponent.name | resourceName}}"
+ data-ng-bind="isComponentInstanceSelected() ? currentComponent.selectedInstance.name : currentComponent.name | resourceName"></span>
+ </div>
+ <div class="sprite e-sdc-small-icon-pencil w-sdc-designer-update-resource-icon"
+ data-tests-id="renameInstance"
+ data-ng-if="!isViewOnly && isComponentInstanceSelected() && !selectedComponent.archived"
+ data-ng-click="openUpdateModal()" id="editPencil"></div>
+
+ <div class="sprite e-sdc-small-icon-delete w-sdc-designer-delete-resource-icon"
+ data-tests-id="deleteInstance"
+ data-ng-if="!isViewOnly && isComponentInstanceSelected() && !selectedComponent.archived"
+ data-ng-click="!isLoading && deleteSelectedComponentInstance()" title="Delete Resource Instance"></div>
</div>
- <div class="w-sdc-designer-sidebar-logo">
- <span class="w-sdc-designer-sidebar-logo-title" data-tests-id="selectedCompTitle" tooltips
- tooltip-class="tooltip-custom break-word-tooltip"
- tooltip-content="​{{isComponentInstanceSelected() ? currentComponent.selectedInstance.name : currentComponent.name | resourceName}}"
- data-ng-bind="isComponentInstanceSelected() ? currentComponent.selectedInstance.name : currentComponent.name | resourceName"></span>
+ <div class="w-sdc-designer-sidebar-tabs">
+ <button class="i-sdc-designer-sidebar-tab" data-ui-sref-active="active"
+ data-ui-sref="workspace.composition.details"
+ tooltips tooltip-class="tooltip-custom tab-tooltip" tooltip-content="Information"
+ data-tests-id="information-tab"
+ data-ng-class="{'disabled': disabledTabs}">
+ <div class="i-sdc-designer-sidebar-tab-icon sprite-new info"></div>
+ </button>
+ <!--<button class="i-sdc-designer-sidebar-tab" data-ui-sref-active="active"-->
+ <!--ui-sref="workspace.composition.structure"-->
+ <!--tooltips tooltip-class="tooltip-custom tab-tooltip" tooltip-content="Composition">-->
+ <!--<div class="i-sdc-designer-sidebar-tab-icon sprite-new structure"></div>-->
+ <!--</button>-->
+ <button class="i-sdc-designer-sidebar-tab" data-ui-sref-active="active"
+ data-ui-sref="workspace.composition.deployment"
+ tooltips tooltip-class="tooltip-custom tab-tooltip" tooltip-content="Deployment Artifacts"
+ data-tests-id="deployment-artifact-tab"
+ data-ng-if="!isPNF() && !isConfiguration() && !(isComponentInstanceSelected() && currentComponent.selectedInstance.isServiceProxy())"
+ data-ng-class="{'disabled': disabledTabs}">
+ <div class="i-sdc-designer-sidebar-tab-icon sprite-new deployment-artifacts"></div>
+ </button>
+ <button tooltips tooltip-class="tooltip-custom tab-tooltip"
+ tooltip-content="{{selectedComponent.isResource() || (isComponentInstanceSelected() && currentComponent.selectedInstance.isServiceProxy()) ? 'Properties and Attributes': 'Inputs'}}"
+ class="i-sdc-designer-sidebar-tab" data-ui-sref-active="active"
+ data-ui-sref="workspace.composition.properties"
+ data-tests-id="properties-and-attributes-tab"
+ data-ng-class="{'disabled': disabledTabs}">
+ <div class="i-sdc-designer-sidebar-tab-icon sprite-new"
+ ng-class="selectedComponent.isResource() || (isComponentInstanceSelected() && currentComponent.selectedInstance.isServiceProxy()) ? 'properties': 'inputs'"></div>
+ </button>
+ <button class="i-sdc-designer-sidebar-tab" data-ui-sref-active="active"
+ data-ui-sref="workspace.composition.artifacts"
+ data-ng-if="!isConfiguration() && !(isComponentInstanceSelected() && currentComponent.selectedInstance.isServiceProxy())"
+ tooltips tooltip-class="tooltip-custom tab-tooltip" tooltip-content="Information Artifacts"
+ data-ng-class="{'disabled': disabledTabs}">
+ <div class="i-sdc-designer-sidebar-tab-icon sprite-new information-artifacts"></div>
+ </button>
+ <button data-ng-if="!selectedComponent.isService() || (isComponentInstanceSelected() && currentComponent.selectedInstance.isServiceProxy())" class="i-sdc-designer-sidebar-tab"
+ data-ui-sref-active="active" ui-sref="workspace.composition.relations"
+ tooltips tooltip-class="tooltip-custom tab-tooltip tooltip-rightside"
+ data-tests-id="requirements-and-capabilities"
+ tooltip-content="Requirements and Capabilities"
+ data-ng-class="{'disabled': disabledTabs}">
+ <div class="i-sdc-designer-sidebar-tab-icon sprite-new relations"></div>
+ </button>
+ <button data-ng-if="selectedComponent.isService() && !(isComponentInstanceSelected() && currentComponent.selectedInstance.isServiceProxy())" class="i-sdc-designer-sidebar-tab"
+ data-ui-sref-active="active" ui-sref="workspace.composition.api" data-tests-id="tab-api"
+ tooltips tooltip-class="tooltip-custom tab-tooltip tooltip-rightside" tooltip-content="API"
+ data-ng-class="{'disabled': disabledTabs}">
+ <div class="i-sdc-designer-sidebar-tab-icon sprite-new api"></div>
+ </button>
+
</div>
- <div class="sprite e-sdc-small-icon-pencil w-sdc-designer-update-resource-icon"
- data-ng-if="!isViewOnly && isComponentInstanceSelected()"
- data-ng-click="openUpdateModal()" id="editPencil"></div>
-
- <div class="sprite e-sdc-small-icon-delete w-sdc-designer-delete-resource-icon"
- data-tests-id="e-sdc-small-icon-delete"
- data-ng-if="!isViewOnly && isComponentInstanceSelected()"
- data-ng-click="!isLoading && deleteSelectedComponentInstance()" title="Delete Resource Instance"></div>
- </div>
-
- <div class="w-sdc-designer-sidebar-tabs">
- <button class="i-sdc-designer-sidebar-tab" data-ui-sref-active="active"
- data-ui-sref="workspace.composition.details"
- tooltips tooltip-class="tooltip-custom tab-tooltip" tooltip-content="Information"
- data-tests-id="information-tab"
- data-ng-class="{'disabled': disabledTabs}">
- <div class="i-sdc-designer-sidebar-tab-icon sprite-new info"></div>
- </button>
- <!--<button class="i-sdc-designer-sidebar-tab" data-ui-sref-active="active"-->
- <!--ui-sref="workspace.composition.structure"-->
- <!--tooltips tooltip-class="tooltip-custom tab-tooltip" tooltip-content="Composition">-->
- <!--<div class="i-sdc-designer-sidebar-tab-icon sprite-new structure"></div>-->
- <!--</button>-->
- <button class="i-sdc-designer-sidebar-tab" data-ui-sref-active="active"
- data-ui-sref="workspace.composition.deployment"
- tooltips tooltip-class="tooltip-custom tab-tooltip" tooltip-content="Deployment Artifacts"
- data-tests-id="deployment-artifact-tab"
- data-ng-if="!isPNF() && !isConfiguration() && !(isComponentInstanceSelected() && currentComponent.selectedInstance.isServiceProxy())"
- data-ng-class="{'disabled': disabledTabs}">
- <div class="i-sdc-designer-sidebar-tab-icon sprite-new deployment-artifacts"></div>
- </button>
- <button tooltips tooltip-class="tooltip-custom tab-tooltip"
- tooltip-content="{{selectedComponent.isResource() || (isComponentInstanceSelected() && currentComponent.selectedInstance.isServiceProxy()) ? 'Properties and Attributes': 'Inputs'}}"
- class="i-sdc-designer-sidebar-tab" data-ui-sref-active="active"
- data-ui-sref="workspace.composition.properties"
- data-tests-id="properties-and-attributes-tab"
- data-ng-class="{'disabled': disabledTabs}">
- <div class="i-sdc-designer-sidebar-tab-icon sprite-new"
- ng-class="selectedComponent.isResource() || (isComponentInstanceSelected() && currentComponent.selectedInstance.isServiceProxy()) ? 'properties': 'inputs'"></div>
- </button>
- <button class="i-sdc-designer-sidebar-tab" data-ui-sref-active="active"
- data-ui-sref="workspace.composition.artifacts"
- data-ng-if="!isConfiguration() && !(isComponentInstanceSelected() && currentComponent.selectedInstance.isServiceProxy())"
- tooltips tooltip-class="tooltip-custom tab-tooltip" tooltip-content="Information Artifacts"
- data-ng-class="{'disabled': disabledTabs}">
- <div class="i-sdc-designer-sidebar-tab-icon sprite-new information-artifacts"></div>
- </button>
- <button data-ng-if="!selectedComponent.isService() || (isComponentInstanceSelected() && currentComponent.selectedInstance.isServiceProxy())" class="i-sdc-designer-sidebar-tab"
- data-ui-sref-active="active" ui-sref="workspace.composition.relations"
- tooltips tooltip-class="tooltip-custom tab-tooltip tooltip-rightside"
- data-tests-id="requirements-and-capabilities"
- tooltip-content="Requirements and Capabilities"
- data-ng-class="{'disabled': disabledTabs}">
- <div class="i-sdc-designer-sidebar-tab-icon sprite-new relations"></div>
- </button>
- <button data-ng-if="selectedComponent.isService() && !(isComponentInstanceSelected() && currentComponent.selectedInstance.isServiceProxy())" class="i-sdc-designer-sidebar-tab"
- data-ui-sref-active="active" ui-sref="workspace.composition.api" data-tests-id="tab-api"
- tooltips tooltip-class="tooltip-custom tab-tooltip tooltip-rightside" tooltip-content="API"
- data-ng-class="{'disabled': disabledTabs}">
- <div class="i-sdc-designer-sidebar-tab-icon sprite-new api"></div>
- </button>
+ <div data-ui-view="" class="w-sdc-designer-sidebar-tab-content-view"></div>
</div>
- <div data-ui-view="" class="w-sdc-designer-sidebar-tab-content-view"></div>
+ <!-- Solution for now to support policies and groups working with Angular 2 components -->
+ <!-- isCertified not relevant for group or policy -->
+ <!-- (selectedZoneInstanceType === ZoneInstanceType.GROUP || selectedZoneInstanceType === ZoneInstanceType.POLICY) -->
+ <div ng-if="selectedZoneInstance">
+
+ <ng2-composition-panel
+ [is-loading]="isLoading"
+ [is-view-only]="isViewOnly || isCanvasTagging"
+ [selected-zone-instance-name]="selectedZoneInstance.instanceData.name"
+ [selected-zone-instance-id]="selectedZoneInstance.instanceData.uniqueId"
+ [selected-zone-instance-type]="selectedZoneInstance.type"
+ [topology-template]="currentComponent"
+ >
+ </ng2-composition-panel>
+ </div>
<loader data-display="isLoadingRightPanel" relative="true" size="medium"></loader>
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 f351450..b9bb66c 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 6e3258f..e389395 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 @@
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 033c466..9468937 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"></span>
<ng-form name="editForm" data-ng-if="isComponentInstanceSelected()">
- <select data-ng-model="editResourceVersion.changeVersion" name="changeVersion" data-tests-id="changeVersion" data-ng-disabled="$parent.isViewOnly || selectedComponent.uniqueId != editResourceVersion.allVersions[editResourceVersion.changeVersion]"
+ <select data-ng-model="editResourceVersion.changeVersion" name="changeVersion" data-tests-id="changeVersion"
+ data-ng-disabled="$parent.isViewOnly || selectedComponent.uniqueId != editResourceVersion.allVersions[editResourceVersion.changeVersion] || selectedComponent.archived"
class="i-sdc-designer-sidebar-section-content-item-value i-sdc-form-select"
- data-ng-class="{'minor': (editResourceVersion.changeVersion)%1}"
+ data-ng-class="{'minor': (editResourceVersion.changeVersion)%1, 'disabled':selectedComponent.archived}"
data-ng-change="changeResourceVersion()">
<option class="select-instance-version" data-ng-class="{'minor': key%1}"
ng-repeat="(key, value) in editResourceVersion.allVersions">{{key}}</option>
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties-view-model.ts
index efd5cfd..e3ddecd 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties-view-model.ts
+++ b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties-view-model.ts
@@ -139,9 +139,11 @@
(this.$scope.isPropertyOwner() ?
this.$scope.properties[property.parentUniqueId] :
this.$scope.properties[property.resourceInstanceUniqueId]) || [],
- this.isPropertyValueOwner()).then((updatedProperty:PropertyModel) => {
- let oldProp = _.find(this.$scope.properties[updatedProperty.resourceInstanceUniqueId], (prop:PropertyModel) => {return prop.uniqueId == updatedProperty.uniqueId;});
- oldProp.value = updatedProperty.value;
+ this.isPropertyValueOwner(), "component", property.resourceInstanceUniqueId).then((updatedProperty:PropertyModel) => {
+ if(updatedProperty){
+ let oldProp = _.find(this.$scope.properties[updatedProperty.resourceInstanceUniqueId], (prop:PropertyModel) => {return prop.uniqueId == updatedProperty.uniqueId;});
+ oldProp.value = updatedProperty.value;
+ }
});
};
@@ -224,7 +226,9 @@
return this.$filter("resourceName")(this.$scope.currentComponent.name);
default:
- return this.$filter("resourceName")((_.find(this.$scope.currentComponent.componentInstances, {uniqueId: key})).name);
+ let componentInstance = _.find(this.$scope.currentComponent.componentInstances, {uniqueId: key});
+ if(componentInstance)
+ return this.$filter("resourceName")(componentInstance.name);
}
};
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties.less b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties.less
index 41a90bf..ce5acc8 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties.less
+++ b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties.less
@@ -1,5 +1,6 @@
.w-sdc-designer-sidebar-tab-content.properties {
.i-sdc-designer-sidebar-section-content-item-property-and-attribute-label{
+ display:block;
font-weight: bold;
}
.i-sdc-designer-sidebar-section-content-item-button.update{
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment-view-model.ts
index feda7fe..9df377c 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment-view-model.ts
+++ b/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment-view-model.ts
@@ -108,7 +108,7 @@
};
private initRightTabs = ()=> {
- if (this.$scope.currentComponent.groups) {
+ if (this.$scope.currentComponent.modules) {
this.$templateCache.put("hierarchy-view.html", require('app/view-models/tabs/hierarchy/hierarchy-view.html'));
let hierarchyTab = new Tab("hierarchy-view.html", 'Sdc.ViewModels.HierarchyViewModel', 'hierarchy', this.$scope.isViewMode(), this.$scope.currentComponent, 'hierarchy');
this.$scope.tabs.push(hierarchyTab)
@@ -116,11 +116,11 @@
}
private initGraphData = ():void => {
- if(!this.$scope.component.componentInstances || !this.$scope.component.componentInstancesRelations || !this.$scope.component.groups) {
+ if(!this.$scope.component.componentInstances || !this.$scope.component.componentInstancesRelations || !this.$scope.component.modules) {
this.ComponentServiceNg2.getDeploymentGraphData(this.$scope.component).subscribe((response:ComponentGenericResponse) => {
this.$scope.component.componentInstances = response.componentInstances;
this.$scope.component.componentInstancesRelations = response.componentInstancesRelations;
- this.$scope.component.groups = response.groups;
+ this.$scope.component.modules = response.modules;
this.$scope.isLoading = false;
this.initComponent();
this.initRightTabs();
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment-view.html b/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment-view.html
index f8b5f23..1065552 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment-view.html
+++ b/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment-view.html
@@ -5,6 +5,6 @@
</div>
<div class="w-sdc-deployment-right-bar">
- <sdc-tabs tabs="tabs" is-view-only="isViewOnly" selected-tab="selectedTab"></sdc-tabs>
+ <ng1-tabs tabs="tabs" is-view-only="isViewOnly" selected-tab="selectedTab"></ng1-tabs>
</div>
</div>
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment.less b/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment.less
index 4c548c7..f51ff62 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment.less
+++ b/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment.less
@@ -10,9 +10,11 @@
.w-sdc-deployment-canvas {
.noselect;
.bg_c;
+ position: relative;
bottom: 0;
width: 100%;
height: 100%;
+ z-index: 0;
.view-mode{
background-color: #f8f8f8;
@@ -27,7 +29,6 @@
position: absolute;
right: 0px;
transition: right 0.2s;
- z-index: 10000;
top: @action_nav_height;
}
}
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal-view.html b/catalog-ui/src/app/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal-view.html
index 3367193..ff4bbd6 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal-view.html
+++ b/catalog-ui/src/app/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal-view.html
@@ -1,4 +1,4 @@
-<sdc-modal modal="modalDitributionStatus" type="classic" class="w-sdc-classic-top-line-modal" buttons="footerButtons" header="Distribution by Status" show-close-button="true">
+<ng1-modal modal="modalDitributionStatus" type="classic" class="w-sdc-classic-top-line-modal" buttons="footerButtons" header="Distribution by Status" show-close-button="true">
<div class="w-sdc-distribution-view">
<div class="w-sdc-distribution-view-header">
@@ -127,4 +127,4 @@
</div>
-</sdc-modal>
+</ng1-modal>
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts
index b03d7c4..68f7898 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts
+++ b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts
@@ -21,11 +21,13 @@
'use strict';
import * as _ from "lodash";
import {ModalsHandler, ValidationUtils, EVENTS, CHANGE_COMPONENT_CSAR_VERSION_FLAG, ComponentType, DEFAULT_ICON,
- ResourceType, ComponentState} from "app/utils";
+ ResourceType, ComponentState, instantiationType, ComponentFactory} from "app/utils";
import {CacheService, EventListenerService, ProgressService, OnboardingService} from "app/services";
-import {IAppConfigurtaion, IValidate, IMainCategory, Resource, ISubCategory,Service, ICsarComponent} from "app/models";
+import {IAppConfigurtaion, IValidate, IMainCategory, Resource, ISubCategory,Service, ICsarComponent, Component} from "app/models";
import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model";
import {Dictionary} from "lodash";
+import { PREVIOUS_CSAR_COMPONENT } from "../../../../utils/constants";
+
export class Validation {
componentNameValidationPattern:RegExp;
@@ -62,8 +64,11 @@
importCsarProgressKey:string;
browseFileLabel:string;
componentCategories:componentCategories;
+ instantiationTypes:Array<instantiationType>;
- onToscaFileChange():void;
+ save():Promise<any>;
+ revert():void;
+ onImportFileChange():void;
validateField(field:any):boolean;
validateName(isInit:boolean):void;
calculateUnique(mainCategory:string, subCategory:string):string; // Build unique string from main and sub category
@@ -74,6 +79,8 @@
openOnBoardingModal():void;
initCategoreis():void;
initEnvironmentContext():void;
+ initInstantiationTypes():void;
+ onInstantiationTypeChange():void;
updateIcon():void;
possibleToUpdateIcon():boolean;
}
@@ -101,7 +108,8 @@
'$interval',
'$filter',
'$timeout',
- 'Sdc.Services.OnboardingService'
+ 'Sdc.Services.OnboardingService',
+ 'ComponentFactory'
];
constructor(private $scope:IGeneralScope,
@@ -124,7 +132,8 @@
protected $interval:any,
private $filter:ng.IFilterService,
private $timeout:ng.ITimeoutService,
- private onBoardingService:OnboardingService) {
+ private onBoardingService:OnboardingService,
+ private ComponentFactory:ComponentFactory) {
this.initScopeValidation();
this.initScopeMethods();
@@ -146,51 +155,64 @@
this.$scope.validation.projectCodeValidationPattern = this.ProjectCodeValidationPattern;
};
- private initImportedToscaBrowseFile = ():void =>{
- // Init the decision if to show onboarding
- this.$scope.isShowOnboardingSelectionBrowse = false;
- if (this.$scope.component.isResource() &&
- this.$scope.isEditMode() &&
- (<Resource>this.$scope.component).resourceType == ResourceType.VF &&
- (<Resource>this.$scope.component).csarUUID) {
- this.$scope.isShowOnboardingSelectionBrowse = true;
- let onboardCsarFilesMap:Dictionary<Dictionary<string>> = this.cacheService.get('onboardCsarFilesMap');
- // The onboardCsarFilesMap in cache contains map of [packageId]:[vsp display name for brows]
- // if the map is empty - Do request to BE
- if(onboardCsarFilesMap) {
- if (onboardCsarFilesMap[(<Resource>this.$scope.component).csarUUID]){
- this.$scope.importedToscaBrowseFileText = onboardCsarFilesMap[(<Resource>this.$scope.component).csarUUID][(<Resource>this.$scope.component).csarVersion];
- }
- }
- if(!onboardCsarFilesMap || !this.$scope.importedToscaBrowseFileText){
+ private loadOnboardingFileCache = ():ng.IPromise<Dictionary<any>> =>{
- let onSuccess = (vsps:Array<ICsarComponent>): void =>{
- onboardCsarFilesMap = {};
- _.each(vsps, (vsp:ICsarComponent)=>{
- onboardCsarFilesMap[vsp.packageId] = onboardCsarFilesMap[vsp.packageId] || {};
- onboardCsarFilesMap[vsp.packageId][vsp.version] = vsp.vspName + " (" + vsp.version + ")";
- });
- this.cacheService.set('onboardCsarFilesMap', onboardCsarFilesMap);
- this.$scope.importedToscaBrowseFileText = onboardCsarFilesMap[(<Resource>this.$scope.component).csarUUID][(<Resource>this.$scope.component).csarVersion];
- };
+ let onboardCsarFilesMap:Dictionary<Dictionary<string>>;
+ let onSuccess = (vsps:Array<ICsarComponent>) =>{
+ onboardCsarFilesMap = {};
+ _.each(vsps, (vsp:ICsarComponent)=>{
+ onboardCsarFilesMap[vsp.packageId] = onboardCsarFilesMap[vsp.packageId] || {};
+ onboardCsarFilesMap[vsp.packageId][vsp.version] = vsp.vspName + " (" + vsp.version + ")";
+ });
+ this.cacheService.set('onboardCsarFilesMap', onboardCsarFilesMap);
+ return onboardCsarFilesMap;
+ };
+ let onError = (): void =>{
+ console.log("Error getting onboarding list");
+ };
+ return this.onBoardingService.getOnboardingVSPs().then(onSuccess, onError);
+ };
- let onError = (): void =>{
- console.log("Error getting onboarding list");
- };
+ private setImportedFileText = ():void => {
- this.onBoardingService.getOnboardingVSPs().then(onSuccess, onError);
+ if(!this.$scope.isShowOnboardingSelectionBrowse) return;
+
+ //these variables makes it easier to read this logic
+ let csarUUID:string = (<Resource>this.$scope.component).csarUUID;
+ let csarVersion:string = (<Resource>this.$scope.component).csarVersion;
+
+ let onboardCsarFilesMap:Dictionary<Dictionary<string>> = this.cacheService.get('onboardCsarFilesMap');
+ let assignFileName = ():void => {
+ if(this.$scope.component.vspArchived){
+ this.$scope.importedToscaBrowseFileText = 'VSP is archived';
+ } else {
+ this.$scope.importedToscaBrowseFileText = onboardCsarFilesMap[csarUUID][csarVersion];
}
}
- };
+
+
+ if(this.$scope.component.vspArchived || (onboardCsarFilesMap && onboardCsarFilesMap[csarUUID] && onboardCsarFilesMap[csarUUID][csarVersion])){ //check that the file name is already in cache
+ assignFileName();
+ } else {
+ this.loadOnboardingFileCache().then((onboardingFiles) => {
+ onboardCsarFilesMap = onboardingFiles;
+ this.cacheService.set('onboardCsarFilesMap', onboardingFiles);
+ assignFileName();
+ }, ()=> {});
+ }
+
+ }
+
+ isCreateModeAvailable(verifyObj:string): boolean {
+ var isCheckout:boolean = ComponentState.NOT_CERTIFIED_CHECKOUT === this.$scope.component.lifecycleState;
+ return this.$scope.isCreateMode() || (isCheckout && !verifyObj)
+ }
private initScope = ():void => {
- // Work around to change the csar version
- if (this.cacheService.get(CHANGE_COMPONENT_CSAR_VERSION_FLAG)) {
- (<Resource>this.$scope.component).csarVersion = this.cacheService.get(CHANGE_COMPONENT_CSAR_VERSION_FLAG);
- }
-
+
this.$scope.importCsarProgressKey = "importCsarProgressKey";
+
this.$scope.browseFileLabel = this.$scope.component.isResource() && (<Resource>this.$scope.component).resourceType === ResourceType.VF ? "Upload file" : "Upload VFC";
this.$scope.progressService = this.progressService;
this.$scope.componentCategories = new componentCategories();
@@ -216,9 +238,33 @@
if (this.$scope.isEditMode() && resource.resourceType == ResourceType.VF && !resource.csarUUID) {
this.$scope.isShowFileBrowse = true;
}
+ } else if(this.$scope.component.isService()){
+ // Init Instantiation types
+ this.$scope.initInstantiationTypes();
}
- this.initImportedToscaBrowseFile();
+ // Work around to change the csar version
+ if (this.cacheService.get(CHANGE_COMPONENT_CSAR_VERSION_FLAG)) {
+ //(<Resource>this.$scope.component).csarVersion = this.cacheService.get(CHANGE_COMPONENT_CSAR_VERSION_FLAG);
+ this.cacheService.remove(CHANGE_COMPONENT_CSAR_VERSION_FLAG);
+ this.$scope.updateUnsavedFileFlag(true);
+
+ if (!this.$scope.isViewMode() && this.cacheService.get(PREVIOUS_CSAR_COMPONENT)) { //keep the old component in the cache until checkout, so we dont need to pass it around
+ this.$scope.setOriginComponent(this.cacheService.get(PREVIOUS_CSAR_COMPONENT));
+ this.cacheService.remove(PREVIOUS_CSAR_COMPONENT);
+ }
+ }
+
+
+ // Init the decision if to show onboarding
+ if (this.$scope.component.isResource() && this.$scope.isEditMode() &&
+ (<Resource>this.$scope.component).resourceType == ResourceType.VF && (<Resource>this.$scope.component).csarUUID) {
+ this.$scope.isShowOnboardingSelectionBrowse = true;
+ this.setImportedFileText();
+ } else {
+ this.$scope.isShowOnboardingSelectionBrowse = false;
+ }
+
//init file extensions based on the file that was imported.
if (this.$scope.component.isResource() && (<Resource>this.$scope.component).importedFile) {
@@ -231,11 +277,14 @@
(<Resource>this.$scope.component).importedFile.filetype = "yaml";
this.$scope.importedFileExtension = this.sdcConfig.toscaFileExtension;
}
+ this.$scope.restoreFile = angular.copy((<Resource>this.$scope.originComponent).importedFile); //create backup
} else if (this.$scope.isEditMode() && (<Resource>this.$scope.component).resourceType === ResourceType.VF) {
this.$scope.importedFileExtension = this.sdcConfig.csarFileExtension;
//(<Resource>this.$scope.component).importedFile.filetype="csar";
}
+
+
this.$scope.setValidState(true);
this.$scope.calculateUnique = (mainCategory:string, subCategory:string):string => {
@@ -252,6 +301,12 @@
this.$scope.originComponent.contactId = this.$scope.component.contactId;
}
+
+ this.$scope.$on('$destroy', () => {
+ this.EventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE_WITH_SAVE);
+ this.EventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
+ });
+
};
// Convert category string MainCategory_#_SubCategory to Array with one item (like the server except)
@@ -299,14 +354,28 @@
}
};
+ this.$scope.initInstantiationTypes = ():void => {
+ if (this.$scope.componentType === ComponentType.SERVICE) {
+ this.$scope.instantiationTypes = new Array();
+ this.$scope.instantiationTypes.push(instantiationType.A_LA_CARTE);
+ this.$scope.instantiationTypes.push(instantiationType.MACRO);
+ var instantiationTypeField:string =(<Service>this.$scope.component).instantiationType;
+ if (instantiationTypeField === ""){
+ this.$scope.instantiationTypes.push("");
+ }
+ else if (this.isCreateModeAvailable(instantiationTypeField)) {
+ (<Service>this.$scope.component).instantiationType = instantiationType.A_LA_CARTE;
+
+ }
+ }
+ };
this.$scope.initEnvironmentContext = ():void => {
if (this.$scope.componentType === ComponentType.SERVICE) {
this.$scope.environmentContextObj = this.cacheService.get('UIConfiguration').environmentContext;
var environmentContext:string =(<Service>this.$scope.component).environmentContext;
- var isCheckout:boolean = ComponentState.NOT_CERTIFIED_CHECKOUT === this.$scope.component.lifecycleState;
// In creation new service OR check outing old service without environmentContext parameter - set default value
- if(this.$scope.isCreateMode() || (isCheckout && !environmentContext)){
+ if(this.isCreateModeAvailable(environmentContext)){
(<Service>this.$scope.component).environmentContext = this.$scope.environmentContextObj.defaultValue;
}
}
@@ -320,19 +389,33 @@
};
this.$scope.openOnBoardingModal = ():void => {
+ if(this.$scope.component.vspArchived) return;
let csarUUID = (<Resource>this.$scope.component).csarUUID;
- this.ModalsHandler.openOnboadrdingModal('Update', csarUUID).then(()=> {
- // OK
- this.$scope.uploadFileChangedInGeneralTab();
- }, ()=> {
- // ERROR
- });
+ let csarVersion = (<Resource>this.$scope.component).csarVersion;
+ this.ModalsHandler.openOnboadrdingModal('Update', csarUUID, csarVersion).then((result)=> {
+
+ if(result){
+ this.ComponentFactory.getComponentWithMetadataFromServer(result.type.toUpperCase(), result.previousComponent.uniqueId).then(
+ (component:Component)=> {
+ if (result.componentCsar && component.isResource()){
+ this.cacheService.set(PREVIOUS_CSAR_COMPONENT, angular.copy(component));
+ component = this.ComponentFactory.updateComponentFromCsar(result.componentCsar, <Resource>component);
+ }
+
+ this.$scope.setComponent(component);
+ this.$scope.updateUnsavedFileFlag(true);
+ this.setImportedFileText();
+ }, ()=> {
+ // ERROR
+ });
+ }
+ }, () => {});
};
this.$scope.updateIcon = ():void => {
this.ModalsHandler.openUpdateIconModal(this.$scope.component).then((isDirty:boolean)=> {
- if(!this.$scope.isCreateMode()){
- this.$state.current.data.unsavedChanges = this.$state.current.data.unsavedChanges || isDirty;
+ if(isDirty && !this.$scope.isCreateMode()){
+ this.setUnsavedChanges(true);
}
}, ()=> {
// ERROR
@@ -340,7 +423,7 @@
};
this.$scope.possibleToUpdateIcon = ():boolean => {
- if(this.$scope.componentCategories.selectedCategory && (!this.$scope.component.isResource() || this.$scope.component.vendorName)){
+ if(this.$scope.componentCategories.selectedCategory && (!this.$scope.component.isResource() || this.$scope.component.vendorName) && !this.$scope.component.isAlreadyCertified()){
return true;
}else{
return false;
@@ -364,7 +447,6 @@
return;
}
- //?????????????????????????
let subtype:string = ComponentType.RESOURCE == this.$scope.componentType ? this.$scope.component.getComponentSubType() : undefined;
let onFailed = (response) => {
@@ -407,6 +489,55 @@
}
};
+
+ this.EventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE_WITH_SAVE, (nextState) => {
+ if (this.$state.current.data.unsavedChanges && this.$scope.isValidForm){
+ this.$scope.save().then(() => {
+ this.$scope.handleChangeLifecycleState(nextState);
+ }, () => {
+ console.error("Save failed, unable to change lifecycle state to " + nextState);
+ });
+ } else if(!this.$scope.isValidForm){
+ console.error("Form is not valid");
+ } else {
+ let newCsarVersion:string;
+ if(this.$scope.unsavedFile){
+ newCsarVersion = (<Resource>this.$scope.component).csarVersion;
+ }
+ this.$scope.handleChangeLifecycleState(nextState, newCsarVersion);
+ }
+ });
+
+
+ this.$scope.revert = ():void => {
+ //in state of import file leave the file in place
+
+ this.$scope.setComponent(this.ComponentFactory.createComponent(this.$scope.originComponent));
+
+ if (this.$scope.component.isResource() && this.$scope.restoreFile) {
+ (<Resource>this.$scope.component).importedFile = angular.copy(this.$scope.restoreFile);
+ }
+
+ this.setImportedFileText();
+ this.$scope.updateBreadcrumbs(this.$scope.component); //update on workspace
+
+ this.$scope.componentCategories.selectedCategory = this.$scope.originComponent.selectedCategory;
+ this.setUnsavedChanges(false);
+ this.$scope.updateUnsavedFileFlag(false);
+ this.$scope.editForm.$setPristine();
+ };
+
+ this.$scope.onImportFileChange = () => {
+
+ if( !this.$scope.restoreFile && this.$scope.editForm.fileElement.value && this.$scope.editForm.fileElement.value.filename || //if file started empty but we have added a new one
+ this.$scope.restoreFile && !angular.equals(this.$scope.restoreFile, this.$scope.editForm.fileElement.value)){ //or file was swapped for a new one
+ this.$scope.updateUnsavedFileFlag(true);
+ } else {
+ this.$scope.updateUnsavedFileFlag(false);
+ this.$scope.editForm.fileElement.$setPristine();
+ }
+ };
+
this.$scope.$watchCollection('component.name', (newData:any):void => {
this.$scope.validateName(false);
});
@@ -417,9 +548,10 @@
});
this.$scope.$watch("editForm.$dirty", (newVal, oldVal) => {
- if (newVal !== oldVal) {
- this.$state.current.data.unsavedChanges = newVal && !this.$scope.isCreateMode();
+ if (newVal && !this.$scope.isCreateMode()) {
+ this.setUnsavedChanges(true);
}
+
});
this.$scope.onCategoryChange = ():void => {
@@ -439,9 +571,12 @@
this.$scope.component.icon = DEFAULT_ICON;
}
};
- this.EventListenerService.registerObserverCallback(EVENTS.ON_CHECKOUT, this.$scope.reload);
- this.EventListenerService.registerObserverCallback(EVENTS.ON_REVERT, ()=>{
- this.$scope.componentCategories.selectedCategory = this.$scope.originComponent.selectedCategory;
- });
+ this.EventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.$scope.reload);
+
};
+
+ private setUnsavedChanges = (hasChanges:boolean):void => {
+ this.$state.current.data.unsavedChanges = hasChanges;
+ };
+
}
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html
index 36976c6..28b033a 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html
+++ b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html
@@ -1,5 +1,14 @@
<div include-padding="true" class="sdc-workspace-general-step">
+ <div class="w-sdc-main-container-body-content-action-buttons">
+ <div data-ng-if="unsavedFile && !isCreateMode() && !isViewMode()" class="unsaved-file-warning">
+ <span class="sprite-new sdc-warning"></span> Click save to update to the new VSP
+ </div>
+ <button class="tlv-btn blue" data-ng-if="isDesigner()" data-ng-show="isGeneralView()" data-ng-class="{'disabled' : !isValidForm || isDisableMode() || isViewMode() || isCreateMode()}"
+ data-ng-click="save()" data-tests-id="create/save" tooltips tooltip-content="Save">Save</button>
+ <span data-ng-if="isDesigner()" data-ng-class="{'disabled' :isDisableMode() || isViewMode() || isCreateMode()}" ng-click="revert()" class="sprite-new revert-btn" data-tests-id="revert"
+ data-ng-show="isGeneralView()" tooltips tooltip-content="Revert"></span>
+ </div>
<form novalidate class="w-sdc-form" name="editForm" validation-on-load form-to-validate="editForm">
<div class="w-sdc-form-section-container">
@@ -9,10 +18,13 @@
<div class="w-sdc-form-column">
<div class="upper-general-fields">
<div class="selected-icon-container" data-ng-class="{'show-only-on-over':'defaulticon'!=component.icon && !isViewMode()}">
- <div class="selected-icon-inner-container">
+ <div class="selected-icon-inner-container ">
<div class="sprite-new update-component-icon" data-ng-click="updateIcon()" data-ng-if="!isViewMode() && possibleToUpdateIcon()"></div>
<div class="i-sdc-form-item-suggested-icon large selected-icon {{component.iconSprite}} {{component.icon}}"
- data-ng-class="{ 'disable': isViewMode() || !possibleToUpdateIcon() }"
+ data-ng-class="{
+ 'disable': isViewMode() || !possibleToUpdateIcon(),
+ 'archive-component active-component-static': component.archived
+ }"
ng-model="component.icon"
tooltips tooltip-content='{{component.icon | translate}}'
>
@@ -27,7 +39,7 @@
data-ng-class="{'view-mode': isViewMode()}"
name="componentName"
data-ng-init="isCreateMode() && validateName(true)"
- data-ng-maxlength="50"
+ data-ng-maxlength="50"
data-ng-model="component.name"
type="text"
data-required
@@ -53,7 +65,7 @@
<!--------------------- CATEGORIES -------------------->
<div class="i-sdc-form-item"
- data-ng-class="{'error': validateField(editForm.category)}">
+ data-ng-class="{'error': validateField(editForm.category)}">
<loader data-display="!categories && !initCategoreis()" relative="true"></loader>
<label class="i-sdc-form-label required">Category</label>
<select class="i-sdc-form-select"
@@ -132,14 +144,17 @@
<div class="w-sdc-form-column">
<!--------------------- IMPORT TOSCA FILE USING BROWSE (ALSO VFC) -------------------->
<div class="i-sdc-form-item" ng-if="isShowFileBrowse">
+
+ <!-- // element-disabled="{{!isCreateMode()&&!(isEditMode()&&component.resourceType=='VF')&&component.vspArchived}} || {{isViewMode()}}" -->
+
<label class="i-sdc-form-label" data-ng-class="{'required':isCreateMode()}">{{browseFileLabel}}</label>
<file-upload id="fileUploadElement"
class="i-sdc-form-input"
element-name="fileElement"
- element-disabled="{{!isCreateMode()&&!(isEditMode()&&component.resourceType=='VF')}} || {{isViewMode()}}"
+ element-disabled="{{(!isCreateMode()&&!(isEditMode()&&component.resourceType=='VF'))|| isViewMode() || component.vspArchived}}"
form-element="editForm"
file-model="component.importedFile"
- on-file-changed-in-directive="uploadFileChangedInGeneralTab"
+ on-file-changed-in-directive="onImportFileChange"
extensions="{{importedFileExtension}}"
default-text="'Browse to select file'"
data-ng-class="{'error':!(isEditMode()&&component.resourceType=='VF') && (!editForm.fileElement.$valid || !component.importedFile.filename)}"></file-upload>
@@ -147,16 +162,16 @@
<!--------------------- IMPORT TOSCA FILE USING ONBOARDING -------------------->
<div class="i-sdc-form-item" ng-if="isShowOnboardingSelectionBrowse">
- <label class="i-sdc-form-label required">Select VSP</label>
- <div class="i-sdc-form-file-upload i-sdc-form-input">
- <span class="i-sdc-form-file-name" data-tests-id="filename">{{(fileModel && fileModel.filename) || importedToscaBrowseFileText}}</span>
- <div class="i-sdc-form-file-upload-x-btn" ng-click="cancel()" data-ng-show="fileModel.filename && fileModel.filename!=='' && elementDisabled!=='true'"></div>
- <input type="button" name="fileElement"/>
- <div class="file-upload-browse-btn" data-ng-click="openOnBoardingModal()" data-tests-id="browseButton">Browse</div>
- </div>
+ <label class="i-sdc-form-label required">Select VSP</label>
+ <div class="i-sdc-form-file-upload i-sdc-form-input">
+ <span class="i-sdc-form-file-name" data-ng-disabled="component.vspArchived" data-tests-id="filename">{{(fileModel && fileModel.filename) || importedToscaBrowseFileText }}</span>
+ <div class="i-sdc-form-file-upload-x-btn" ng-click="cancel()" data-ng-show="fileModel.filename && fileModel.filename!=='' && elementDisabled!=='true'"></div>
+ <input type="button" data-ng-disabled="component.vspArchived" name="fileElement" />
+ <div class="file-upload-browse-btn" data-ng-click="openOnBoardingModal()" data-ng-disabled="!component.vspArchived" data-tests-id="browseButton">Browse</div>
+ </div>
</div>
- <div class="input-error-file-upload" data-ng-show="component.importedFile && (!editForm.fileElement.$valid || !component.importedFile.filename)">
+ <div class="input-error-file-upload" data-ng-disabled="!component.archived" data-ng-show="component.importedFile && (!editForm.fileElement.$valid || !component.importedFile.filename)">
<!-- editForm.fileElement.$error.required <== Can not use this, because the browse is done from outside for the first time -->
<span ng-show="!(isEditMode()&&component.resourceType=='VF')&&!component.importedFile.filename" translate="NEW_SERVICE_RESOURCE_ERROR_TOSCA_FILE_REQUIRED"></span><!-- Required -->
<span ng-show="editForm.fileElement.$error.maxsize" translate="VALIDATION_ERROR_MAX_FILE_SIZE"></span>
@@ -283,7 +298,7 @@
</div>
<!--------------------- Resource Model Number -------------------->
- <!--------------------- ECOMPGENERATEDNAMING -------------------->
+ <!--------------------- ECOMPGENERATEDNAMING -------------------->
<div class="i-sdc-form-item"
data-ng-class="{'error': validateField(editForm.ecompGeneratedNaming)}"
@@ -307,7 +322,7 @@
<!--------------------- NAMING POLICY -------------------->
<div ng-if="component.isService()" class="i-sdc-form-item" data-ng-class="{'error': validateField(editForm.namingPolicy)}">
- <label class="i-sdc-form-label">Naming policy</label>
+ <label class="i-sdc-form-label">Naming Policy</label>
<input class="i-sdc-form-input"
name="namingPolicy"
data-ng-class="{'view-mode': isViewMode() || !component.ecompGeneratedNaming}"
@@ -389,6 +404,21 @@
</div>
<!--------------------- ENVIRONMENT CONTEXT ------------------>
+ <!--------------------- Instantiation Type -------------------->
+ <div class="i-sdc-form-item" data-ng-if="component.isService() && instantiationTypes">
+ <label class="i-sdc-form-label">Instantiation Type</label>
+ <select class="i-sdc-form-select"
+ name="instantiationType"
+ data-ng-class="{'view-mode': isViewMode()}"
+ data-ng-disabled="component.isCsarComponent()"
+ data-ng-model="component.instantiationType"
+ data-tests-id="selectInstantiationType">
+ <option ng-repeat="type in instantiationTypes">{{type}}</option>
+
+ </select>
+ </div>
+
+ <!--------------------- Instantiation Type -------------------->
<div class="meta-data" data-ng-if="component.creationDate">
<div>
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/general/general.less b/catalog-ui/src/app/view-models/workspace/tabs/general/general.less
index b9b59de..b60e4b8 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/general/general.less
+++ b/catalog-ui/src/app/view-models/workspace/tabs/general/general.less
@@ -1,5 +1,12 @@
.sdc-workspace-general-step {
display: flex;
+ flex-direction: column;
+ .w-sdc-main-container-body-content-action-buttons{
+ display: flex;
+ justify-content: flex-end;
+ align-items: center;
+ margin-bottom: 10px;
+ }
.w-sdc-form {
padding: 0;
flex-grow: 10;
@@ -26,10 +33,15 @@
width: 100px;
height: 28px;
text-align: center;
+ border-left: solid 1px #cfcfcf;
&.disabled {
cursor: default;
}
+
+ &:hover:not(.disabled) {
+ background-color: #dbdee2;
+ }
}
}
@@ -80,8 +92,7 @@
padding: 8px 0 2px 20px;
text-align: left;
background-color: @tlv_color_t;
- position: absolute;
- bottom: 0;
+ position: relative;
width: 100%;
.meta-data-item-value{
padding-bottom: 6px;
@@ -97,19 +108,19 @@
display: flex;
align-items: center;
.selected-icon-inner-container{
- height: 64px;
- width: 64px;
+ height: 60px;
+ width: 60px;
margin: 0 auto;
}
.update-component-icon{
position: relative;
float: right;
cursor: pointer;
+ z-index: 1;
}
.selected-icon{
position: relative;
top: -20px;
- z-index: -1;
&.disable{
position: inherit;
}
@@ -137,7 +148,22 @@
}
+ .unsaved-file-warning {
+ border: solid 1px #ffb81c;
+ padding: 5px 8px;
+ display: flex;
+ align-items: center;
+ color: #ffb81c;
+ margin-right: 10px;
+ border-radius: 2px;
+ .sdc-warning {
+ margin-right:4px;
+ }
+ }
+ .revert-btn {
+ margin-left: 10px;
+ }
}
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/inputs/resource-input/resource-inputs-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/inputs/resource-input/resource-inputs-view-model.ts
index 2a7cd3d..4b9d314 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/inputs/resource-input/resource-inputs-view-model.ts
+++ b/catalog-ui/src/app/view-models/workspace/tabs/inputs/resource-input/resource-inputs-view-model.ts
@@ -17,121 +17,121 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
+/*********** DEPRECATED -- replaced by prop assignments */
+// 'use strict';
+// import * as _ from "lodash";
+// import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model";
+// import {ComponentInstance, InstancesInputsOrPropertiesMapData, Resource, PropertyModel, InputModel} from "app/models";
+// import {ModalsHandler} from "app/utils";
-'use strict';
-import * as _ from "lodash";
-import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model";
-import {ComponentInstance, InstancesInputsOrPropertiesMapData, Resource, PropertyModel, InputModel} from "app/models";
-import {ModalsHandler} from "app/utils";
+// export interface IInputsViewModelScope extends IWorkspaceViewModelScope {
+// InstanceInputsProperties:InstancesInputsOrPropertiesMapData; //this is tha map object that hold the selected inputs and the inputs we already used
+// vfInstancesList:Array<ComponentInstance>;
+// component:Resource;
-export interface IInputsViewModelScope extends IWorkspaceViewModelScope {
- InstanceInputsProperties:InstancesInputsOrPropertiesMapData; //this is tha map object that hold the selected inputs and the inputs we already used
- vfInstancesList:Array<ComponentInstance>;
- component:Resource;
+// onArrowPressed():void;
+// getInputPropertiesForInstance(instanceId:string, instance:ComponentInstance):ng.IPromise<boolean> ;
+// loadInputPropertiesForInstance(instanceId:string, input:InputModel):ng.IPromise<boolean> ;
+// openEditValueModal(input:InputModel):void;
+// openEditPropertyModal(property:PropertyModel):void;
+// }
- onArrowPressed():void;
- getInputPropertiesForInstance(instanceId:string, instance:ComponentInstance):ng.IPromise<boolean> ;
- loadInputPropertiesForInstance(instanceId:string, input:InputModel):ng.IPromise<boolean> ;
- openEditValueModal(input:InputModel):void;
- openEditPropertyModal(property:PropertyModel):void;
-}
+// export class ResourceInputsViewModel {
-export class ResourceInputsViewModel {
+// static '$inject' = [
+// '$scope',
+// '$q',
+// 'ModalsHandler'
+// ];
- static '$inject' = [
- '$scope',
- '$q',
- 'ModalsHandler'
- ];
+// constructor(private $scope:IInputsViewModelScope, private $q:ng.IQService, private ModalsHandler:ModalsHandler) {
+// this.initScope();
+// }
- constructor(private $scope:IInputsViewModelScope, private $q:ng.IQService, private ModalsHandler:ModalsHandler) {
- this.initScope();
- }
+// private initScope = ():void => {
- private initScope = ():void => {
+// this.$scope.InstanceInputsProperties = new InstancesInputsOrPropertiesMapData();
+// this.$scope.vfInstancesList = this.$scope.component.componentInstances;
- this.$scope.InstanceInputsProperties = new InstancesInputsOrPropertiesMapData();
- this.$scope.vfInstancesList = this.$scope.component.componentInstances;
+// // Need to cast all inputs to InputModel for the search to work
+// let tmpInputs:Array<InputModel> = new Array<InputModel>();
+// _.each(this.$scope.component.inputs, (input):void => {
+// tmpInputs.push(new InputModel(input));
+// });
+// this.$scope.component.inputs = tmpInputs;
+// // This function is not supported for resource
+// //this.$scope.component.getComponentInputs();
- // Need to cast all inputs to InputModel for the search to work
- let tmpInputs:Array<InputModel> = new Array<InputModel>();
- _.each(this.$scope.component.inputs, (input):void => {
- tmpInputs.push(new InputModel(input));
- });
- this.$scope.component.inputs = tmpInputs;
- // This function is not supported for resource
- //this.$scope.component.getComponentInputs();
+// /*
+// * When clicking on instance input in the left or right table, this function will load all properties of the selected input
+// */
+// this.$scope.getInputPropertiesForInstance = (instanceId:string, instance:ComponentInstance):ng.IPromise<boolean> => {
+// let deferred = this.$q.defer<boolean>();
+// instance.properties = this.$scope.component.componentInstancesProperties[instanceId];
+// deferred.resolve(true);
+// return deferred.promise;
+// };
- /*
- * When clicking on instance input in the left or right table, this function will load all properties of the selected input
- */
- this.$scope.getInputPropertiesForInstance = (instanceId:string, instance:ComponentInstance):ng.IPromise<boolean> => {
- let deferred = this.$q.defer();
- instance.properties = this.$scope.component.componentInstancesProperties[instanceId];
- deferred.resolve(true);
- return deferred.promise;
- };
+// /*
+// * When clicking on instance input in the left or right table, this function will load all properties of the selected input
+// */
+// this.$scope.loadInputPropertiesForInstance = (instanceId:string, input:InputModel):ng.IPromise<boolean> => {
+// let deferred = this.$q.defer<boolean>();
- /*
- * When clicking on instance input in the left or right table, this function will load all properties of the selected input
- */
- this.$scope.loadInputPropertiesForInstance = (instanceId:string, input:InputModel):ng.IPromise<boolean> => {
- let deferred = this.$q.defer();
+// let onSuccess = (properties:Array<PropertyModel>) => {
+// input.properties = properties;
+// deferred.resolve(true);
+// };
- let onSuccess = (properties:Array<PropertyModel>) => {
- input.properties = properties;
- deferred.resolve(true);
- };
+// let onError = () => {
+// deferred.resolve(false)
+// };
- let onError = () => {
- deferred.resolve(false)
- };
+// if (!input.properties) {
+// this.$scope.component.getComponentInstanceInputProperties(instanceId, input.uniqueId).then(onSuccess, onError);
+// } else {
+// deferred.resolve(true);
+// }
+// return deferred.promise;
+// };
- if (!input.properties) {
- this.$scope.component.getComponentInstanceInputProperties(instanceId, input.uniqueId).then(onSuccess, onError);
- } else {
- deferred.resolve(true);
- }
- return deferred.promise;
- };
+// /*
+// * When pressing the arrow, we create service inputs from the inputs selected
+// */
+// this.$scope.onArrowPressed = ():void => {
+// let onSuccess = (inputsCreated:Array<InputModel>) => {
- /*
- * When pressing the arrow, we create service inputs from the inputs selected
- */
- this.$scope.onArrowPressed = ():void => {
- let onSuccess = (inputsCreated:Array<InputModel>) => {
+// //disabled all the inputs in the left table
+// _.forEach(this.$scope.InstanceInputsProperties, (properties:Array<PropertyModel>) => {
+// _.forEach(properties, (property:PropertyModel) => {
+// property.isAlreadySelected = true;
+// });
+// });
- //disabled all the inputs in the left table
- _.forEach(this.$scope.InstanceInputsProperties, (properties:Array<PropertyModel>) => {
- _.forEach(properties, (property:PropertyModel) => {
- property.isAlreadySelected = true;
- });
- });
+// // Adding color to the new inputs (right table)
+// _.forEach(inputsCreated, (input) => {
+// input.isNew = true;
+// });
- // Adding color to the new inputs (right table)
- _.forEach(inputsCreated, (input) => {
- input.isNew = true;
- });
+// // Removing color to the new inputs (right table)
+// setTimeout(() => {
+// _.forEach(inputsCreated, (input) => {
+// input.isNew = false;
+// });
+// this.$scope.$apply();
+// }, 3000);
+// };
- // Removing color to the new inputs (right table)
- setTimeout(() => {
- _.forEach(inputsCreated, (input) => {
- input.isNew = false;
- });
- this.$scope.$apply();
- }, 3000);
- };
+// this.$scope.component.createInputsFormInstances(this.$scope.InstanceInputsProperties).then(onSuccess);
+// };
- this.$scope.component.createInputsFormInstances(this.$scope.InstanceInputsProperties).then(onSuccess);
- };
+// this.$scope.openEditValueModal = (input:InputModel) => {
+// this.ModalsHandler.openEditInputValueModal(input);
+// };
- this.$scope.openEditValueModal = (input:InputModel) => {
- this.ModalsHandler.openEditInputValueModal(input);
- };
-
- this.$scope.openEditPropertyModal = (property:PropertyModel):void => {
- this.ModalsHandler.openEditPropertyModal(property, this.$scope.component, this.$scope.component.componentInstancesProperties[property.resourceInstanceUniqueId], false).then(() => {
- });
- }
- }
-}
+// this.$scope.openEditPropertyModal = (property:PropertyModel):void => {
+// this.ModalsHandler.openEditPropertyModal(property, this.$scope.component, this.$scope.component.componentInstancesProperties[property.resourceInstanceUniqueId], false).then(() => {
+// });
+// }
+// }
+// }
\ No newline at end of file
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/inputs/service-input/service-inputs-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/inputs/service-input/service-inputs-view-model.ts
index bdbc0a4..5e69f5b 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/inputs/service-input/service-inputs-view-model.ts
+++ b/catalog-ui/src/app/view-models/workspace/tabs/inputs/service-input/service-inputs-view-model.ts
@@ -17,382 +17,382 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
+/***** DEPRECATED - replaced by prop assignments */
+// 'use strict';
+// import * as _ from "lodash";
+// import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model";
+// import {ComponentInstance, InstancesInputsOrPropertiesMapData, Service, IAppMenu, InputModel, PropertyModel, InputPropertyBase} from "app/models";
+// import {DataTypesService} from "app/services";
+// import {ModalsHandler, ResourceType} from "app/utils";
-'use strict';
-import * as _ from "lodash";
-import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model";
-import {ComponentInstance, InstancesInputsOrPropertiesMapData, Service, IAppMenu, InputModel, PropertyModel, InputPropertyBase} from "app/models";
-import {DataTypesService} from "app/services";
-import {ModalsHandler, ResourceType} from "app/utils";
+// interface IServiceInputsViewModelScope extends IWorkspaceViewModelScope {
-interface IServiceInputsViewModelScope extends IWorkspaceViewModelScope {
+// vfInstancesList:Array<ComponentInstance>;
+// instanceInputsMap:InstancesInputsOrPropertiesMapData; //this is tha map object that hold the selected inputs and the inputs we already used
+// instancePropertiesMap:InstancesInputsOrPropertiesMapData;
+// component:Service;
+// sdcMenu:IAppMenu;
+// isViewOnly:boolean;
+// isArrowDisabled:boolean;
+// onArrowPressed():void;
+// checkArrowState():void;
+// loadComponentInputs():void;
+// loadInstanceInputs(instance:ComponentInstance):ng.IPromise<boolean> ;
+// loadInstanceProperties(instance:ComponentInstance):ng.IPromise<boolean> ;
+// loadInputPropertiesForInstance(instanceId:string, input:InputModel):ng.IPromise<boolean> ;
+// loadInputInputs(input:InputModel):ng.IPromise<boolean>;
+// deleteInput(input:InputModel):void
+// openEditValueModal(input:InputModel):void;
+// openSelectPropertyDataTypeViewModel(instanceId:string, property:PropertyModel):void;
+// openEditPropertyDataTypeViewModel(property:PropertyModel):void;
+// dataTypesService:DataTypesService;
+// }
- vfInstancesList:Array<ComponentInstance>;
- instanceInputsMap:InstancesInputsOrPropertiesMapData; //this is tha map object that hold the selected inputs and the inputs we already used
- instancePropertiesMap:InstancesInputsOrPropertiesMapData;
- component:Service;
- sdcMenu:IAppMenu;
- isViewOnly:boolean;
- isArrowDisabled:boolean;
- onArrowPressed():void;
- checkArrowState():void;
- loadComponentInputs():void;
- loadInstanceInputs(instance:ComponentInstance):ng.IPromise<boolean> ;
- loadInstanceProperties(instance:ComponentInstance):ng.IPromise<boolean> ;
- loadInputPropertiesForInstance(instanceId:string, input:InputModel):ng.IPromise<boolean> ;
- loadInputInputs(input:InputModel):ng.IPromise<boolean>;
- deleteInput(input:InputModel):void
- openEditValueModal(input:InputModel):void;
- openSelectPropertyDataTypeViewModel(instanceId:string, property:PropertyModel):void;
- openEditPropertyDataTypeViewModel(property:PropertyModel):void;
- dataTypesService:DataTypesService;
-}
+// export class ServiceInputsViewModel {
-export class ServiceInputsViewModel {
+// static '$inject' = [
+// '$scope',
+// '$q',
+// 'ModalsHandler',
+// 'Sdc.Services.DataTypesService'
+// ];
- static '$inject' = [
- '$scope',
- '$q',
- 'ModalsHandler',
- 'Sdc.Services.DataTypesService'
- ];
+// constructor(private $scope:IServiceInputsViewModelScope,
+// private $q:ng.IQService,
+// private ModalsHandler:ModalsHandler,
+// private DataTypesService:DataTypesService) {
+// this.initScope();
+// this.$scope.isViewOnly = this.$scope.isViewMode();
+// }
- constructor(private $scope:IServiceInputsViewModelScope,
- private $q:ng.IQService,
- private ModalsHandler:ModalsHandler,
- private DataTypesService:DataTypesService) {
- this.initScope();
- this.$scope.isViewOnly = this.$scope.isViewMode();
- }
+// private getInputsOrPropertiesAlreadySelected = (instanceNormalizeName:string, arrayToFilter:Array<InputPropertyBase>):Array<any> => {
+// let alreadySelectedInput = [];
+// _.forEach(arrayToFilter, (inputOrProperty:InputPropertyBase) => {
+// let expectedServiceInputName = instanceNormalizeName + '_' + inputOrProperty.name;
+// let inputAlreadyInService = _.find(this.$scope.component.inputs, (serviceInput:InputModel) => {
+// //Checking if the input prefix is the instance name + '_' + property/input name (prefix because we don't need to check full name for complex dataType)
+// return serviceInput.name.substring(0, expectedServiceInputName.length) === expectedServiceInputName;
+// });
+// if (inputAlreadyInService) {
+// inputOrProperty.isAlreadySelected = true;
+// alreadySelectedInput.push(inputOrProperty);
+// } else {
+// inputOrProperty.isAlreadySelected = false;
+// }
+// });
+// return alreadySelectedInput;
+// };
- private getInputsOrPropertiesAlreadySelected = (instanceNormalizeName:string, arrayToFilter:Array<InputPropertyBase>):Array<any> => {
- let alreadySelectedInput = [];
- _.forEach(arrayToFilter, (inputOrProperty:InputPropertyBase) => {
- let expectedServiceInputName = instanceNormalizeName + '_' + inputOrProperty.name;
- let inputAlreadyInService = _.find(this.$scope.component.inputs, (serviceInput:InputModel) => {
- //Checking if the input prefix is the instance name + '_' + property/input name (prefix because we don't need to check full name for complex dataType)
- return serviceInput.name.substring(0, expectedServiceInputName.length) === expectedServiceInputName;
- });
- if (inputAlreadyInService) {
- inputOrProperty.isAlreadySelected = true;
- alreadySelectedInput.push(inputOrProperty);
- } else {
- inputOrProperty.isAlreadySelected = false;
- }
- });
- return alreadySelectedInput;
- };
+// /*
+// * When loading the screen again, we need to disabled the inputs that already created on the service,
+// * we do that by comparing the service input name, to the instance name + '_' + the resource instance input name.
+// */
+// private disableEnableSelectedInputsOrPropertiesOnInit = (instance:ComponentInstance):void => {
- /*
- * When loading the screen again, we need to disabled the inputs that already created on the service,
- * we do that by comparing the service input name, to the instance name + '_' + the resource instance input name.
- */
- private disableEnableSelectedInputsOrPropertiesOnInit = (instance:ComponentInstance):void => {
+// if (instance.originType === ResourceType.VF) {
+// this.$scope.instanceInputsMap[instance.uniqueId] = this.getInputsOrPropertiesAlreadySelected(instance.normalizedName, instance.inputs);
+// } else {
+// this.$scope.instancePropertiesMap[instance.uniqueId] = this.getInputsOrPropertiesAlreadySelected(instance.normalizedName, instance.properties);
+// }
+// };
- if (instance.originType === ResourceType.VF) {
- this.$scope.instanceInputsMap[instance.uniqueId] = this.getInputsOrPropertiesAlreadySelected(instance.normalizedName, instance.inputs);
- } else {
- this.$scope.instancePropertiesMap[instance.uniqueId] = this.getInputsOrPropertiesAlreadySelected(instance.normalizedName, instance.properties);
- }
- };
+// /*
+// * Enable Input/Property after delete
+// */
+// private enableInputsAfterDelete = (propertiesOrInputsDeletes:Array<InputPropertyBase>):void => {
- /*
- * Enable Input/Property after delete
- */
- private enableInputsAfterDelete = (propertiesOrInputsDeletes:Array<InputPropertyBase>):void => {
+// _.forEach(propertiesOrInputsDeletes, (deletedInputInput:InputPropertyBase) => { //Enable all component instance inputs deleted
- _.forEach(propertiesOrInputsDeletes, (deletedInputInput:InputPropertyBase) => { //Enable all component instance inputs deleted
+// let inputOrPropertyDeleted:InputPropertyBase = _.find(this.$scope.instanceInputsMap[deletedInputInput.componentInstanceId], (inputOrProperty:InputPropertyBase) => {
+// return inputOrProperty.uniqueId === deletedInputInput.uniqueId;
+// });
+// inputOrPropertyDeleted.isAlreadySelected = false;
+// delete _.remove(this.$scope.instanceInputsMap[deletedInputInput.componentInstanceId], {uniqueId: inputOrPropertyDeleted.uniqueId})[0];
+// });
+// };
- let inputOrPropertyDeleted:InputPropertyBase = _.find(this.$scope.instanceInputsMap[deletedInputInput.componentInstanceId], (inputOrProperty:InputPropertyBase) => {
- return inputOrProperty.uniqueId === deletedInputInput.uniqueId;
- });
- inputOrPropertyDeleted.isAlreadySelected = false;
- delete _.remove(this.$scope.instanceInputsMap[deletedInputInput.componentInstanceId], {uniqueId: inputOrPropertyDeleted.uniqueId})[0];
- });
- };
+// /*
+// * Enable Input/Property after delete
+// */
+// private enablePropertiesAfterDelete = (propertiesOrInputsDeletes:Array<InputPropertyBase>):void => {
- /*
- * Enable Input/Property after delete
- */
- private enablePropertiesAfterDelete = (propertiesOrInputsDeletes:Array<InputPropertyBase>):void => {
+// _.forEach(propertiesOrInputsDeletes, (deletedInputInput:InputPropertyBase) => { //Enable all component instance inputs deleted
+// let componentInstance = _.find(this.$scope.vfInstancesList, (instance:ComponentInstance) => {
+// return instance.uniqueId === deletedInputInput.componentInstanceId;
+// });
+// let inputOrPropertyDeleted:InputPropertyBase = _.find(this.$scope.instancePropertiesMap[deletedInputInput.componentInstanceId], (inputOrProperty:InputPropertyBase) => {
+// return inputOrProperty.uniqueId === deletedInputInput.uniqueId;
+// });
- _.forEach(propertiesOrInputsDeletes, (deletedInputInput:InputPropertyBase) => { //Enable all component instance inputs deleted
- let componentInstance = _.find(this.$scope.vfInstancesList, (instance:ComponentInstance) => {
- return instance.uniqueId === deletedInputInput.componentInstanceId;
- });
- let inputOrPropertyDeleted:InputPropertyBase = _.find(this.$scope.instancePropertiesMap[deletedInputInput.componentInstanceId], (inputOrProperty:InputPropertyBase) => {
- return inputOrProperty.uniqueId === deletedInputInput.uniqueId;
- });
+// let expectedName = componentInstance.normalizedName + '_' + inputOrPropertyDeleted.name;
+// let isAnotherInputExist = _.find(this.$scope.component.inputs, (input:InputModel) => {
+// return input.name.substring(0, expectedName.length) === expectedName;
+// });
+// if (!isAnotherInputExist) {
+// inputOrPropertyDeleted.isAlreadySelected = false;
+// delete _.remove(this.$scope.instancePropertiesMap[deletedInputInput.componentInstanceId], {uniqueId: inputOrPropertyDeleted.uniqueId})[0];
+// }
+// });
+// };
- let expectedName = componentInstance.normalizedName + '_' + inputOrPropertyDeleted.name;
- let isAnotherInputExist = _.find(this.$scope.component.inputs, (input:InputModel) => {
- return input.name.substring(0, expectedName.length) === expectedName;
- });
- if (!isAnotherInputExist) {
- inputOrPropertyDeleted.isAlreadySelected = false;
- delete _.remove(this.$scope.instancePropertiesMap[deletedInputInput.componentInstanceId], {uniqueId: inputOrPropertyDeleted.uniqueId})[0];
- }
- });
- };
+// private initScope = ():void => {
- private initScope = ():void => {
+// this.$scope.instanceInputsMap = new InstancesInputsOrPropertiesMapData();
+// this.$scope.instancePropertiesMap = new InstancesInputsOrPropertiesMapData();
+// this.$scope.isLoading = true;
+// this.$scope.isArrowDisabled = true;
+// // Why do we need this? we call this later.
+// //this.$scope.component.getComponentInputs();
- this.$scope.instanceInputsMap = new InstancesInputsOrPropertiesMapData();
- this.$scope.instancePropertiesMap = new InstancesInputsOrPropertiesMapData();
- this.$scope.isLoading = true;
- this.$scope.isArrowDisabled = true;
- // Why do we need this? we call this later.
- //this.$scope.component.getComponentInputs();
+// let onSuccess = (componentInstances:Array<ComponentInstance>) => {
+// console.log("component instances loaded: ", componentInstances);
+// this.$scope.vfInstancesList = componentInstances;
+// this.$scope.isLoading = false;
+// };
- let onSuccess = (componentInstances:Array<ComponentInstance>) => {
- console.log("component instances loaded: ", componentInstances);
- this.$scope.vfInstancesList = componentInstances;
- this.$scope.isLoading = false;
- };
+// //This function will get al component instance for the left table - in
+// // future the instances will be filter according to search text
+// this.$scope.component.getComponentInstancesFilteredByInputsAndProperties().then(onSuccess);
- //This function will get al component instance for the left table - in
- // future the instances will be filter according to search text
- this.$scope.component.getComponentInstancesFilteredByInputsAndProperties().then(onSuccess);
+// // This function will get the service inputs for the right table
+// this.$scope.component.getComponentInputs();
- // This function will get the service inputs for the right table
- this.$scope.component.getComponentInputs();
+// /*
+// * When clicking on instance in the left table, this function will load all instance inputs
+// */
+// this.$scope.loadInstanceInputs = (instance:ComponentInstance):ng.IPromise<boolean> => {
+// let deferred = this.$q.defer<boolean>();
- /*
- * When clicking on instance in the left table, this function will load all instance inputs
- */
- this.$scope.loadInstanceInputs = (instance:ComponentInstance):ng.IPromise<boolean> => {
- let deferred = this.$q.defer();
+// let onSuccess = (inputs:Array<InputModel>) => {
+// instance.inputs = inputs;
+// this.disableEnableSelectedInputsOrPropertiesOnInit(instance);
+// deferred.resolve(true);
+// };
- let onSuccess = (inputs:Array<InputModel>) => {
- instance.inputs = inputs;
- this.disableEnableSelectedInputsOrPropertiesOnInit(instance);
- deferred.resolve(true);
- };
+// let onError = () => {
+// deferred.resolve(false);
+// };
- let onError = () => {
- deferred.resolve(false);
- };
+// if (!instance.inputs) {
+// this.$scope.component.getComponentInstanceInputs(instance.uniqueId, instance.componentUid).then(onSuccess, onError);
+// //this.disableEnableSelectedInputs(instance);
+// } else {
+// deferred.resolve(true);
+// }
+// return deferred.promise;
+// };
- if (!instance.inputs) {
- this.$scope.component.getComponentInstanceInputs(instance.uniqueId, instance.componentUid).then(onSuccess, onError);
- //this.disableEnableSelectedInputs(instance);
- } else {
- deferred.resolve(true);
- }
- return deferred.promise;
- };
+// this.$scope.loadInstanceProperties = (instance:ComponentInstance):ng.IPromise<boolean> => {
+// let deferred = this.$q.defer<boolean>();
- this.$scope.loadInstanceProperties = (instance:ComponentInstance):ng.IPromise<boolean> => {
- let deferred = this.$q.defer();
+// let onSuccess = (properties:Array<PropertyModel>) => {
+// instance.properties = properties;
+// this.disableEnableSelectedInputsOrPropertiesOnInit(instance);
+// deferred.resolve(true);
+// };
- let onSuccess = (properties:Array<PropertyModel>) => {
- instance.properties = properties;
- this.disableEnableSelectedInputsOrPropertiesOnInit(instance);
- deferred.resolve(true);
- };
+// let onError = () => {
+// deferred.resolve(false);
+// };
- let onError = () => {
- deferred.resolve(false);
- };
+// if (!instance.properties) {
+// this.$scope.component.getComponentInstanceProperties(instance.uniqueId).then(onSuccess, onError);
+// } else {
+// deferred.resolve(true);
+// }
+// return deferred.promise;
+// };
- if (!instance.properties) {
- this.$scope.component.getComponentInstanceProperties(instance.uniqueId).then(onSuccess, onError);
- } else {
- deferred.resolve(true);
- }
- return deferred.promise;
- };
-
- /*
- * When clicking on instance input in the left or right table, this function will load all properties of the selected input
- */
- this.$scope.loadInputPropertiesForInstance = (instanceId:string, input:InputModel):ng.IPromise<boolean> => {
- let deferred = this.$q.defer();
+// /*
+// * When clicking on instance input in the left or right table, this function will load all properties of the selected input
+// */
+// this.$scope.loadInputPropertiesForInstance = (instanceId:string, input:InputModel):ng.IPromise<boolean> => {
+// let deferred = this.$q.defer<boolean>();
- let onSuccess = (properties:Array<PropertyModel>) => {
- input.properties = properties;
- deferred.resolve(true);
- };
+// let onSuccess = (properties:Array<PropertyModel>) => {
+// input.properties = properties;
+// deferred.resolve(true);
+// };
- let onError = () => {
- deferred.resolve(false)
- };
+// let onError = () => {
+// deferred.resolve(false)
+// };
- if (!input.properties) {
- this.$scope.component.getComponentInstanceInputProperties(instanceId, input.uniqueId).then(onSuccess, onError);
- } else {
- deferred.resolve(true);
- }
- return deferred.promise;
- };
+// if (!input.properties) {
+// this.$scope.component.getComponentInstanceInputProperties(instanceId, input.uniqueId).then(onSuccess, onError);
+// } else {
+// deferred.resolve(true);
+// }
+// return deferred.promise;
+// };
- /*
- * When clicking on input in the right table, this function will load all inputs of the selected input
- */
- this.$scope.loadInputInputs = (input:InputModel):ng.IPromise<boolean> => {
- let deferred = this.$q.defer();
+// /*
+// * When clicking on input in the right table, this function will load all inputs of the selected input
+// */
+// this.$scope.loadInputInputs = (input:InputModel):ng.IPromise<boolean> => {
+// let deferred = this.$q.defer<boolean>();
- let onSuccess = () => {
- deferred.resolve(true);
- };
- let onError = () => {
- deferred.resolve(false);
- };
+// let onSuccess = () => {
+// deferred.resolve(true);
+// };
+// let onError = () => {
+// deferred.resolve(false);
+// };
- if (!input.inputs) { // Caching, if exists do not get it.
- this.$scope.component.getServiceInputInputsAndProperties(input.uniqueId).then(onSuccess, onError);
- } else {
- deferred.resolve(true);
- }
- return deferred.promise;
- };
+// if (!input.inputs) { // Caching, if exists do not get it.
+// this.$scope.component.getServiceInputInputsAndProperties(input.uniqueId).then(onSuccess, onError);
+// } else {
+// deferred.resolve(true);
+// }
+// return deferred.promise;
+// };
- /*
- * When pressing the arrow, we create service inputs from the inputs selected
- */
- this.$scope.onArrowPressed = ():void => {
- let onSuccess = (inputsCreated:Array<InputModel>) => {
+// /*
+// * When pressing the arrow, we create service inputs from the inputs selected
+// */
+// this.$scope.onArrowPressed = ():void => {
+// let onSuccess = (inputsCreated:Array<InputModel>) => {
- //disabled all the inputs in the left table
- _.forEach(this.$scope.instanceInputsMap, (inputs:Array<InputModel>, instanceId:string) => {
- _.forEach(inputs, (input:InputModel) => {
- input.isAlreadySelected = true;
- });
- });
- _.forEach(this.$scope.instancePropertiesMap, (properties:Array<PropertyModel>, instanceId:string) => {
- _.forEach(properties, (property:PropertyModel) => {
- property.isAlreadySelected = true;
- });
- });
- this.addColorToItems(inputsCreated);
- };
+// //disabled all the inputs in the left table
+// _.forEach(this.$scope.instanceInputsMap, (inputs:Array<InputModel>, instanceId:string) => {
+// _.forEach(inputs, (input:InputModel) => {
+// input.isAlreadySelected = true;
+// });
+// });
+// _.forEach(this.$scope.instancePropertiesMap, (properties:Array<PropertyModel>, instanceId:string) => {
+// _.forEach(properties, (property:PropertyModel) => {
+// property.isAlreadySelected = true;
+// });
+// });
+// this.addColorToItems(inputsCreated);
+// };
- let onFailed = (error:any) => {
- this.$scope.isArrowDisabled = false;
- console.log("Error declaring input/property");
- };
+// let onFailed = (error:any) => {
+// this.$scope.isArrowDisabled = false;
+// console.log("Error declaring input/property");
+// };
- this.$scope.isArrowDisabled = true;
- this.$scope.component.createInputsFormInstances(this.$scope.instanceInputsMap, this.$scope.instancePropertiesMap).then(onSuccess, onFailed);
- };
+// this.$scope.isArrowDisabled = true;
+// this.$scope.component.createInputsFormInstances(this.$scope.instanceInputsMap, this.$scope.instancePropertiesMap).then(onSuccess, onFailed);
+// };
- /* Iterates through array of selected inputs and properties and returns true if there is at least one new selection on left */
- this.$scope.checkArrowState = ()=> {
+// /* Iterates through array of selected inputs and properties and returns true if there is at least one new selection on left */
+// this.$scope.checkArrowState = ()=> {
- let newInputSelected:boolean = _.some(this.$scope.instanceInputsMap, (inputs:Array<InputModel>) => {
- return _.some(inputs, (input:InputModel)=> {
- return input.isAlreadySelected === false;
- });
- });
+// let newInputSelected:boolean = _.some(this.$scope.instanceInputsMap, (inputs:Array<InputModel>) => {
+// return _.some(inputs, (input:InputModel)=> {
+// return input.isAlreadySelected === false;
+// });
+// });
- let newPropSelected:boolean = _.some(this.$scope.instancePropertiesMap, (properties:Array<PropertyModel>) => {
- return _.some(properties, (property:PropertyModel) => {
- return property.isAlreadySelected === false;
- });
- });
+// let newPropSelected:boolean = _.some(this.$scope.instancePropertiesMap, (properties:Array<PropertyModel>) => {
+// return _.some(properties, (property:PropertyModel) => {
+// return property.isAlreadySelected === false;
+// });
+// });
- this.$scope.isArrowDisabled = !(newInputSelected || newPropSelected);
+// this.$scope.isArrowDisabled = !(newInputSelected || newPropSelected);
- };
+// };
- this.$scope.deleteInput = (inputToDelete:InputModel):void => {
+// this.$scope.deleteInput = (inputToDelete:InputModel):void => {
- let onDelete = ():void => {
+// let onDelete = ():void => {
- let onSuccess = (deletedInput:InputModel):void => {
- if (deletedInput.inputs && deletedInput.inputs.length > 0) { // Enable input declared from input
- this.enableInputsAfterDelete(deletedInput.inputs);
- }
+// let onSuccess = (deletedInput:InputModel):void => {
+// if (deletedInput.inputs && deletedInput.inputs.length > 0) { // Enable input declared from input
+// this.enableInputsAfterDelete(deletedInput.inputs);
+// }
- if (deletedInput.properties && deletedInput.properties.length > 0) { // Enable properties
- this.enablePropertiesAfterDelete(deletedInput.properties);
- }
- deletedInput.isDeleteDisabled = false;
- this.$scope.checkArrowState();
+// if (deletedInput.properties && deletedInput.properties.length > 0) { // Enable properties
+// this.enablePropertiesAfterDelete(deletedInput.properties);
+// }
+// deletedInput.isDeleteDisabled = false;
+// this.$scope.checkArrowState();
- };
+// };
- let onFailed = (error:any):void => {
- console.log("Error deleting input");
- inputToDelete.isDeleteDisabled = false;
- };
+// let onFailed = (error:any):void => {
+// console.log("Error deleting input");
+// inputToDelete.isDeleteDisabled = false;
+// };
- inputToDelete.isDeleteDisabled = true;
- this.addColorToItems([inputToDelete]);
- this.$scope.component.deleteServiceInput(inputToDelete.uniqueId).then((deletedInput:InputModel):void => {
- onSuccess(deletedInput);
- }, onFailed);
- };
+// inputToDelete.isDeleteDisabled = true;
+// this.addColorToItems([inputToDelete]);
+// this.$scope.component.deleteServiceInput(inputToDelete.uniqueId).then((deletedInput:InputModel):void => {
+// onSuccess(deletedInput);
+// }, onFailed);
+// };
- // Get confirmation modal text from menu.json
- let state = "deleteInput";
- let title:string = this.$scope.sdcMenu.alertMessages[state].title;
- let message:string = this.$scope.sdcMenu.alertMessages[state].message.format([inputToDelete.name]);
+// // Get confirmation modal text from menu.json
+// let state = "deleteInput";
+// let title:string = this.$scope.sdcMenu.alertMessages[state].title;
+// let message:string = this.$scope.sdcMenu.alertMessages[state].message.format([inputToDelete.name]);
- // Open confirmation modal
- this.ModalsHandler.openAlertModal(title, message).then(onDelete);
- };
+// // Open confirmation modal
+// this.ModalsHandler.openAlertModal(title, message).then(onDelete);
+// };
- this.$scope.openEditValueModal = (input:InputModel) => {
- this.ModalsHandler.openEditInputValueModal(input);
- };
+// this.$scope.openEditValueModal = (input:InputModel) => {
+// this.ModalsHandler.openEditInputValueModal(input);
+// };
- this.$scope.openSelectPropertyDataTypeViewModel = (instanceId:string, property:PropertyModel) => {
- //to open the select data type modal
- let selectedInstance = _.find(this.$scope.vfInstancesList, {uniqueId: instanceId});
- this.DataTypesService.selectedInstance = selectedInstance; //set the selected instance on the service for compering the input name on the service & the complex property
- this.DataTypesService.selectedComponentInputs = this.$scope.component.inputs; // set all the service inputs on the data type service
- let filteredPropertiesMap = _.filter(this.$scope.instancePropertiesMap[instanceId], (instanceProperty)=> {
- return instanceProperty.name == property.name;
- });//get all properties under the specific property
- this.DataTypesService.selectedPropertiesName = property.propertiesName;
+// this.$scope.openSelectPropertyDataTypeViewModel = (instanceId:string, property:PropertyModel) => {
+// //to open the select data type modal
+// let selectedInstance = _.find(this.$scope.vfInstancesList, {uniqueId: instanceId});
+// this.DataTypesService.selectedInstance = selectedInstance; //set the selected instance on the service for compering the input name on the service & the complex property
+// this.DataTypesService.selectedComponentInputs = this.$scope.component.inputs; // set all the service inputs on the data type service
+// let filteredPropertiesMap = _.filter(this.$scope.instancePropertiesMap[instanceId], (instanceProperty)=> {
+// return instanceProperty.name == property.name;
+// });//get all properties under the specific property
+// this.DataTypesService.selectedPropertiesName = property.propertiesName;
- this.ModalsHandler.openSelectDataTypeModal(property, this.$scope.component, this.$scope.component.properties, filteredPropertiesMap).then((selectedProperty:PropertyModel)=> {
- if (selectedProperty && selectedProperty.propertiesName) {
- let propertyToUpdate:PropertyModel = _.find(selectedInstance.properties, {uniqueId: selectedProperty.uniqueId});
- let existingProperty:PropertyModel = (<PropertyModel>_.find(this.$scope.instancePropertiesMap[instanceId], {uniqueId: propertyToUpdate.uniqueId}));
+// this.ModalsHandler.openSelectDataTypeModal(property, this.$scope.component, this.$scope.component.properties, filteredPropertiesMap).then((selectedProperty:PropertyModel)=> {
+// if (selectedProperty && selectedProperty.propertiesName) {
+// let propertyToUpdate:PropertyModel = _.find(selectedInstance.properties, {uniqueId: selectedProperty.uniqueId});
+// let existingProperty:PropertyModel = (<PropertyModel>_.find(this.$scope.instancePropertiesMap[instanceId], {uniqueId: propertyToUpdate.uniqueId}));
- if (existingProperty) {
- existingProperty.propertiesName = selectedProperty.propertiesName;
- existingProperty.input = selectedProperty.input;
- existingProperty.isAlreadySelected = false;
- } else {
- propertyToUpdate.propertiesName = selectedProperty.propertiesName;
- propertyToUpdate.input = selectedProperty.input;
- this.$scope.instancePropertiesMap[instanceId].push(propertyToUpdate);
+// if (existingProperty) {
+// existingProperty.propertiesName = selectedProperty.propertiesName;
+// existingProperty.input = selectedProperty.input;
+// existingProperty.isAlreadySelected = false;
+// } else {
+// propertyToUpdate.propertiesName = selectedProperty.propertiesName;
+// propertyToUpdate.input = selectedProperty.input;
+// this.$scope.instancePropertiesMap[instanceId].push(propertyToUpdate);
- }
- this.$scope.checkArrowState();
+// }
+// this.$scope.checkArrowState();
- }
- });
- };
+// }
+// });
+// };
- this.$scope.openEditPropertyDataTypeViewModel = (property:PropertyModel)=> {
- this.ModalsHandler.openEditPropertyModal(property, this.$scope.component, this.$scope.component.properties, false).then(() => {
- });
- }
- };
+// this.$scope.openEditPropertyDataTypeViewModel = (property:PropertyModel)=> {
+// this.ModalsHandler.openEditPropertyModal(property, this.$scope.component, this.$scope.component.properties, false).then(() => {
+// });
+// }
+// };
- private addColorToItems = (inputsCreated:Array<InputModel>):void => {
+// private addColorToItems = (inputsCreated:Array<InputModel>):void => {
- // Adding color to the new inputs (right table)
- _.forEach(inputsCreated, (input) => {
- input.isNew = true;
- });
+// // Adding color to the new inputs (right table)
+// _.forEach(inputsCreated, (input) => {
+// input.isNew = true;
+// });
- // Removing color to the new inputs (right table)
- setTimeout(() => {
- _.forEach(inputsCreated, (input) => {
- input.isNew = false;
- });
- this.$scope.$apply();
- }, 3000);
- };
-}
+// // Removing color to the new inputs (right table)
+// setTimeout(() => {
+// _.forEach(inputsCreated, (input) => {
+// input.isNew = false;
+// });
+// this.$scope.$apply();
+// }, 3000);
+// };
+// }
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/properties/properties-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/properties/properties-view-model.ts
index 0360c9c..b09662d 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/properties/properties-view-model.ts
+++ b/catalog-ui/src/app/view-models/workspace/tabs/properties/properties-view-model.ts
@@ -71,7 +71,7 @@
}
private openEditPropertyModal = (property:PropertyModel):void => {
- this.ModalsHandler.openEditPropertyModal(property, this.$scope.component, this.$scope.filteredProperties, false).then((updatedProperty:PropertyModel) => {
+ this.ModalsHandler.openEditPropertyModal(property, this.$scope.component, this.$scope.filteredProperties, false, 'component', this.$scope.component.uniqueId).then((updatedProperty:PropertyModel) => {
//property = updatedProperty;
});
};
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view-model.ts
index f63ab1c..6eaae44 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view-model.ts
+++ b/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view-model.ts
@@ -93,7 +93,7 @@
_.forEach(this.$scope.filteredProperties[indexInFilteredProperties], (prop:PropertyModel)=> {
prop.readonly = true;
});
- this.ModalsHandler.openEditPropertyModal(property, this.$scope.component, this.$scope.filteredProperties[indexInFilteredProperties], false).then(() => {
+ this.ModalsHandler.openEditPropertyModal(property, this.$scope.component, this.$scope.filteredProperties[indexInFilteredProperties], false, "component", this.$scope.component.uniqueId).then(() => {
});
};
diff --git a/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts b/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts
index 9abd713..676a2d3 100644
--- a/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts
+++ b/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts
@@ -26,7 +26,7 @@
import {IUserProperties, IAppMenu, Resource, Component, Plugin, PluginsConfiguration, PluginDisplayOptions} from "app/models";
import {
WorkspaceMode, ComponentFactory, ChangeLifecycleStateHandler, Role, ComponentState, MenuItemGroup, MenuHandler,
- MenuItem, ModalsHandler, States, EVENTS, CHANGE_COMPONENT_CSAR_VERSION_FLAG, ResourceType
+ MenuItem, ModalsHandler, States, EVENTS, CHANGE_COMPONENT_CSAR_VERSION_FLAG, ResourceType, PREVIOUS_CSAR_COMPONENT
} from "app/utils";
import {
EventListenerService,
@@ -36,8 +36,11 @@
LeftPaletteLoaderService
} from "app/services";
import {FileUploadModel} from "../../directives/file-upload/file-upload";
+import {AutomatedUpgradeService} from "../../ng2/pages/automated-upgrade/automated-upgrade.service";
+import {ComponentServiceNg2} from "../../ng2/services/component-services/component.service";
import {EventBusService} from "../../ng2/services/event-bus.service";
import {PluginsService} from "../../ng2/services/plugins.service";
+import {IDependenciesServerResponse} from "../../ng2/services/responses/dependencies-server-response";
export interface IWorkspaceViewModelScope extends ng.IScope {
@@ -70,23 +73,35 @@
menuComponentTitle:string;
progressService:ProgressService;
progressMessage:string;
+ ComponentServiceNg2: ComponentServiceNg2;
// leftPanelComponents:Array<Models.Components.Component>; //this is in order to load the left panel once, and not wait long time when moving to composition
+ unsavedChanges:boolean;
+ unsavedChangesCallback:Function;
+ unsavedFile:boolean;
+
+ startProgress(message:string):void;
+ stopProgress():void;
+ updateBreadcrumbs(component:Component):void;
+ updateUnsavedFileFlag(isUnsaved:boolean):void;
showChangeStateButton():boolean;
getComponent():Component;
setComponent(component:Component):void;
+ setOriginComponent(component:Component):void;
onMenuItemPressed(state:string, params:any):ng.IPromise<boolean>;
- save():ng.IPromise<boolean>;
+ create():void;
+ save():Promise<void>;
setValidState(isValid:boolean):void;
- revert():void;
changeLifecycleState(state:string):void;
- enabledTabs():void
+ handleChangeLifecycleState(state:string, newCsarVersion?:string):void;
+ disableMenuItems():void;
+ enableMenuItems():void;
isDesigner():boolean;
isViewMode():boolean;
isEditMode():boolean;
isCreateMode():boolean;
isDisableMode():boolean;
- showFullIcons():boolean;
+ isGeneralView():boolean;
goToBreadcrumbHome():void;
onVersionChanged(selectedId:string):void;
getLatestVersion():void;
@@ -120,6 +135,8 @@
'Notification',
'$stateParams',
'Sdc.Services.ProgressService',
+ 'ComponentServiceNg2',
+ 'AutomatedUpgradeService',
'EventBusService',
'PluginsService'
];
@@ -141,8 +158,12 @@
private Notification:any,
private $stateParams:any,
private progressService:ProgressService,
+ private ComponentServiceNg2:ComponentServiceNg2,
+ private AutomatedUpgradeService:AutomatedUpgradeService,
private eventBusService:EventBusService,
private pluginsService:PluginsService) {
+
+
this.initScope();
this.initAfterScope();
@@ -170,22 +191,18 @@
private initChangeLifecycleStateButtons = ():void => {
let state = this.$scope.component.isService() && (Role.OPS == this.role || Role.GOVERNOR == this.role) ? this.$scope.component.distributionStatus : this.$scope.component.lifecycleState;
- this.$scope.changeLifecycleStateButtons = this.sdcMenu.roles[this.role].changeLifecycleStateButtons[state];
- };
+ this.$scope.changeLifecycleStateButtons = (this.sdcMenu.roles[this.role].changeLifecycleStateButtons[state] || [])[this.$scope.component.componentType.toUpperCase()];
- private isNeedSave = ():boolean => {
- return this.$scope.isEditMode() &&
- this.$state.current.data && this.$state.current.data.unsavedChanges;
};
private initLeftPalette = ():void => {
- this.LeftPaletteLoaderService.loadLeftPanel(this.$scope.component);
+ //this.LeftPaletteLoaderService.loadLeftPanel(this.$scope.component);
};
private initScope = ():void => {
this.$scope.component = this.injectComponent;
- this.initLeftPalette();
+ //this.initLeftPalette();
this.$scope.menuComponentTitle = this.$scope.component.name;
this.$scope.disabledButtons = false;
this.$scope.originComponent = this.ComponentFactory.createComponent(this.$scope.component);
@@ -202,7 +219,10 @@
this.$scope.isComposition = (this.$state.current.name.indexOf(States.WORKSPACE_COMPOSITION) > -1);
this.$scope.isDeployment = this.$state.current.name == States.WORKSPACE_DEPLOYMENT;
this.$scope.progressService = this.progressService;
- this.$scope.isActiveTopBar = true;
+ this.$scope.unsavedChanges = false;
+
+ this.EventListenerService.registerObserverCallback(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.setWorkspaceButtonState);
+ //this.EventListenerService.registerObserverCallback(EVENTS.ON_UPDATE_VSP_FILE, this.updateVspFlag);
this.$scope.getComponent = ():Component => {
return this.$scope.component;
@@ -218,19 +238,82 @@
this.$scope.component = component;
};
+ this.$scope.setOriginComponent = (component:Component):void => {
+ this.$scope.originComponent = component;
+ }
+
this.$scope.uploadFileChangedInGeneralTab = ():void => {
// In case user select browse file, and in update mode, need to disable submit for testing and checkin buttons.
if (this.$scope.isEditMode() && this.$scope.component.isResource() && (<Resource>this.$scope.component).resourceType == ResourceType.VF) {
- this.$scope.disabledButtons = true;
+ // NOTE: Commented out the disabling of the workspace buttons on CSAR updating due fix of a bug [417534]
+ // this.$scope.disabledButtons = true;
}
};
+ this.$scope.archiveComponent = ():void => {
+ this.$scope.isLoading = true;
+ const typeComponent = this.$scope.component.componentType;
+ this.ComponentServiceNg2.archiveComponent(typeComponent, this.$scope.component.uniqueId).subscribe(()=>{
+ this.$scope.isLoading = false;
+ if(this.$state.params.previousState){
+ switch(this.$state.params.previousState){
+ case 'catalog':
+ case 'dashboard':
+ this.$state.go(this.$state.params.previousState);
+ break;
+ default:
+ break;
+ }
+ }
+ this.$scope.component.archived = true;
+ this.deleteArchiveCache();
+
+ this.Notification.success({
+ message: this.$scope.component.name + ' ' + this.$filter('translate')("ARCHIVE_SUCCESS_MESSAGE_TEXT"),
+ title: this.$filter('translate')("ARCHIVE_SUCCESS_MESSAGE_TITLE")
+ });
+ }, (error) => { this.$scope.isLoading = false; });
+ }
+
+ this.$scope.restoreComponent = ():void => {
+ this.$scope.isLoading = true;
+ const typeComponent = this.$scope.component.componentType;
+ this.ComponentServiceNg2.restoreComponent(typeComponent, this.$scope.component.uniqueId).subscribe(()=>{
+ this.$scope.isLoading = false;
+ this.Notification.success({
+ message: this.$scope.component.name + ' ' + this.$filter('translate')("RESTORE_SUCCESS_MESSAGE_TEXT"),
+ title: this.$filter('translate')("RESTORE_SUCCESS_MESSAGE_TITLE")
+ });
+ });
+ this.$scope.component.archived = false;
+ this.deleteArchiveCache();
+ }
+
+ this.$scope.$on('$stateChangeStart', (event, toState, toParams, fromState, fromParams) => {
+ if(this.$scope.isEditMode()){
+ if (fromParams.id == toParams.id && this.$state.current.data && this.$state.current.data.unsavedChanges) {
+ event.preventDefault();
+ if(this.$scope.isValidForm){
+ this.$scope.save().then(() => {
+ this.$scope.onMenuItemPressed(toState.name, toParams);
+ }, ()=> {
+ console.error("Save failed, unable to navigate to " + toState.name);
+ })
+ } else {
+ console.error("Form is invalid, unable to navigate to " + toState.name);
+ }
+ }
+ }
+
+ });
+
this.$scope.$on('$stateChangeSuccess', (event, toState) => {
this.$scope.updateSelectedMenuItem(this.$state.current.name);
});
this.$scope.onMenuItemPressed = (state:string, params:any):ng.IPromise<boolean> => {
- let deferred = this.$q.defer();
+
+ let deferred:ng.IDeferred<boolean> = this.$q.defer();
let goToState = ():void => {
this.$state.go(state, Object.assign({
id: this.$scope.component.uniqueId,
@@ -239,14 +322,8 @@
}, params));
deferred.resolve(true);
};
- if (this.isNeedSave()) {
- if (this.$scope.isValidForm) {
- this.$scope.save().then(goToState);
- } else {
- console.log('form is not valid');
- deferred.reject(false);
- }
- } 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
+
+ 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
(this.$state.current.name === States.WORKSPACE_MANAGEMENT_WORKFLOW || this.$state.current.name === States.WORKSPACE_NETWORK_CALL_FLOW)) {
let onGetSuccess = (component:Component) => {
this.$scope.isLoading = false;
@@ -271,7 +348,7 @@
};
this.$scope.onVersionChanged = (selectedId:string):void => {
- if (this.$state.current.data && this.$state.current.data.unsavedChanges) {
+ if (this.$scope.isGeneralView() && this.$state.current.data.unsavedChanges) {
this.$scope.changeVersion.selectedVersion = _.find(this.$scope.versionsList, (versionObj)=> {
return versionObj.versionId === this.$scope.component.uniqueId;
});
@@ -298,37 +375,35 @@
this.$scope.onVersionChanged(_.first(this.$scope.versionsList).versionId);
};
- this.$scope.save = (state?:string):ng.IPromise<boolean> => {
- this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_CLICK);
+ this.$scope.create = () => {
+
+ this.$scope.startProgress("Creating Asset...");
+ _.first(this.$scope.leftBarTabs.menuItems).isDisabled = true;//disabled click on general tab (DE246274)
- this.progressService.initCreateComponentProgress(this.$scope.component.uniqueId);
-
- let deferred = this.$q.defer();
- let modalInstance:ng.ui.bootstrap.IModalServiceInstance;
+ // In case we import CSAR. Notify user that import VF will take long time (the create is performed in the background).
+ if (this.$scope.component.isResource() && (<Resource>this.$scope.component).csarUUID) {
+ this.Notification.info({
+ message: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_TAKES_LONG_TIME_DESCRIPTION"),
+ title: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_TAKES_LONG_TIME_TITLE")
+ });
+ }
let onFailed = () => {
+ this.$scope.stopProgress();
+ this.$scope.isLoading = false; // stop the progress.
_.first(this.$scope.leftBarTabs.menuItems).isDisabled = false;//enabled click on general tab (DE246274)
this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_ERROR);
- this.progressService.deleteProgressValue(this.$scope.component.uniqueId);
+ let modalInstance:ng.ui.bootstrap.IModalServiceInstance;
modalInstance && modalInstance.close(); // Close the modal in case it is opened.
this.$scope.component.tags = _.without(this.$scope.component.tags, this.$scope.component.name);// for fix DE246217
- this.$scope.isCreateProgress = false;
- this.$scope.isLoading = false; // stop the progress.
this.$scope.setValidState(true); // Set the form valid (if sent form is valid, the error from server).
- if (!this.$scope.isCreateMode()) {
- this.$scope.component = this.ComponentFactory.createComponent(this.$scope.originComponent); // Set the component back to the original.
- this.enableMenuItems(); // Enable the menu items (left tabs), so user can press on them.
- this.$scope.disabledButtons = false; // Enable "submit for testing" & checking buttons.
- }
-
- deferred.reject(false);
};
let onSuccessCreate = (component:Component) => {
+ this.$scope.stopProgress();
this.showSuccessNotificationMessage();
- this.progressService.deleteProgressValue(this.$scope.component.uniqueId);
// Update the components list for breadcrumbs
this.components.unshift(component);
@@ -337,99 +412,73 @@
id: component.uniqueId,
type: component.componentType.toLowerCase(),
components: this.components
- }, { inherit: false });
-
- deferred.resolve(true);
+ }, {inherit: false});
};
- let onSuccessUpdate = (component:Component) => {
- this.$scope.isCreateProgress = false;
- this.$scope.disabledButtons = false;
- this.showSuccessNotificationMessage();
- this.progressService.deleteProgressValue(this.$scope.component.uniqueId);
-
- // Stop the circle loader.
- this.$scope.isLoading = false;
-
- component.tags = _.reject(component.tags, (item)=> {
- return item === component.name
- });
-
- // Update the components list for breadcrumbs
- const bcIdx = this.MenuHandler.findBreadcrumbComponentIndex(this.components, component);
- if (bcIdx !== -1) {
- this.components[bcIdx] = component;
- this.initBreadcrumbs(); // re-calculate breadcrumbs
- }
-
- // Update the component
- this.$scope.component = component;
- this.$scope.originComponent = this.ComponentFactory.createComponent(this.$scope.component);
-
- // Enable left tags
- this.$scope.enabledTabs();
-
- if (this.$state.current.data) {
- this.$state.current.data.unsavedChanges = false;
- }
-
- deferred.resolve(true);
- };
-
- if (this.$scope.isCreateMode()) {
- this.$scope.progressMessage = "Creating Asset...";
- // CREATE MODE
- this.$scope.isCreateProgress = true;
-
- _.first(this.$scope.leftBarTabs.menuItems).isDisabled = true;//disabled click on general tab (DE246274)
-
- // Start creating the component
- this.ComponentFactory.createComponentOnServer(this.$scope.component).then(onSuccessCreate, onFailed);
-
- // In case we import CSAR. Notify user that import VF will take long time (the create is performed in the background).
- if (this.$scope.component.isResource() && (<Resource>this.$scope.component).csarUUID) {
- this.Notification.info({
- message: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_TAKES_LONG_TIME_DESCRIPTION"),
- title: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_TAKES_LONG_TIME_TITLE")
- });
- }
- } else {
- // UPDATE MODE
- this.$scope.isCreateProgress = true;
- this.$scope.progressMessage = "Updating Asset...";
- this.disableMenuItems();
+ this.ComponentFactory.createComponentOnServer(this.$scope.component).then(onSuccessCreate, onFailed);
- // Work around to change the csar version
- if (this.cacheService.get(CHANGE_COMPONENT_CSAR_VERSION_FLAG)) {
- (<Resource>this.$scope.component).csarVersion = this.cacheService.get(CHANGE_COMPONENT_CSAR_VERSION_FLAG);
- this.cacheService.remove(CHANGE_COMPONENT_CSAR_VERSION_FLAG);
- }
-
- this.$scope.component.updateComponent().then(onSuccessUpdate, onFailed);
- }
- return deferred.promise;
};
- this.$scope.revert = ():void => {
- //in state of import file leave the file in place
- if (this.$scope.component.isResource() && (<Resource>this.$scope.component).importedFile) {
- let tempFile:FileUploadModel = (<Resource>this.$scope.component).importedFile;
- this.$scope.component = this.ComponentFactory.createComponent(this.$scope.originComponent);
- (<Resource>this.$scope.component).importedFile = tempFile;
- } else {
- this.$scope.component = this.ComponentFactory.createComponent(this.$scope.originComponent);
- }
- this.EventListenerService.notifyObservers(EVENTS.ON_REVERT);
+ this.$scope.save = ():Promise<void> => {
+
+ this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_CLICK);
+
+ this.$scope.startProgress("Updating Asset...");
+ this.$scope.disableMenuItems();
+
+ return new Promise<void>((resolve, reject) => {
+ let stopProgressAndEnableUI = () => {
+ this.$scope.disabledButtons = false;
+ this.$scope.isLoading = false;
+ this.$scope.enableMenuItems();
+ this.$scope.stopProgress();
+ }
+
+ let onFailed = () => {
+ stopProgressAndEnableUI();
+ this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_ERROR);
+
+ reject();
+ };
+
+ let onSuccessUpdate = (component:Component) => {
+ stopProgressAndEnableUI();
+ this.showSuccessNotificationMessage();
+
+ component.tags = _.reject(component.tags, (item)=> {
+ return item === component.name
+ });
+
+ this.$scope.updateBreadcrumbs(component);
+
+ //update the component
+ this.$scope.setComponent(component);
+ this.$scope.originComponent = this.ComponentFactory.createComponent(this.$scope.component);
+
+ if (this.cacheService.contains(CHANGE_COMPONENT_CSAR_VERSION_FLAG)) {
+ this.cacheService.remove(CHANGE_COMPONENT_CSAR_VERSION_FLAG);
+ }
+ if (this.cacheService.contains(PREVIOUS_CSAR_COMPONENT)){
+ this.cacheService.remove(PREVIOUS_CSAR_COMPONENT);
+ }
+
+ //clear edit flags
+ this.$state.current.data.unsavedChanges = false;
+ this.$scope.unsavedFile = false;
+ resolve();
+ };
+
+ this.$scope.component.updateComponent().then(onSuccessUpdate, onFailed);
+ });
+
};
this.$scope.changeLifecycleState = (state:string):void => {
- if (this.isNeedSave() && state !== 'deleteVersion') {
- this.$scope.save().then(() => {
- changeLifecycleState(state);
- })
+ if (this.$scope.isGeneralView() && state !== 'deleteVersion') {
+ this.EventListenerService.notifyObservers(EVENTS.ON_LIFECYCLE_CHANGE_WITH_SAVE, state);
} else {
- changeLifecycleState(state);
+ this.$scope.handleChangeLifecycleState(state);
}
};
@@ -440,7 +489,7 @@
this.$state.go('dashboard');
};
- let changeLifecycleState = (state:string) => {
+ this.$scope.handleChangeLifecycleState = (state:string, newCsarVersion?:string) => {
if ('monitor' === state) {
this.$state.go('workspace.distribution');
return;
@@ -466,9 +515,9 @@
// only checkOut get the full component from server
// this.$scope.component = component;
// Work around to change the csar version
- if (this.cacheService.get(CHANGE_COMPONENT_CSAR_VERSION_FLAG)) {
- (<Resource>this.$scope.component).csarVersion = this.cacheService.get(CHANGE_COMPONENT_CSAR_VERSION_FLAG);
- }
+ if(newCsarVersion) {
+ this.cacheService.set(CHANGE_COMPONENT_CSAR_VERSION_FLAG, newCsarVersion);
+ }
//when checking out a minor version uuid remains
const bcIdx = _.findIndex(this.components, (item) => {
@@ -480,20 +529,17 @@
//when checking out a major(certified) version
this.components.unshift(component);
}
- // this.$state.go(this.$state.current.name, {
- // id: component.uniqueId,
- // type: component.componentType.toLowerCase(),
- // components: this.components
- // });
this.$scope.mode = this.initViewMode();
this.initChangeLifecycleStateButtons();
this.initVersionObject();
this.$scope.isLoading = false;
this.EventListenerService.notifyObservers(EVENTS.ON_CHECKOUT, component);
+
this.Notification.success({
message: this.$filter('translate')("CHECKOUT_SUCCESS_MESSAGE_TEXT"),
title: this.$filter('translate')("CHECKOUT_SUCCESS_MESSAGE_TITLE")
});
+
});
break;
case 'lifecycleState/CHECKIN':
@@ -528,11 +574,9 @@
});
break;
case 'lifecycleState/certify':
- defaultActionAfterChangeLifecycleState();
- this.Notification.success({
- message: this.$filter('translate')("ACCEPT_TESTING_SUCCESS_MESSAGE_TEXT"),
- title: this.$filter('translate')("ACCEPT_TESTING_SUCCESS_MESSAGE_TITLE")
- });
+
+ this.$scope.handleCertification(component);
+
break;
//DE203504 Bug Fix Start
case 'lifecycleState/startCertification':
@@ -588,11 +632,7 @@
this.ChangeLifecycleStateHandler.changeLifecycleState(this.$scope.component, data, this.$scope, onSuccess);
};
- this.$scope.enabledTabs = ():void => {
- this.$scope.leftBarTabs.menuItems.forEach((item:MenuItem) => {
- item.isDisabled = false;
- });
- };
+
this.$scope.isViewMode = ():boolean => {
return this.$scope.mode === WorkspaceMode.VIEW;
@@ -606,7 +646,7 @@
return this.$scope.mode === WorkspaceMode.VIEW && this.$scope.component.lifecycleState === ComponentState.NOT_CERTIFIED_CHECKIN;
};
- this.$scope.showFullIcons = ():boolean => {
+ this.$scope.isGeneralView = ():boolean => {
//we show revert and save icons only in general view
return this.$state.current.name === States.WORKSPACE_GENERAL;
};
@@ -697,15 +737,96 @@
};
this.$scope.reload = (component:Component):void => {
- this.$state.go(this.$state.current.name,{id:component.uniqueId},{reload:true});
+ this.$state.go(this.$state.current.name, {id: component.uniqueId}, {reload: true});
};
- this.$scope.$on('setWorkspaceTopBarActive', (event:ng.IAngularEvent, isActive:boolean) => {
- this.$scope.isActiveTopBar = isActive;
+ this.$scope.$on('$destroy', () => {
+ this.EventListenerService.unRegisterObserver(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES);
});
+
+ this.$scope.openAutomatedUpgradeModal = ():void => {
+ this.$scope.isLoading = true;
+ this.ComponentServiceNg2.getDependencies(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response:Array<IDependenciesServerResponse>)=> {
+ this.$scope.isLoading = false;
+ this.AutomatedUpgradeService.openAutomatedUpgradeModal(response, this.$scope.component, false);
+ });
+ }
+
+ this.$scope.handleCertification = (certifyComponent): void => {
+ if (this.$scope.component.getComponentSubType() === ResourceType.VF) {
+ this.ComponentServiceNg2.getDependencies(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response:Array<IDependenciesServerResponse>) => {
+ this.$scope.isLoading = false;
+
+ let isUpgradeNeeded = _.filter(response, (componentToUpgrade:IDependenciesServerResponse) => {
+ return componentToUpgrade.dependencies && componentToUpgrade.dependencies.length > 0;
+ });
+ if(isUpgradeNeeded.length === 0) {
+ this.onSuccessWithoutUpgradeNeeded();
+ return;
+ }
+ this.refreshDataAfterChangeLifecycleState(certifyComponent);
+ this.AutomatedUpgradeService.openAutomatedUpgradeModal(response, this.$scope.component, true);
+ });
+ } else {
+ this.onSuccessWithoutUpgradeNeeded();
+ }
+ }
+
+ this.$scope.disableMenuItems = () => {
+ this.$scope.leftBarTabs.menuItems.forEach((item:MenuItem) => {
+ item.isDisabled = (States.WORKSPACE_GENERAL != item.state);
+ });
+ }
+
+ this.$scope.enableMenuItems = () => {
+ this.$scope.leftBarTabs.menuItems.forEach((item:MenuItem) => {
+ item.isDisabled = false;
+ });
+ }
+
+
+ this.$scope.startProgress = (message:string):void => {
+ this.progressService.initCreateComponentProgress(this.$scope.component.uniqueId);
+ this.$scope.isCreateProgress = true;
+ this.$scope.progressMessage = message;
+ };
+
+ this.$scope.stopProgress = ():void => {
+ this.$scope.isCreateProgress = false;
+ this.progressService.deleteProgressValue(this.$scope.component.uniqueId);
+ }
+
+ this.$scope.updateBreadcrumbs = (component:Component):void => {
+ // Update the components list for breadcrumbs
+ const bcIdx = this.MenuHandler.findBreadcrumbComponentIndex(this.components, component);
+ if (bcIdx !== -1) {
+ this.components[bcIdx] = component;
+ this.initBreadcrumbs(); // re-calculate breadcrumbs
+ }
+ }
+
+ this.$scope.updateUnsavedFileFlag = (isUnsaved:boolean) => {
+ this.$scope.unsavedFile = isUnsaved;
+ }
};
+ private onSuccessWithoutUpgradeNeeded = ():void => {
+ this.$scope.isLoading = false;
+ this.Notification.success({
+ message: this.$filter('translate')("ACCEPT_TESTING_SUCCESS_MESSAGE_TEXT"),
+ title: this.$filter('translate')("ACCEPT_TESTING_SUCCESS_MESSAGE_TITLE")
+ });
+ this.$state.go('dashboard');
+ }
+ private refreshDataAfterChangeLifecycleState = (component:Component):void => {
+ this.$scope.isLoading = false;
+ this.$scope.mode = this.initViewMode();
+ this.initChangeLifecycleStateButtons();
+ this.initVersionObject();
+ this.EventListenerService.notifyObservers(EVENTS.ON_LIFECYCLE_CHANGE, component);
+ }
+
private initAfterScope = ():void => {
// In case user select csar from the onboarding modal, need to disable checkout and submit for testing.
if (this.$state.params['disableButtons'] === true) {
@@ -743,6 +864,10 @@
return tempMenuItems;
};
+ private deleteArchiveCache = () => {
+ this.cacheService.remove("archiveComponents"); //delete the cache to ensure the archive is reloaded from server
+ };
+
private initBreadcrumbs = () => {
this.components = this.cacheService.get('breadcrumbsComponents');
let breadcrumbsComponentsLvl = this.MenuHandler.generateBreadcrumbsModelFromComponents(this.components, this.$scope.component);
@@ -787,32 +912,16 @@
}
menuItem.callback = () => this.$scope[menuItem.action](menuItem.state, menuItem.params);
menuItem.isDisabled = (inCreateMode && States.WORKSPACE_GENERAL != menuItem.state) ||
- (States.WORKSPACE_DEPLOYMENT === menuItem.state && this.$scope.component.groups && this.$scope.component.groups.length === 0 && this.$scope.component.isResource());
+ (States.WORKSPACE_DEPLOYMENT === menuItem.state && this.$scope.component.modules && this.$scope.component.modules.length === 0 && this.$scope.component.isResource());
return menuItem;
});
if (this.cacheService.get('breadcrumbsComponents')) {
this.initBreadcrumbs();
- } else {
- let onSuccess = (components:Array<Component>) => {
- this.cacheService.set('breadcrumbsComponents', components);
- this.initBreadcrumbs();
- };
- this.EntityService.getCatalog().then(onSuccess); //getAllComponents() doesnt return components from catalog
}
}
- private disableMenuItems() {
- this.$scope.leftBarTabs.menuItems.forEach((item:MenuItem) => {
- item.isDisabled = (States.WORKSPACE_GENERAL != item.state);
- });
- }
- private enableMenuItems() {
- this.$scope.leftBarTabs.menuItems.forEach((item:MenuItem) => {
- item.isDisabled = false;
- });
- }
private showSuccessNotificationMessage = ():void => {
this.Notification.success({
@@ -821,4 +930,9 @@
});
};
+ private setWorkspaceButtonState = (newState:boolean, callback?:Function) => {
+ this.$scope.unsavedChanges = newState;
+ this.$scope.unsavedChangesCallback = callback;
+ }
+
}
diff --git a/catalog-ui/src/app/view-models/workspace/workspace-view.html b/catalog-ui/src/app/view-models/workspace/workspace-view.html
index 1452754..f6fed6a 100644
--- a/catalog-ui/src/app/view-models/workspace/workspace-view.html
+++ b/catalog-ui/src/app/view-models/workspace/workspace-view.html
@@ -17,9 +17,9 @@
<div class="version-container">
<span data-ng-if="!isCreateMode() && !component.isLatestVersion()" class="not-latest"></span>
- <select class="version-selector" data-ng-if="!isCreateMode()" data-tests-id="versionHeader" data-ng-model="changeVersion.selectedVersion" data-ng-class="{'disabled': !isActiveTopBar}"
- ng-options="'V'+version.versionNumber for version in versionsList" data-ng-change="onVersionChanged(changeVersion.selectedVersion.versionId)">
- </select>
+ <select class="version-selector" data-ng-if="!isCreateMode()" data-tests-id="versionHeader" data-ng-model="changeVersion.selectedVersion" data-ng-class="{'disabled': unsavedChanges}"
+ ng-options="'V'+version.versionNumber for version in versionsList" data-ng-change="onVersionChanged(changeVersion.selectedVersion.versionId)">
+ </select>
</div>
<div class="lifecycle-state">
@@ -27,6 +27,9 @@
<span class="lifecycle-state-text" data-tests-id="formlifecyclestate">{{getStatus()}}</span>
</div>
+ <div class="archive-state-label" ng-if="component.archived">
+ <div class="sprite-new archive-label" ></div>
+ </div>
<div class="progress-container" >
<top-progress class="general-view-top-progress" progress-value="progressService.getProgressValue(component.uniqueId)" progress-message="progressMessage"></top-progress>
@@ -34,47 +37,64 @@
<div class="sdc-workspace-top-bar-buttons">
- <span ng-if="!isCreateMode() && !component.isLatestVersion() && !showChangeStateButton()" [disabled]="!isActiveTopBar">Switch to the <a ng-click="getLatestVersion()">latest version</a></span>
+ <span ng-if="!isCreateMode() && !component.isLatestVersion() && !showChangeStateButton()" [disabled]="unsavedChanges">Switch to the <a ng-click="getLatestVersion()">latest version</a></span>
- <button ng-if="isDesigner() && !isCreateMode()"
- data-ng-class="{'disabled' :!isValidForm || isDisableMode() || isViewMode() || !isActiveTopBar}"
- ng-click="save()"
+ <button ng-if="isDesigner() && !isCreateMode() && component.lifecycleState === 'CERTIFIED' && (component.isService() || component.getComponentSubType() === 'VF')"
+ ng-click="openAutomatedUpgradeModal()"
class="tlv-btn blue"
- data-tests-id="create/save"
- data-ng-show="showFullIcons()"
- sdc-smart-tooltip="">Update</button>
+ data-ng-class="{'disabled' : component.archived}"
+ data-tests-id="open-upgrade-vsp-popup"
+ sdc-smart-tooltip="" prevent-double-click>{{component.isResource() ? 'Upgrade Services' : 'Update Services'}}</button>
+
<button ng-repeat="(key,button) in changeLifecycleStateButtons"
ng-click="changeLifecycleState(key)"
ng-if="showChangeStateButton() && key != 'deleteVersion'"
- data-ng-disabled="isCreateMode() || button.disabled || disabledButtons || !isValidForm || !isActiveTopBar"
+ data-ng-disabled="isCreateMode() || button.disabled || disabledButtons || !isValidForm || unsavedChanges || component.archived"
class="change-lifecycle-state-btn tlv-btn"
ng-class="$first ? 'outline green' : 'grey'"
- data-tests-id="{{button.text | testsId}}">
+ data-tests-id="{{button.text | testsId}}" prevent-double-click>
{{button.text}}
+
</button>
- <button ng-if="!isViewMode() && isCreateMode()" data-ng-disabled="!isValidForm || isDisableMode() || isLoading || !isActiveTopBar" ng-click="save()" class="tlv-btn outline green" data-tests-id="create/save">Create</button>
- <span data-ng-if="isDesigner() && !isCreateMode() && component.lifecycleState === 'NOT_CERTIFIED_CHECKOUT'" sdc-smart-tooltip=""
- data-ng-class="{'disabled' : !isValidForm || isDisableMode() || isViewMode() || !isActiveTopBar}" ng-click="changeLifecycleState('deleteVersion')"
- class="sprite-new delete-btn" data-tests-id="delete_version" sdc-smart-tooltip="">Delete</span>
+ <button ng-if="!isCreateMode() && component.archived"
+ data-ng-class="{'disabled' :!isDesigner() || !component.isLatestVersion()}"
+ ng-click="restoreComponent()"
+ class="tlv-btn blue"
+ data-tests-id="restore-component-button"
+ prevent-double-click>Restore</button>
- <span data-ng-if="isDesigner()" data-ng-class="{'disabled' :isDisableMode() || isViewMode() || !isActiveTopBar}" ng-click="revert()" class="sprite-new revert-btn" data-tests-id="revert"
- data-ng-show="showFullIcons()" sdc-smart-tooltip="">Revert</span>
+ <button ng-if="!isViewMode() && isCreateMode()" data-ng-disabled="!isValidForm || isDisableMode() || isLoading || unsavedChanges" ng-click="create()" class="tlv-btn outline green" data-tests-id="create/save">Create</button>
+
+ <span data-ng-if="isDesigner() && !isCreateMode() && component.lifecycleState === 'NOT_CERTIFIED_CHECKOUT' && !component.archived" sdc-smart-tooltip=""
+ data-ng-class="{'disabled' : !isValidForm || isDisableMode() || isViewMode() || unsavedChanges}" ng-click="changeLifecycleState('deleteVersion')"
+ class="sprite-new delete-btn" data-tests-id="delete_version" sdc-smart-tooltip="Delete" prevent-double-click>Delete</span>
+
+ <span data-ng-click = "archiveComponent()"
+ ng-model-options="{ debounce: 300 }"
+ data-ng-class="{'disabled' : !component.isLatestVersion()}"
+ data-ng-if = "isDesigner() && component.lifecycleState !== 'NOT_CERTIFIED_CHECKOUT' && !isCreateMode() && !component.archived"
+ data-tests-id="archive-component-button"
+ class="sprite-new archive-btn" sdc-smart-tooltip="Archive" prevent-double-click>Archive</span>
+
+
<span class="delimiter"></span>
- <span class="sprite-new x-btn" data-ng-click="goToBreadcrumbHome()" sdc-smart-tooltip="">Close</span>
+ <span class="sprite-new x-btn" data-ng-click="goToBreadcrumbHome()" data-ng-class="{'disabled' : unsavedChanges}" sdc-smart-tooltip="">Close</span>
</div>
</div>
<div class="w-sdc-main-container-body-content-wrapper">
- <div class="tab-title" data-ng-if="!isComposition && !isDeployment && !isPlugins">
- {{getTabTitle()}}
+ <div class="w-sdc-main-container-body-content-header">
+ <div class="tab-title" data-ng-if="!isComposition && !isDeployment && !isPlugins">
+ {{getTabTitle()}}
+ </div>
</div>
<div class="w-sdc-main-container-body-content" data-ng-class="{'third-party':thirdParty}" data-ui-view></div>
</div>
</div>
</div>
- <top-nav [hide-search]="true" [menu-model]="breadcrumbsModel" [version]="version"></top-nav>
+ <top-nav [hide-search]="true" [menu-model]="breadcrumbsModel" [version]="version" [unsaved-changes]="unsavedChanges" [unsaved-changes-callback]="unsavedChangesCallback"></top-nav>
</div>
diff --git a/catalog-ui/src/app/view-models/workspace/workspace.less b/catalog-ui/src/app/view-models/workspace/workspace.less
index 0cc30ec..b9956c6 100644
--- a/catalog-ui/src/app/view-models/workspace/workspace.less
+++ b/catalog-ui/src/app/view-models/workspace/workspace.less
@@ -128,7 +128,7 @@
.delimiter {
height: 32px;
width: 1px;
- background-color: #959595;
+ background-color: @main_color_o;
display: inline-block;
vertical-align: middle;
margin-right: 20px;
@@ -136,6 +136,16 @@
}
+ .archive-state-label {
+ padding: 7px 0 0 10px;
+ margin: 2px 0 7px 10px;
+ border-left: 1px solid @main_color_o;
+ line-height: 15px;
+ font-family: @font-opensans-bold;
+ color: @main_color_m;
+ font-size:12px;
+ }
+
.lifecycle-state {
padding: 7px 0 0 10px;
margin: 2px 0 7px 10px;
@@ -191,7 +201,26 @@
}
.w-sdc-main-container-body-content-wrapper {
overflow: auto;
- height: calc(~'100% - @{action_nav_height}')
+ height: calc(~'100% - @{action_nav_height}');
+ .w-sdc-main-container-body-content-header {
+ display: flex;
+ .tab-title {
+ flex-grow: 1;
+ }
+ .w-sdc-main-container-body-content-action-buttons {
+ margin:72px 100px 0 0;
+ > * {
+ display: inline-block;
+ vertical-align: middle;
+ }
+ .revert-btn {
+ text-indent: 100%;
+ }
+ .save-btn {
+ text-indent: 100%;
+ }
+ }
+ }
}
}
}
diff --git a/catalog-ui/src/assets/languages/en_US.json b/catalog-ui/src/assets/languages/en_US.json
index 0423967..612d14e 100644
--- a/catalog-ui/src/assets/languages/en_US.json
+++ b/catalog-ui/src/assets/languages/en_US.json
@@ -42,6 +42,7 @@
"GENERAL_LABEL_SYSTEM_NAME": "System Name:",
"GENERAL_LABEL_SOURCE_SERVICE_NAME": "Source Service Name:",
"GENERAL_LABEL_RESOURCE_CUSTOMIZATION_UUID": "Resource Customization UUID:",
+
"=========== GENERAL_TAB ===========": "",
"GENERAL_TAB_LABEL_RESOURCE_MODEL_NUMBER":"Vendor Model Number",
@@ -49,8 +50,8 @@
"GENERAL_TAB_LABEL_SERVICE_ROLE": "Service Role",
"=========== GENERAL ERROR PAGES ===========": "",
- "GENERAL_ERROR_403_TITLE": "SDC",
- "GENERAL_ERROR_403_DESCRIPTION": "Sorry, You are not authorized to view this page, Please contact the <a data-ng-href='mailto:{{mailto}}'> Service Design and Creation administrator</a> for access permission.",
+ "GENERAL_ERROR_403_TITLE": "SDC Access Denied",
+ "GENERAL_ERROR_403_DESCRIPTION": "Sorry, you are not authorized to view this page. Please visit the Portal Application to provision a user account for SDC.",
"=========== ERROR VIEW MODEL ===========": "",
"ADMIN_EMAIL": "",
@@ -425,6 +426,10 @@
"APPROVE_SUCCESS_MESSAGE_TITLE": "Approve",
"DISTRIBUTE_SUCCESS_MESSAGE_TEXT": "Distributed successfully",
"DISTRIBUTE_SUCCESS_MESSAGE_TITLE": "Distribute",
+ "RESTORE_SUCCESS_MESSAGE_TITLE":"Restore",
+ "RESTORE_SUCCESS_MESSAGE_TEXT":"successfully restored",
+ "ARCHIVE_SUCCESS_MESSAGE_TITLE":"Archive",
+ "ARCHIVE_SUCCESS_MESSAGE_TEXT":"successfully archived",
"=========== ON BOARDING MODAL INFO MESSAGES ===========": "",
"ON_BOARDING_GENERAL_INFO": "Displays a table of VSPs created using Onboarding.<br/> Each row displays details for a single VSP.<br/> When expanded you can either import CSAR files that are yet to be imported or update CSAR files that were previously imported.",
@@ -448,7 +453,28 @@
"=========== PLUGIN NOT CONNECTED ===========": "",
"PLUGIN_NOT_CONNECTED_ERROR_MAIN": "The \"{{pluginName}}\" plugin is currently unavailable.",
- "PLUGIN_NOT_CONNECTED_ERROR_SUB": "Please try again later."
+ "PLUGIN_NOT_CONNECTED_ERROR_SUB": "Please try again later.",
-
+ "=========== POLICY AND GROUPS ===========": "",
+ "ADD_TARGETS" : "Add Targets",
+ "ADD_MEMBERS" : "Add Members",
+ "=========== AUTOMATED UPGRADE ===========": "",
+ "RESOURCE_UPGRADE_TITLE" : "Upgrade Services",
+ "SERVICE_UPGRADE_TITLE" : "Update Service References",
+ "RESOURCE_UPGRADE_STATUS_TITLE" : "Upgrade Services - Status",
+ "SERVICE_UPGRADE_STATUS_TITLE" : "Update Service References - Status",
+ "RESOURCE_NOTHING_TO_UPGRADE" : "There are no services which include instance of <b>\"{{vspName}}\"</b> VF.<br/>Please close this popup window to continue your work.",
+ "SERVICE_NOTHING_TO_UPGRADE" : "There aren’t any services which include a reference to {{vspName}}.",
+ "RESOURCE_AUTOMATED_UPGRADE_WITH_COMPONENTS_TO_UPGRADE": "The following services include instance of <b>\"{{vspName}}\"</b> VF.<br/>Services eligible for upgrade are auto selected with the latest version of <b>\"{{vspName}}\" {{vspVersion}}</b>.<br/>Please de-select them if you do not want them to be upgraded",
+ "RESOURCE_AUTOMATED_UPGRADE_ALL_COMPONENTS_LOCKED": "The following services include instance of <b>\"{{vspName}}\"</b> VF, however they are locked and can not be automatically upgraded with <b>\"{{vspName}}\" {{vspVersion}}</b>.<br/>Please close this popup window to continue your work.",
+ "RESOURCE_AUTOMATED_UPGRADE_ALL_COMPONENTS_UPGRADED": "The listed services each include the <b>\"{{vspName}}\"</b> VF and have already been upgraded with the most recently certified version of the <b>{{vspName}} {{vspVersion}}</b>.<br/>Please close this popup window to continue your work.",
+ "RESOURCE_CERTIFICATION_STATUS_TEXT": "The \"{{resourceName}}\" VF was successfully updated and certified.",
+ "RESOURCE_UPGRADE_STATUS_SUCCESS": "Automated service upgrade was completed and successful.<br/>The services which are successfully upgraded are in checked-in state with version displayed below. Please close this popup window and proceed with design completion on the services",
+ "RESOURCE_UPGRADE_STATUS_FAIL": "Automated service upgrade failed.",
+ "SERVICE_UPGRADE_STATUS_SUCCESS": "Automated service upgrade was completed and successful.<br/>The services which are successfully upgraded are in checked-in state with version displayed below. Please close this popup window and proceed with design completion on the services",
+ "SERVICE_UPGRADE_STATUS_FAIL": "Automated service upgrade failed.",
+ "SERVICE_CERTIFICATION_STATUS_TEXT": "Service {{serviceName}} was successfully certified",
+ "SERVICE_AUTOMATED_UPGRADE_WITH_COMPONENTS_TO_UPGRADE": "The following services reference <b>{{vspName}}</b>.<br/> One or more of the services were not yet upgraded with the most recently certified version of <b>{{vspName}}</b>.</br>Select services from the list to upgrade them with <b>{{vspName}} {{vspVersion}}</b>.",
+ "SERVICE_AUTOMATED_UPGRADE_ALL_COMPONENTS_LOCKED": "The listed services reference <b>{{vspName}}</b>.<br/> These services were not upgraded with the most recently certified version of <b>{{vspName}}</b>. Currently they are locked from being upgraded with <b>{{vspName}} {{vspVersion}}</b>",
+ "SERVICE_AUTOMATED_UPGRADE_ALL_COMPONENTS_UPGRADED": "The listed services each reference <b>{{vspName}}</b> and have already been updated with the most recently certified version of the <b>{{vspName}} {{vspVersion}}</b>"
}
diff --git a/catalog-ui/src/assets/styles/app.less b/catalog-ui/src/assets/styles/app.less
index 638b28e..1b42aef 100644
--- a/catalog-ui/src/assets/styles/app.less
+++ b/catalog-ui/src/assets/styles/app.less
@@ -9,6 +9,7 @@
@import 'mixins_old.less';
@import 'global.less';
@import '../../../node_modules/sdc-ui/css/style.css';
+/* @import '../../../node_modules/sdc-ui/css/theme_1802.css'; */
@import 'sprite-old.less';
@import 'sprite.less';
@@ -16,6 +17,7 @@
@import 'sprite-services-icons.less';
@import 'sprite-group-icons.less';
@import 'sprite-policy-icons.less';
+@import 'archive-resouce.less';
@import 'animation.less';
@import 'buttons.less';
@@ -49,7 +51,7 @@
@import '../../app/directives/graphs-v2/composition-graph/composition-graph.less';
@import '../../app/directives/graphs-v2/deployment-graph/deployment-graph.less';
@import '../../app/directives/graphs-v2/palette/palette.less';
-@import '../../app/directives/graphs-v2/relation-menu/relation-menu.less';
+// @import '../../app/directives/graphs-v2/relation-menu/relation-menu.less';
@import '../../app/directives/capabilities-and-requirements/capabilities-requirements-list.less';
// @import '../../app/directives/graphs-v2/asset-popover/asset-popover.less';
@import '../../app/directives/info-tooltip/info-tooltip.less';
@@ -120,3 +122,4 @@
@import '../../app/view-models/workspace/tabs/interface-operation/interface-operation.less';
@import '../../app/view-models/workspace/workspace.less';
@import '../../app/view-models/workspace/tabs/plugins/plugins-context.less';
+@import 'override.less';
diff --git a/catalog-ui/src/assets/styles/archive-resouce.less b/catalog-ui/src/assets/styles/archive-resouce.less
new file mode 100644
index 0000000..ec064e0
--- /dev/null
+++ b/catalog-ui/src/assets/styles/archive-resouce.less
@@ -0,0 +1,7 @@
+.archive-resource-btn {
+ background: url('images/archive-delete/archive.svg') top left no-repeat;
+ display: inline-block;
+ width: 24px;
+ height: 24px;
+ text-indent: 100%;
+}
\ No newline at end of file
diff --git a/catalog-ui/src/assets/styles/images/archive-delete/archive.png b/catalog-ui/src/assets/styles/images/archive-delete/archive.png
new file mode 100644
index 0000000..5284a54
--- /dev/null
+++ b/catalog-ui/src/assets/styles/images/archive-delete/archive.png
Binary files differ
diff --git a/catalog-ui/src/assets/styles/images/archive-delete/archive.svg b/catalog-ui/src/assets/styles/images/archive-delete/archive.svg
new file mode 100644
index 0000000..162e5ea
--- /dev/null
+++ b/catalog-ui/src/assets/styles/images/archive-delete/archive.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg">
+ <!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch -->
+ <title>icons/versio_bar/archive</title>
+ <desc>Created with Sketch.</desc>
+ <defs></defs>
+ <g id="Symbols-" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="icons/versio_bar/archive" fill="#5A5A5A">
+ <path d="M1.96142578,9.02011447 C1.16722011,9.02011447 0,9.03344727 0,7.20846897 L0,4.06491428 C0,2.16137695 1.16722011,2 1.96142578,2 L22.0875382,2 C22.8817438,2 24.0641007,2.46750217 24.0641007,4.06491428 L24.0641007,7.20846897 C24.0641007,8.57785373 22.8817438,9.02011447 22.0875382,9.02011447 L21.0783829,9.02011447 L21.0783829,21.6395264 C21.0783829,22.4091347 20.4299479,23.0284153 19.6357422,23.0284153 L4.46949616,23.0284153 C3.67529049,23.0284153 3.02685547,22.4091347 3.02685547,21.6395264 L3.02685547,9.02011447 L1.96142578,9.02011447 Z M19,20.9406738 L19,9.00119358 L5.11112098,9.00119358 L5.11112098,20.9406738 L19,20.9406738 Z M9,13 C8.4,13 8,12.6 8,12 C8,11.4 8.4,11 9,11 L15,11 C15.6,11 16,11.4 16,12 C16,12.6 15.6,13 15,13 L9,13 Z M2.87234189,7.00119358 L21.206041,7.00119358 C21.6790502,7.00119358 22.0625,6.66540714 22.0625,6.25119358 L22.0625,4.75119358 C22.0625,4.33698001 21.6790502,4.00119358 21.206041,4.00119358 L2.87234189,4.00119358 C2.39933264,4.00119358 2.01588288,4.33698001 2.01588288,4.75119358 L2.01588288,6.25119358 C2.01588288,6.66540714 2.39933264,7.00119358 2.87234189,7.00119358 Z" id="Combined-Shape"></path>
+ </g>
+ </g>
+</svg>
\ No newline at end of file
diff --git a/catalog-ui/src/assets/styles/images/canvas-tagging-icons/group_1.svg b/catalog-ui/src/assets/styles/images/canvas-tagging-icons/group_1.svg
new file mode 100644
index 0000000..fa4e06c
--- /dev/null
+++ b/catalog-ui/src/assets/styles/images/canvas-tagging-icons/group_1.svg
@@ -0,0 +1,33 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="44" height="41">
+ <defs>
+ <filter id="groups_1-a" width="145.5%" height="145.5%" x="-22.7%" y="-13.6%" filterUnits="objectBoundingBox">
+ <feOffset dy="2" in="SourceAlpha" result="shadowOffsetOuter1"/>
+ <feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1"/>
+ <feColorMatrix in="shadowBlurOuter1" result="shadowMatrixOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
+ <feMerge>
+ <feMergeNode in="shadowMatrixOuter1"/>
+ <feMergeNode in="SourceGraphic"/>
+ </feMerge>
+ </filter>
+ <path id="groups_1-b" d="M6,4 L6,1 C6,0.4 5.6,0 5,0 C4.4,0 4,0.4 4,1 L4,4 L1,4 C0.4,4 0,4.4 0,5 C0,5.6 0.4,6 1,6 L4,6 L4,9 C4,9.6 4.4,10 5,10 C5.6,10 6,9.6 6,9 L6,6 L9,6 C9.6,6 10,5.6 10,5 C10,4.4 9.6,4 9,4 L6,4 Z"/>
+ <polygon id="groups_1-d" points="7.841 8.516 12.487 6.865 0 0 3.64 13.776 6.366 9.668 9.63 13.845 11.104 12.693"/>
+ <filter id="groups_1-c" width="196.1%" height="186.7%" x="-48.1%" y="-36.1%" filterUnits="objectBoundingBox">
+ <feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"/>
+ <feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/>
+ <feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5"/>
+ <feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/>
+ <feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/>
+ </filter>
+ </defs>
+ <g fill="none" fill-rule="evenodd" transform="translate(4 3)">
+ <g transform="translate(15 11)">
+ <path fill="#009FDB" stroke="#FFF" d="M3,0 L19,0 C20.6568542,-3.04359188e-16 22,1.34314575 22,3 L22,19 C22,20.6568542 20.6568542,22 19,22 L3,22 C1.34314575,22 2.02906125e-16,20.6568542 0,19 L0,3 C-2.02906125e-16,1.34314575 1.34314575,3.04359188e-16 3,0 Z" filter="url(#groups_1-a)"/>
+ <g transform="translate(6 6)">
+ <use fill="#FFF" xlink:href="#groups_1-b"/>
+ </g>
+ </g>
+ <use fill="#000" filter="url(#groups_1-c)" xlink:href="#groups_1-d"/>
+ <use fill="#FFF" xlink:href="#groups_1-d"/>
+ <path stroke="#000" stroke-opacity=".8" d="M8.6617598,8.75489325 L11.806255,12.7796636 L9.54386134,14.5472392 L6.39936616,10.5224689 L3.44128728,14.9806328 L-0.781456351,-1.00021852 L13.7031213,6.96320943 L8.6617598,8.75489325 Z"/>
+ </g>
+</svg>
diff --git a/catalog-ui/src/assets/styles/images/canvas-tagging-icons/group_2.svg b/catalog-ui/src/assets/styles/images/canvas-tagging-icons/group_2.svg
new file mode 100644
index 0000000..f6b1cf1
--- /dev/null
+++ b/catalog-ui/src/assets/styles/images/canvas-tagging-icons/group_2.svg
@@ -0,0 +1,33 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="45" height="44">
+ <defs>
+ <filter id="groups_2-a" width="145.5%" height="145.5%" x="-22.7%" y="-13.6%" filterUnits="objectBoundingBox">
+ <feOffset dy="2" in="SourceAlpha" result="shadowOffsetOuter1"/>
+ <feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1"/>
+ <feColorMatrix in="shadowBlurOuter1" result="shadowMatrixOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
+ <feMerge>
+ <feMergeNode in="shadowMatrixOuter1"/>
+ <feMergeNode in="SourceGraphic"/>
+ </feMerge>
+ </filter>
+ <path id="groups_2-b" d="M6,4 L6,1 C6,0.4 5.6,0 5,0 C4.4,0 4,0.4 4,1 L4,4 L1,4 C0.4,4 0,4.4 0,5 C0,5.6 0.4,6 1,6 L4,6 L4,9 C4,9.6 4.4,10 5,10 C5.6,10 6,9.6 6,9 L6,6 L9,6 C9.6,6 10,5.6 10,5 C10,4.4 9.6,4 9,4 L6,4 Z"/>
+ <path id="groups_2-d" d="M3.98190975,9.99999992 L3.09529739,8.64532799 C2.48991036,7.72034561 1.20039622,7.38287755 0.214035029,7.88996475 L0.443864811,7.77180951 C0.199079509,7.89765337 0.081702931,8.21138642 0.182488604,8.47214489 L1.40976041,11.6474128 C1.60431817,12.1507837 2.10121802,12.8626937 2.51297222,13.2203156 C2.51297222,13.2203156 4.98190975,15.2638557 4.98190975,16.03003 L4.98190975,16.9999999 L8.98190975,16.9999999 L9.98190975,14.9999999 L10.9819098,16.9999999 L11.9819098,17 L11.9819098,16.0300302 C11.9819098,15.2638559 13.4907506,12.8506759 13.4907506,12.8506759 C13.7684994,12.3815967 14,11.5552351 14,11.0065899 L14,6.9718022 C13.9819097,6.07849828 13.2225759,5.35453877 12.2856231,5.35453877 C11.8168923,5.35453877 11.4372254,5.71651852 11.4372254,6.1634131 L11.4372254,6.48657465 C11.4372254,5.59327073 10.6778916,4.86931122 9.7409389,4.86931122 C9.27220806,4.86931122 8.89254117,5.23129097 8.89254117,5.67818555 L8.89254117,6.0013471 C8.89254117,5.10804318 8.13320739,4.38408367 7.19625465,4.38408367 C6.72752382,4.38408367 6.34785693,4.74606342 6.34785693,5.192958 L6.34785693,5.51611955 C6.34785693,5.37255591 6.33251267,5.25843099 6.30286699,5.16799051 L6.04408993,1.0012141 C6.00909675,0.437760917 5.53419442,0 4.98190967,0 C4.42577449,0 3.98190967,0.447629061 3.98190967,0.999807492 L3.98190967,5 L3.98190975,9.99999992 Z M11,9.00000012 L12,9 L12,12.9999999 L11,13 L11,9.00000012 L11,9.00000012 Z M9,9.00000012 L10,9 L10,12.9999999 L9,13 L9,9.00000012 L9,9.00000012 Z M7,9.00000012 L8,9 L8,12.9999999 L7,13 L7,9.00000012 L7,9.00000012 Z"/>
+ <filter id="groups_2-c" width="186.6%" height="170.6%" x="-43.3%" y="-29.4%" filterUnits="objectBoundingBox">
+ <feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"/>
+ <feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/>
+ <feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5"/>
+ <feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/>
+ <feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/>
+ </filter>
+ </defs>
+ <g fill="none" fill-rule="evenodd" transform="translate(4 3)">
+ <g transform="translate(16 14)">
+ <path fill="#009FDB" stroke="#FFF" d="M3,0 L19,0 C20.6568542,-3.04359188e-16 22,1.34314575 22,3 L22,19 C22,20.6568542 20.6568542,22 19,22 L3,22 C1.34314575,22 2.02906125e-16,20.6568542 0,19 L0,3 C-2.02906125e-16,1.34314575 1.34314575,3.04359188e-16 3,0 Z" filter="url(#groups_2-a)"/>
+ <g transform="translate(6 6)">
+ <use fill="#FFF" xlink:href="#groups_2-b"/>
+ </g>
+ </g>
+ <use fill="#000" filter="url(#groups_2-c)" xlink:href="#groups_2-d"/>
+ <use fill="#FFF" xlink:href="#groups_2-d"/>
+ <path stroke="#000" stroke-opacity=".8" d="M3.48190972,8.32416496 L3.48190967,5 L3.48190967,0.999807491 C3.48190967,0.170429729 4.15068503,-0.5 4.98190967,-0.5 C5.80152555,-0.5 6.49196322,0.146369011 6.54312845,0.970221378 L6.729109,3.96484284 C6.87493261,3.91257008 7.03237962,3.88408367 7.19625465,3.88408367 C7.87883467,3.88408367 8.49131623,4.18500488 8.89495329,4.65876818 C9.12697419,4.47737206 9.42176446,4.36931122 9.7409389,4.36931122 C10.4235189,4.36931122 11.0360005,4.67023243 11.4396375,5.14399573 C11.6716584,4.96259961 11.9664487,4.85453877 12.2856231,4.85453877 C13.4881886,4.85453877 14.4761616,5.78959763 14.5,6.9718022 L14.5,11.0065899 C14.5,11.6413376 14.2462612,12.556081 13.9147021,13.1157516 C13.8694672,13.1880985 13.788913,13.3198554 13.6849071,13.4950007 C13.511352,13.7872659 13.3378324,14.0912197 13.1763581,14.3904728 C13.1037538,14.5250271 13.0351585,14.6557806 12.9712321,14.7818029 C12.6639479,15.3875721 12.4819098,15.8603735 12.4819098,16.0300302 L12.4819098,17.5000001 L10.6728927,17.4999999 L9.98190975,16.1180339 L9.29092675,17.4999999 L4.48190975,17.4999999 L4.48190975,16.03003 C4.48190975,15.9441015 4.22664544,15.5664829 3.80083171,15.1083367 C3.6777582,14.9759181 3.54245432,14.8374578 3.39695629,14.6944531 C3.13416835,14.4361686 2.85142222,14.1758166 2.56855227,13.9270547 C2.39897253,13.7779227 2.26768741,13.6663479 2.1851049,13.5978113 C1.71375103,13.1884251 1.16828661,12.409552 0.943384241,11.8276717 L-0.28388756,8.65240379 C-0.444283002,8.23741952 -0.319449182,7.76260422 0.000730716832,7.47505565 L-0.0145732772,7.44528707 C0.0327844808,7.42094049 0.0806824543,7.39816945 0.129050684,7.37695571 C0.156751662,7.359073 0.18549978,7.34242973 0.215256505,7.32713183 L0.221175841,7.33864583 C1.37808265,6.88340881 2.77316135,7.29220176 3.48190972,8.32416496 Z M0.000730716832,7.47505565 C0.0405415491,7.43930216 0.0833724658,7.40644385 0.129050684,7.37695571 C0.159577614,7.36356695 0.190291862,7.35079852 0.221175841,7.33864583 L0.672473117,8.2164872 L0.442643335,8.33464243 L0.000730716832,7.47505565 Z M11.5,11 L11.5,12.9999999 L11.9999999,12.4999999 L10.9999999,12.5 L11.5,13 L11.5,11 Z M11.5,11 L11.5,9.00000012 L11.0000001,9.50000012 L12.0000001,9.5 L11.5,9 L11.5,11 Z M9.5,11 L9.5,12.9999999 L9.99999994,12.4999999 L8.99999994,12.5 L9.5,13 L9.5,11 Z M9.5,11 L9.5,9.00000012 L9.00000006,9.50000012 L10.0000001,9.5 L9.5,9 L9.5,11 Z M7.5,11 L7.5,12.9999999 L7.99999994,12.4999999 L6.99999994,12.5 L7.5,13 L7.5,11 Z M7.5,11 L7.5,9.00000012 L7.00000006,9.50000012 L8.00000006,9.5 L7.5,9 L7.5,11 Z"/>
+ </g>
+</svg>
diff --git a/catalog-ui/src/assets/styles/images/canvas-tagging-icons/policy_1.svg b/catalog-ui/src/assets/styles/images/canvas-tagging-icons/policy_1.svg
new file mode 100644
index 0000000..c7f83e8
--- /dev/null
+++ b/catalog-ui/src/assets/styles/images/canvas-tagging-icons/policy_1.svg
@@ -0,0 +1,33 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="44" height="41">
+ <defs>
+ <filter id="policies_1-a" width="145.5%" height="145.5%" x="-22.7%" y="-13.6%" filterUnits="objectBoundingBox">
+ <feOffset dy="2" in="SourceAlpha" result="shadowOffsetOuter1"/>
+ <feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1"/>
+ <feColorMatrix in="shadowBlurOuter1" result="shadowMatrixOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
+ <feMerge>
+ <feMergeNode in="shadowMatrixOuter1"/>
+ <feMergeNode in="SourceGraphic"/>
+ </feMerge>
+ </filter>
+ <path id="policies_1-b" d="M6,4 L6,1 C6,0.4 5.6,0 5,0 C4.4,0 4,0.4 4,1 L4,4 L1,4 C0.4,4 0,4.4 0,5 C0,5.6 0.4,6 1,6 L4,6 L4,9 C4,9.6 4.4,10 5,10 C5.6,10 6,9.6 6,9 L6,6 L9,6 C9.6,6 10,5.6 10,5 C10,4.4 9.6,4 9,4 L6,4 Z"/>
+ <polygon id="policies_1-d" points="7.841 8.516 12.487 6.865 0 0 3.64 13.776 6.366 9.668 9.63 13.845 11.104 12.693"/>
+ <filter id="policies_1-c" width="196.1%" height="186.7%" x="-48.1%" y="-36.1%" filterUnits="objectBoundingBox">
+ <feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"/>
+ <feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/>
+ <feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5"/>
+ <feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/>
+ <feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/>
+ </filter>
+ </defs>
+ <g fill="none" fill-rule="evenodd" transform="translate(4 3)">
+ <g transform="translate(15 11)">
+ <path fill="#162F90" stroke="#FFF" d="M3,0 L19,0 C20.6568542,-3.04359188e-16 22,1.34314575 22,3 L22,19 C22,20.6568542 20.6568542,22 19,22 L3,22 C1.34314575,22 2.02906125e-16,20.6568542 0,19 L0,3 C-2.02906125e-16,1.34314575 1.34314575,3.04359188e-16 3,0 Z" filter="url(#policies_1-a)"/>
+ <g transform="translate(6 6)">
+ <use fill="#FFF" xlink:href="#policies_1-b"/>
+ </g>
+ </g>
+ <use fill="#000" filter="url(#policies_1-c)" xlink:href="#policies_1-d"/>
+ <use fill="#FFF" xlink:href="#policies_1-d"/>
+ <path stroke="#000" stroke-opacity=".8" d="M8.6617598,8.75489325 L11.806255,12.7796636 L9.54386134,14.5472392 L6.39936616,10.5224689 L3.44128728,14.9806328 L-0.781456351,-1.00021852 L13.7031213,6.96320943 L8.6617598,8.75489325 Z"/>
+ </g>
+</svg>
diff --git a/catalog-ui/src/assets/styles/images/canvas-tagging-icons/policy_2.svg b/catalog-ui/src/assets/styles/images/canvas-tagging-icons/policy_2.svg
new file mode 100644
index 0000000..0b52177
--- /dev/null
+++ b/catalog-ui/src/assets/styles/images/canvas-tagging-icons/policy_2.svg
@@ -0,0 +1,33 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="45" height="44">
+ <defs>
+ <filter id="policies_2-a" width="145.5%" height="145.5%" x="-22.7%" y="-13.6%" filterUnits="objectBoundingBox">
+ <feOffset dy="2" in="SourceAlpha" result="shadowOffsetOuter1"/>
+ <feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1"/>
+ <feColorMatrix in="shadowBlurOuter1" result="shadowMatrixOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
+ <feMerge>
+ <feMergeNode in="shadowMatrixOuter1"/>
+ <feMergeNode in="SourceGraphic"/>
+ </feMerge>
+ </filter>
+ <path id="policies_2-b" d="M6,4 L6,1 C6,0.4 5.6,0 5,0 C4.4,0 4,0.4 4,1 L4,4 L1,4 C0.4,4 0,4.4 0,5 C0,5.6 0.4,6 1,6 L4,6 L4,9 C4,9.6 4.4,10 5,10 C5.6,10 6,9.6 6,9 L6,6 L9,6 C9.6,6 10,5.6 10,5 C10,4.4 9.6,4 9,4 L6,4 Z"/>
+ <path id="policies_2-d" d="M3.98190975,9.99999992 L3.09529739,8.64532799 C2.48991036,7.72034561 1.20039622,7.38287755 0.214035029,7.88996475 L0.443864811,7.77180951 C0.199079509,7.89765337 0.081702931,8.21138642 0.182488604,8.47214489 L1.40976041,11.6474128 C1.60431817,12.1507837 2.10121802,12.8626937 2.51297222,13.2203156 C2.51297222,13.2203156 4.98190975,15.2638557 4.98190975,16.03003 L4.98190975,16.9999999 L8.98190975,16.9999999 L9.98190975,14.9999999 L10.9819098,16.9999999 L11.9819098,17 L11.9819098,16.0300302 C11.9819098,15.2638559 13.4907506,12.8506759 13.4907506,12.8506759 C13.7684994,12.3815967 14,11.5552351 14,11.0065899 L14,6.9718022 C13.9819097,6.07849828 13.2225759,5.35453877 12.2856231,5.35453877 C11.8168923,5.35453877 11.4372254,5.71651852 11.4372254,6.1634131 L11.4372254,6.48657465 C11.4372254,5.59327073 10.6778916,4.86931122 9.7409389,4.86931122 C9.27220806,4.86931122 8.89254117,5.23129097 8.89254117,5.67818555 L8.89254117,6.0013471 C8.89254117,5.10804318 8.13320739,4.38408367 7.19625465,4.38408367 C6.72752382,4.38408367 6.34785693,4.74606342 6.34785693,5.192958 L6.34785693,5.51611955 C6.34785693,5.37255591 6.33251267,5.25843099 6.30286699,5.16799051 L6.04408993,1.0012141 C6.00909675,0.437760917 5.53419442,0 4.98190967,0 C4.42577449,0 3.98190967,0.447629061 3.98190967,0.999807492 L3.98190967,5 L3.98190975,9.99999992 Z M11,9.00000012 L12,9 L12,12.9999999 L11,13 L11,9.00000012 L11,9.00000012 Z M9,9.00000012 L10,9 L10,12.9999999 L9,13 L9,9.00000012 L9,9.00000012 Z M7,9.00000012 L8,9 L8,12.9999999 L7,13 L7,9.00000012 L7,9.00000012 Z"/>
+ <filter id="policies_2-c" width="186.6%" height="170.6%" x="-43.3%" y="-29.4%" filterUnits="objectBoundingBox">
+ <feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"/>
+ <feOffset dy="1" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/>
+ <feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5"/>
+ <feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/>
+ <feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/>
+ </filter>
+ </defs>
+ <g fill="none" fill-rule="evenodd" transform="translate(4 3)">
+ <g transform="translate(16 14)">
+ <path fill="#162F90" stroke="#FFF" d="M3,0 L19,0 C20.6568542,-3.04359188e-16 22,1.34314575 22,3 L22,19 C22,20.6568542 20.6568542,22 19,22 L3,22 C1.34314575,22 2.02906125e-16,20.6568542 0,19 L0,3 C-2.02906125e-16,1.34314575 1.34314575,3.04359188e-16 3,0 Z" filter="url(#policies_2-a)"/>
+ <g transform="translate(6 6)">
+ <use fill="#FFF" xlink:href="#policies_2-b"/>
+ </g>
+ </g>
+ <use fill="#000" filter="url(#policies_2-c)" xlink:href="#policies_2-d"/>
+ <use fill="#FFF" xlink:href="#policies_2-d"/>
+ <path stroke="#000" stroke-opacity=".8" d="M3.48190972,8.32416496 L3.48190967,5 L3.48190967,0.999807491 C3.48190967,0.170429729 4.15068503,-0.5 4.98190967,-0.5 C5.80152555,-0.5 6.49196322,0.146369011 6.54312845,0.970221378 L6.729109,3.96484284 C6.87493261,3.91257008 7.03237962,3.88408367 7.19625465,3.88408367 C7.87883467,3.88408367 8.49131623,4.18500488 8.89495329,4.65876818 C9.12697419,4.47737206 9.42176446,4.36931122 9.7409389,4.36931122 C10.4235189,4.36931122 11.0360005,4.67023243 11.4396375,5.14399573 C11.6716584,4.96259961 11.9664487,4.85453877 12.2856231,4.85453877 C13.4881886,4.85453877 14.4761616,5.78959763 14.5,6.9718022 L14.5,11.0065899 C14.5,11.6413376 14.2462612,12.556081 13.9147021,13.1157516 C13.8694672,13.1880985 13.788913,13.3198554 13.6849071,13.4950007 C13.511352,13.7872659 13.3378324,14.0912197 13.1763581,14.3904728 C13.1037538,14.5250271 13.0351585,14.6557806 12.9712321,14.7818029 C12.6639479,15.3875721 12.4819098,15.8603735 12.4819098,16.0300302 L12.4819098,17.5000001 L10.6728927,17.4999999 L9.98190975,16.1180339 L9.29092675,17.4999999 L4.48190975,17.4999999 L4.48190975,16.03003 C4.48190975,15.9441015 4.22664544,15.5664829 3.80083171,15.1083367 C3.6777582,14.9759181 3.54245432,14.8374578 3.39695629,14.6944531 C3.13416835,14.4361686 2.85142222,14.1758166 2.56855227,13.9270547 C2.39897253,13.7779227 2.26768741,13.6663479 2.1851049,13.5978113 C1.71375103,13.1884251 1.16828661,12.409552 0.943384241,11.8276717 L-0.28388756,8.65240379 C-0.444283002,8.23741952 -0.319449182,7.76260422 0.000730716832,7.47505565 L-0.0145732772,7.44528707 C0.0327844808,7.42094049 0.0806824543,7.39816945 0.129050684,7.37695571 C0.156751662,7.359073 0.18549978,7.34242973 0.215256505,7.32713183 L0.221175841,7.33864583 C1.37808265,6.88340881 2.77316135,7.29220176 3.48190972,8.32416496 Z M0.000730716832,7.47505565 C0.0405415491,7.43930216 0.0833724658,7.40644385 0.129050684,7.37695571 C0.159577614,7.36356695 0.190291862,7.35079852 0.221175841,7.33864583 L0.672473117,8.2164872 L0.442643335,8.33464243 L0.000730716832,7.47505565 Z M11.5,11 L11.5,12.9999999 L11.9999999,12.4999999 L10.9999999,12.5 L11.5,13 L11.5,11 Z M11.5,11 L11.5,9.00000012 L11.0000001,9.50000012 L12.0000001,9.5 L11.5,9 L11.5,11 Z M9.5,11 L9.5,12.9999999 L9.99999994,12.4999999 L8.99999994,12.5 L9.5,13 L9.5,11 Z M9.5,11 L9.5,9.00000012 L9.00000006,9.50000012 L10.0000001,9.5 L9.5,9 L9.5,11 Z M7.5,11 L7.5,12.9999999 L7.99999994,12.4999999 L6.99999994,12.5 L7.5,13 L7.5,11 Z M7.5,11 L7.5,9.00000012 L7.00000006,9.50000012 L8.00000006,9.5 L7.5,9 L7.5,11 Z"/>
+ </g>
+</svg>
diff --git a/catalog-ui/src/assets/styles/images/canvas-tagging-icons/policy_added.svg b/catalog-ui/src/assets/styles/images/canvas-tagging-icons/policy_added.svg
index 9ff3901..269f437 100644
--- a/catalog-ui/src/assets/styles/images/canvas-tagging-icons/policy_added.svg
+++ b/catalog-ui/src/assets/styles/images/canvas-tagging-icons/policy_added.svg
@@ -1,33 +1,18 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch -->
- <title>Group 13 Copy</title>
- <desc>Created with Sketch.</desc>
- <defs>
- <path d="M3,0 L15,0 C16.6568542,-3.04359188e-16 18,1.34314575 18,3 L18,15 C18,16.6568542 16.6568542,18 15,18 L3,18 C1.34314575,18 -6.85272294e-16,16.6568542 -8.8817842e-16,15 L0,3 C-2.02906125e-16,1.34314575 1.34314575,-5.83819232e-16 3,-8.8817842e-16 Z" id="path-1"></path>
- <filter x="-25.0%" y="-13.9%" width="150.0%" height="150.0%" filterUnits="objectBoundingBox" id="filter-2">
- <feMorphology radius="0.5" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
- <feOffset dx="0" dy="2" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
- <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
- <feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"></feComposite>
- <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
- </filter>
- <path d="M12.6603086,4.57405469 L8.30209375,11.5833406 L5.57568359,9.20957266 C5.13068359,8.77957266 4.46368359,8.77957266 4.01968359,9.20957266 C3.57568359,9.64057266 3.57568359,10.2865727 4.01968359,10.7175727 L7.52409375,13.8453406 C7.74609375,14.0603406 7.96809375,14.1683406 8.30209375,14.1683406 C8.63509375,14.1683406 8.85809375,14.0603406 9.07909375,13.8453406 L14.2163086,6.08105469 C14.6603086,5.65105469 14.6603086,5.00505469 14.2163086,4.57405469 C13.7723086,4.14305469 13.1053086,4.14305469 12.6603086,4.57405469 Z" id="path-3"></path>
- </defs>
- <g id="sdc" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
- <g id="Group-13-Copy" transform="translate(3.000000, 1.000000)">
- <g id="Group-4-Copy-9">
- <g id="Group-3">
- <g id="Rectangle-15-Copy-5">
- <use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
- <use stroke="#FFFFFF" stroke-width="1" fill="#0568AE" fill-rule="evenodd" xlink:href="#path-1"></use>
- </g>
- </g>
- </g>
- <mask id="mask-4" fill="white">
- <use xlink:href="#path-3"></use>
- </mask>
- <use id="Mask" fill="#FFFFFF" xlink:href="#path-3"></use>
- </g>
- </g>
-</svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24">
+ <defs>
+ <path id="group-13-copy-b" d="M3,0 L15,0 C16.6568542,-3.04359188e-16 18,1.34314575 18,3 L18,15 C18,16.6568542 16.6568542,18 15,18 L3,18 C1.34314575,18 -6.85272294e-16,16.6568542 -8.8817842e-16,15 L0,3 C-2.02906125e-16,1.34314575 1.34314575,-5.83819232e-16 3,-8.8817842e-16 Z"/>
+ <filter id="group-13-copy-a" width="150%" height="150%" x="-25%" y="-13.9%" filterUnits="objectBoundingBox">
+ <feMorphology in="SourceAlpha" operator="dilate" radius=".5" result="shadowSpreadOuter1"/>
+ <feOffset dy="2" in="shadowSpreadOuter1" result="shadowOffsetOuter1"/>
+ <feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1"/>
+ <feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/>
+ <feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
+ </filter>
+ <path id="group-13-copy-c" d="M12.6603086,4.57405469 L8.30209375,11.5833406 L5.57568359,9.20957266 C5.13068359,8.77957266 4.46368359,8.77957266 4.01968359,9.20957266 C3.57568359,9.64057266 3.57568359,10.2865727 4.01968359,10.7175727 L7.52409375,13.8453406 C7.74609375,14.0603406 7.96809375,14.1683406 8.30209375,14.1683406 C8.63509375,14.1683406 8.85809375,14.0603406 9.07909375,13.8453406 L14.2163086,6.08105469 C14.6603086,5.65105469 14.6603086,5.00505469 14.2163086,4.57405469 C13.7723086,4.14305469 13.1053086,4.14305469 12.6603086,4.57405469 Z"/>
+ </defs>
+ <g fill="none" fill-rule="evenodd" transform="translate(3 1)">
+ <use fill="#000" filter="url(#group-13-copy-a)" xlink:href="#group-13-copy-b"/>
+ <use fill="#162F90" stroke="#FFF" xlink:href="#group-13-copy-b"/>
+ <use fill="#FFF" xlink:href="#group-13-copy-c"/>
+ </g>
+</svg>
diff --git a/catalog-ui/src/assets/styles/images/relationship-icons/BindsTo.svg b/catalog-ui/src/assets/styles/images/relationship-icons/BindsTo.svg
index ae5647d..e19fc4c 100644
--- a/catalog-ui/src/assets/styles/images/relationship-icons/BindsTo.svg
+++ b/catalog-ui/src/assets/styles/images/relationship-icons/BindsTo.svg
@@ -1,4 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="25" height="25" viewBox="0 0 25 25">
+<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" width="25" height="25" viewBox="0 0 25 25">
<defs>
<style>
.cls-1 {
diff --git a/catalog-ui/src/assets/styles/images/relationship-icons/ConnectedTo.svg b/catalog-ui/src/assets/styles/images/relationship-icons/ConnectedTo.svg
index 4ee7672..9f7a75b 100644
--- a/catalog-ui/src/assets/styles/images/relationship-icons/ConnectedTo.svg
+++ b/catalog-ui/src/assets/styles/images/relationship-icons/ConnectedTo.svg
@@ -1,4 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="25" height="25" viewBox="0 0 25 25">
+<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" width="25" height="25" viewBox="0 0 25 25">
<defs>
<style>
.cls-1 {
diff --git a/catalog-ui/src/assets/styles/images/relationship-icons/DependsOn.svg b/catalog-ui/src/assets/styles/images/relationship-icons/DependsOn.svg
index e38808e..39d613b 100644
--- a/catalog-ui/src/assets/styles/images/relationship-icons/DependsOn.svg
+++ b/catalog-ui/src/assets/styles/images/relationship-icons/DependsOn.svg
@@ -1,4 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="25" height="25" viewBox="0 0 25 25">
+<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" width="25" height="25" viewBox="0 0 25 25">
<defs>
<style>
.cls-1, .cls-2 {
diff --git a/catalog-ui/src/assets/styles/images/relationship-icons/HostedOn.svg b/catalog-ui/src/assets/styles/images/relationship-icons/HostedOn.svg
index 5daf84a..22df67c 100644
--- a/catalog-ui/src/assets/styles/images/relationship-icons/HostedOn.svg
+++ b/catalog-ui/src/assets/styles/images/relationship-icons/HostedOn.svg
@@ -1,4 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="25" height="25" viewBox="0 0 25 25">
+<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" width="25" height="25" viewBox="0 0 25 25">
<defs>
<style>
.cls-1 {
diff --git a/catalog-ui/src/assets/styles/images/relationship-icons/LinksTo.svg b/catalog-ui/src/assets/styles/images/relationship-icons/LinksTo.svg
index fb4c687..3299595 100644
--- a/catalog-ui/src/assets/styles/images/relationship-icons/LinksTo.svg
+++ b/catalog-ui/src/assets/styles/images/relationship-icons/LinksTo.svg
@@ -1,4 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="25" height="25" viewBox="0 0 25 25">
+<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" width="25" height="25" viewBox="0 0 25 25">
<defs>
<style>
.cls-1 {
diff --git a/catalog-ui/src/assets/styles/images/relationship-icons/RoutesTo.svg b/catalog-ui/src/assets/styles/images/relationship-icons/RoutesTo.svg
index 4c3caf5..3a79cff 100644
--- a/catalog-ui/src/assets/styles/images/relationship-icons/RoutesTo.svg
+++ b/catalog-ui/src/assets/styles/images/relationship-icons/RoutesTo.svg
@@ -1,4 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="25" height="25" viewBox="0 0 25 25">
+<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" width="25" height="25" viewBox="0 0 25 25">
<defs>
<style>
.cls-1 {
diff --git a/catalog-ui/src/assets/styles/images/relationship-icons/arrow.svg b/catalog-ui/src/assets/styles/images/relationship-icons/arrow.svg
index 4696e50..02ec817 100644
--- a/catalog-ui/src/assets/styles/images/relationship-icons/arrow.svg
+++ b/catalog-ui/src/assets/styles/images/relationship-icons/arrow.svg
@@ -1,4 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="7" height="9" viewBox="0 0 7 9">
+<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" width="7" height="9" viewBox="0 0 7 9">
<defs>
<style>
.cls-1 {
diff --git a/catalog-ui/src/assets/styles/images/relationship-icons/arrow_connection_right.svg b/catalog-ui/src/assets/styles/images/relationship-icons/arrow_connection_right.svg
index ea2d9f2..bfb7be5 100644
--- a/catalog-ui/src/assets/styles/images/relationship-icons/arrow_connection_right.svg
+++ b/catalog-ui/src/assets/styles/images/relationship-icons/arrow_connection_right.svg
@@ -1,4 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="7" height="9" viewBox="0 0 7 9">
+<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" width="7" height="9" viewBox="0 0 7 9">
<defs>
<style>
.cls-1 {
diff --git a/catalog-ui/src/assets/styles/images/relationship-icons/conected.svg b/catalog-ui/src/assets/styles/images/relationship-icons/conected.svg
index 4ee7672..9f7a75b 100644
--- a/catalog-ui/src/assets/styles/images/relationship-icons/conected.svg
+++ b/catalog-ui/src/assets/styles/images/relationship-icons/conected.svg
@@ -1,4 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="25" height="25" viewBox="0 0 25 25">
+<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" width="25" height="25" viewBox="0 0 25 25">
<defs>
<style>
.cls-1 {
diff --git a/catalog-ui/src/assets/styles/images/resource-icons/archive_big.png b/catalog-ui/src/assets/styles/images/resource-icons/archive_big.png
new file mode 100644
index 0000000..fd5ae3d
--- /dev/null
+++ b/catalog-ui/src/assets/styles/images/resource-icons/archive_big.png
Binary files differ
diff --git a/catalog-ui/src/assets/styles/images/resource-icons/archive_small.png b/catalog-ui/src/assets/styles/images/resource-icons/archive_small.png
new file mode 100644
index 0000000..207cc41
--- /dev/null
+++ b/catalog-ui/src/assets/styles/images/resource-icons/archive_small.png
Binary files differ
diff --git a/catalog-ui/src/assets/styles/images/sprites/sprite-global.png b/catalog-ui/src/assets/styles/images/sprites/sprite-global.png
index 2cf0bd7..ca628a2 100644
--- a/catalog-ui/src/assets/styles/images/sprites/sprite-global.png
+++ b/catalog-ui/src/assets/styles/images/sprites/sprite-global.png
Binary files differ
diff --git a/catalog-ui/src/assets/styles/images/sprites/sprite-global.png-orig b/catalog-ui/src/assets/styles/images/sprites/sprite-global.png-orig
new file mode 100644
index 0000000..51cfefa
--- /dev/null
+++ b/catalog-ui/src/assets/styles/images/sprites/sprite-global.png-orig
Binary files differ
diff --git a/catalog-ui/src/assets/styles/images/sprites/sprite-policy-groups-icons.png b/catalog-ui/src/assets/styles/images/sprites/sprite-policy-groups-icons.png
index fe1723e..57da9e2 100644
--- a/catalog-ui/src/assets/styles/images/sprites/sprite-policy-groups-icons.png
+++ b/catalog-ui/src/assets/styles/images/sprites/sprite-policy-groups-icons.png
Binary files differ
diff --git a/catalog-ui/src/assets/styles/images/sprites/sprite-resource-icons.png b/catalog-ui/src/assets/styles/images/sprites/sprite-resource-icons.png
index 7f21e24..dc63954 100644
--- a/catalog-ui/src/assets/styles/images/sprites/sprite-resource-icons.png
+++ b/catalog-ui/src/assets/styles/images/sprites/sprite-resource-icons.png
Binary files differ
diff --git a/catalog-ui/src/assets/styles/layout/main.less b/catalog-ui/src/assets/styles/layout/main.less
index 2992b1d..4dfeb8b 100644
--- a/catalog-ui/src/assets/styles/layout/main.less
+++ b/catalog-ui/src/assets/styles/layout/main.less
@@ -27,9 +27,22 @@
.sdc-tile {
margin: 10px;
.sdc-tile-content {
+ overflow: visible;
+
+ .sdc-tile-content-icon {
+ width: 100%;
+ margin-top: -1em;
+ text-align: right;
+ }
+
.sdc-tile-content-info {
.sdc-tile-info-line {
display: inline-block;
+
+ &.title {
+ line-height: 1.4em;
+ height: auto;
+ }
}
}
}
@@ -38,6 +51,13 @@
}
}
+.w-sdc-tile-multiline-ellipsis {
+ .multiline-ellipsis-dots {
+ background: linear-gradient(to right, transparent 0%, #ffffff 80%);
+ padding-left: 1em;
+ }
+}
+
.w-sdc-row-flex-items {
display: flex;
flex-wrap: wrap;
diff --git a/catalog-ui/src/assets/styles/mixins.less b/catalog-ui/src/assets/styles/mixins.less
index b55d4fd..e71f344 100644
--- a/catalog-ui/src/assets/styles/mixins.less
+++ b/catalog-ui/src/assets/styles/mixins.less
@@ -219,3 +219,37 @@
-ms-user-select: text;
user-select: text;
}
+
+
+.square-icon() {
+ display: inline-block;
+ background-color: @main_color_a;
+ padding: 0;
+ margin: 0;
+ margin-right: 7px;
+ width: 2em;
+ height: 2em;
+ border-radius: 1px;
+
+ &::before {
+ display: block;
+ content: "";
+ color: @main_color_p;
+ text-align: center;
+ line-height: 2em;
+ width: calc(100% - 2px);
+ height: calc(100% - 2px);
+ }
+
+ &.small {
+ font-size: 14px;
+ }
+
+ &.medium {
+ font-size: 20px;
+ }
+
+ &.large {
+ font-size: 30px;
+ }
+}
diff --git a/catalog-ui/src/assets/styles/override.less b/catalog-ui/src/assets/styles/override.less
new file mode 100644
index 0000000..960be23
--- /dev/null
+++ b/catalog-ui/src/assets/styles/override.less
@@ -0,0 +1,72 @@
+@sdcui_color_white: #ffffff;
+@sdcui_color_dark-blue: #0568ae;
+@sdcui_color_blue: #009fdb;
+@sdcui_color_light-blue: #1eb9f3;
+@sdcui_color_blue-disabled: #9dd9ef;
+@sdcui_color_lighter-blue: #e6f6fb;
+@sdcui_color_black: #000000;
+@sdcui_color_text-black: #191919;
+@sdcui_color_rich-black: #323943;
+@sdcui_color_dark-gray: #5a5a5a;
+@sdcui_color_gray: #959595;
+@sdcui_color_light-gray: #d2d2d2;
+@sdcui_color_silver: #eaeaea;
+@sdcui_color_light-silver: #f2f2f2;
+@sdcui_color_lighter-silver: #f8f8f8;
+@sdcui_color_green: #4ca90c;
+@sdcui_color_red: #cf2a2a;
+@sdcui_color_light-red: #ed4141;
+@sdcui_color_disabled-red: #f4adad;
+@sdcui_color_yellow: #ffb81c;
+@sdcui_color_dark-purple: #702f8a;
+@sdcui_color_purple: #9063cd;
+@sdcui_color_light-purple: #caa2dd;
+
+/* override sdc-ui library tabs */
+body.composition {
+
+ .sdc-tabs {
+ .sdc-tab {
+ background-color: @sdcui_color_white;
+ border: 1px solid @sdcui_color_silver;
+ border-left: none;
+ display: inline-block;
+ height: 36px;
+ text-align: center;
+ cursor: pointer;
+ padding: 2px 10px 0 10px;
+ margin: 0;
+
+
+ &:first-child {
+ border-left: 1px solid @sdcui_color_silver;
+ }
+ &.sdc-tab-active {
+ background-color: @sdcui_color_silver;
+ }
+ &[disabled] {
+ opacity: 0.3;
+ cursor: default;
+ }
+ }
+ &.sdc-tabs-header {
+ .sdc-tab {
+ font-size: 24px;
+ }
+ }
+ &.sdc-tabs-menu {
+ .sdc-tab {
+ font-size: 14px;
+ padding: 0px 10px 4px 10px;
+ }
+ }
+ .sdc-tab-content {
+ margin-top: 0;
+ }
+ }
+
+}
+//override sdc-ui version 53 css, used by onboarding. This can be removed after we update past version 42
+sdc-modal {
+ position: static !important;
+}
diff --git a/catalog-ui/src/assets/styles/sprite-group-icons.less b/catalog-ui/src/assets/styles/sprite-group-icons.less
index 47340ad..363f7a9 100644
--- a/catalog-ui/src/assets/styles/sprite-group-icons.less
+++ b/catalog-ui/src/assets/styles/sprite-group-icons.less
@@ -4,7 +4,7 @@
}
.sprite-group-icons.disable { opacity:0.5;}
-.sprite-group-icons.group { background-position: -43px -42px; width: 40px; height: 40px;}
+.sprite-group-icons.group { background-position: -239px -43px; width: 40px; height: 40px;}
.sprite-group-icons.group-border { background-position: -123px -36px; width: 55px; height: 55px;}
sprite-group-icons.group-empty { background-position: -40px -274px; width: 47px; height: 47px;}
diff --git a/catalog-ui/src/assets/styles/sprite-policy-icons.less b/catalog-ui/src/assets/styles/sprite-policy-icons.less
index 154cf0b..40f4f7e 100644
--- a/catalog-ui/src/assets/styles/sprite-policy-icons.less
+++ b/catalog-ui/src/assets/styles/sprite-policy-icons.less
@@ -5,7 +5,7 @@
.sprite-policy-icons.disable { opacity:0.5;}
-.sprite-policy-icons.policy { background-position: -42px -130px; width: 40px; height: 40px;}
+.sprite-policy-icons.policy { background-position: -239px -130px; width: 40px; height: 40px;}
.sprite-policy-icons.policy-border { background-position: -123px -123px; width: 55px; height: 55px;}
.sprite-policy-icons.policy-empty { background-position: -40px -546px; width: 47px; height: 47px;}
diff --git a/catalog-ui/src/assets/styles/sprite-resource-icons.less b/catalog-ui/src/assets/styles/sprite-resource-icons.less
index 2f542d6..0ada1c8 100644
--- a/catalog-ui/src/assets/styles/sprite-resource-icons.less
+++ b/catalog-ui/src/assets/styles/sprite-resource-icons.less
@@ -96,7 +96,7 @@
.sprite-resource-icons.oracle.large { background-position: -70px -1229px; width: 60px; height: 60px;}
.sprite-resource-icons.defaulticon { background-position: -282px -2069px; width: 60px; height: 60px;}
-.sprite-resource-icons.defaulticon.small { background-position: -210px -2101px; width: 28px; height: 28px;}
+.sprite-resource-icons.defaulticon.small { background-position: -211px -2101px; width: 28px; height: 28px;}
.sprite-resource-icons.defaulticon.medium { background-position: -141px -2089px; width: 40px; height: 40px;}
.sprite-resource-icons.defaulticon.large { background-position: -70px -2069px; width: 61px; height: 60px;}
diff --git a/catalog-ui/src/assets/styles/sprite.less b/catalog-ui/src/assets/styles/sprite.less
index aaf4f55..3e56a01 100644
--- a/catalog-ui/src/assets/styles/sprite.less
+++ b/catalog-ui/src/assets/styles/sprite.less
@@ -1,3 +1,5 @@
+@import "variables";
+@import '../../assets/styles/mixins';
.sprite-new {
background-image: url('images/sprites/sprite-global.png');
display: inline-block;
@@ -140,7 +142,7 @@
.Deployed { background-position: -573px -718px; width: 16px; height: 16px;}
.error-icon { background-position: -51px -751px; width: 13px; height: 11px;}
-.asdc-warning { background-position: -100px -748px; width: 17px; height: 15px;}
+.asdc-warning, .sdc-warning { background-position: -100px -748px; width: 17px; height: 15px;}
.link-btn { background-position: -636px -424px; width: 19px; height: 19px;}
.link-btn:hover { background-position: -636px -453px; width: 19px; height: 19px;}
@@ -291,3 +293,43 @@
.white-arrow-back{ background-position: -767px -918px; width: 23px; height: 23px;}
.link-tooltip-arrow{background-position:-746px -961px; width: 20px; height: 14px;}
+
+.archive-btn { background-position: -110px -419px; width: 24px; height: 24px;}
+.archive-btn:hover { background-position: -110px -447px; width: 24px; height: 24px;}
+
+.archive-component {
+ position:relative;
+ &::after {
+ content: "";
+ display: block;
+ background: url('images/sprites/sprite-global.png') no-repeat -739px -1044px;
+ width: 61px;
+ height: 61px;
+ position: absolute;
+ top: 0;
+ left: 0;
+ }
+ &.active-component-static {
+ &::after {
+ position: static;
+ }
+ }
+}
+
+.archive-label { background-position: -739px -1136px; width: 67px; height: 18px;}
+
+.icon-group {
+ .square-icon();
+
+ &::before {
+ content: "G";
+ }
+}
+.icon-policy {
+ .square-icon();
+ background-color: @main_color_b;
+
+ &::before {
+ content: "P";
+ }
+}
\ No newline at end of file
diff --git a/catalog-ui/src/assets/styles/svg/source/fit-all.svg b/catalog-ui/src/assets/styles/svg/source/fit-all.svg
index dbea909..03834f8 100644
--- a/catalog-ui/src/assets/styles/svg/source/fit-all.svg
+++ b/catalog-ui/src/assets/styles/svg/source/fit-all.svg
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- width="18px" height="19px" viewBox="0 0 18 19">
+ width="18px" height="19px" viewBox="0 0 18 19">
<path fillRule="evenodd" d="M 17.94 18.86C 17.77 18.92 17.63 19 17.4 18.94 16.03 18.93 12.86 19 12.86 19 12.5 19 11.92 18.85 12 18 12.08 17.07 12.5 17 12.86 17 12.86 17 14.79 17 14.79 17 14.79 17 10.44 11.98 10.44 11.98 10.44 11.98 11.77 10.51 11.77 10.51 11.77 10.51 16.33 15.76 16.33 15.76 16.33 15.76 16.33 12.99 16.33 12.99 16.23 12.09 17.03 11.99 17.4 11.99 17.77 11.99 18.01 12.27 18.01 12.69 18.01 12.69 18.01 18.23 18.01 18.23 18.01 17.81 18 18.55 17.94 18.86ZM 17.33 7.36C 16.92 7.36 16.04 7.25 16.15 6.31 16.15 6.31 16.15 3.62 16.15 3.62 16.15 3.62 11.37 9 11.37 9 11.37 9 10.01 7.53 10.01 7.53 10.01 7.53 14.82 2.1 14.82 2.1 14.82 2.1 12.33 2.1 12.33 2.1 11.92 2.1 11.47 2.02 11.37 1.05 11.29 0.16 11.92-0 12.33-0 12.33-0 15.82 0.07 17.33 0.06 17.59 0 17.74 0.08 17.93 0.15 17.99 0.47 18 1.25 18 0.8 18 0.8 18 6.62 18 6.62 18 7.06 17.73 7.36 17.33 7.36ZM 5.67 16.9C 6.08 16.9 6.53 16.98 6.63 17.95 6.71 18.84 6.08 19 5.67 19 5.67 19 2.18 18.93 0.67 18.94 0.41 19 0.26 18.92 0.07 18.85 0.01 18.53-0 17.75-0 18.2-0 18.2-0 12.38-0 12.38-0 11.94 0.27 11.64 0.67 11.64 1.08 11.64 1.96 11.75 1.85 12.69 1.85 12.69 1.85 15.38 1.85 15.38 1.85 15.38 6.63 10 6.63 10 6.63 10 7.99 11.47 7.99 11.47 7.99 11.47 3.18 16.9 3.18 16.9 3.18 16.9 5.67 16.9 5.67 16.9ZM 6.63 9C 6.63 9 1.85 3.62 1.85 3.62 1.85 3.62 1.85 6.31 1.85 6.31 1.96 7.25 1.08 7.36 0.67 7.36 0.27 7.36-0 7.06-0 6.62-0 6.62-0 0.8-0 0.8-0 1.25 0.01 0.47 0.07 0.15 0.26 0.08 0.41 0 0.67 0.06 2.18 0.07 5.67-0 5.67-0 6.08-0 6.71 0.16 6.63 1.05 6.53 2.02 6.08 2.1 5.67 2.1 5.67 2.1 3.18 2.1 3.18 2.1 3.18 2.1 7.99 7.53 7.99 7.53 7.99 7.53 6.63 9 6.63 9Z" fill="rgb(89,89,89)"/></svg>
\ No newline at end of file
diff --git a/catalog-ui/src/assets/styles/svg/source/minus.svg b/catalog-ui/src/assets/styles/svg/source/minus.svg
index 4ced110..7e204f1 100644
--- a/catalog-ui/src/assets/styles/svg/source/minus.svg
+++ b/catalog-ui/src/assets/styles/svg/source/minus.svg
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- width="16px" height="2px" viewBox="0 0 16 2">
+ width="16px" height="2px" viewBox="0 0 16 2">
<path fillRule="evenodd" d="M 1-0C 1-0 15-0 15-0 15.55-0 16 0.45 16 1 16 1.55 15.55 2 15 2 15 2 1 2 1 2 0.45 2 0 1.55 0 1 0 0.45 0.45-0 1-0Z" fill="rgb(99,99,99)"/></svg>
\ No newline at end of file
diff --git a/catalog-ui/src/assets/styles/svg/source/plus.svg b/catalog-ui/src/assets/styles/svg/source/plus.svg
index dff172c..34670ed 100644
--- a/catalog-ui/src/assets/styles/svg/source/plus.svg
+++ b/catalog-ui/src/assets/styles/svg/source/plus.svg
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- width="18px" height="18px" viewBox="0 0 18 18">
+ width="18px" height="18px" viewBox="0 0 18 18">
<path fillRule="evenodd" d="M 17 10C 17 10 10 10 10 10 10 10 10 17 10 17 10 17.55 9.55 18 9 18 8.45 18 8 17.55 8 17 8 17 8 10 8 10 8 10 1 10 1 10 0.45 10 0 9.55 0 9 0 8.45 0.45 8 1 8 1 8 8 8 8 8 8 8 8 1 8 1 8 0.45 8.45 0 9 0 9.55 0 10 0.45 10 1 10 1 10 8 10 8 10 8 17 8 17 8 17.55 8 18 8.45 18 9 18 9.55 17.55 10 17 10Z" fill="rgb(99,99,99)"/></svg>
\ No newline at end of file
diff --git a/catalog-ui/src/assets/styles/svg/source/search-magnify.svg b/catalog-ui/src/assets/styles/svg/source/search-magnify.svg
index 279c13f..f5483a5 100644
--- a/catalog-ui/src/assets/styles/svg/source/search-magnify.svg
+++ b/catalog-ui/src/assets/styles/svg/source/search-magnify.svg
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- width="23px" height="26px" viewBox="0 0 23 26">
+ width="23px" height="26px" viewBox="0 0 23 26">
<path fillRule="evenodd" d="M 17.53 4.53C 14.5 0.28 8.55-0.71 4.3 2.32 0.05 5.36-0.94 11.31 2.09 15.56 3.56 17.63 5.74 18.99 8.25 19.41 10.42 19.77 12.58 19.38 14.48 18.32 14.48 18.32 20.28 25.23 20.28 25.23 20.44 25.47 20.7 25.61 20.93 25.65 21.16 25.69 21.45 25.64 21.68 25.47 22.15 25.13 22.26 24.5 21.92 24.06 21.92 24.06 16.11 17.15 16.11 17.15 17.73 15.7 18.81 13.79 19.17 11.61 19.58 9.14 19.01 6.6 17.53 4.53ZM 3.76 14.4C 1.37 11.04 2.14 6.4 5.5 4 7.18 2.8 9.16 2.41 11.07 2.73 12.97 3.05 14.73 4.07 15.92 5.74 17.09 7.38 17.52 9.34 17.19 11.32 16.86 13.29 15.79 15 14.18 16.17 12.58 17.35 10.58 17.77 8.61 17.44 6.65 17.08 4.9 16.03 3.76 14.4Z" fill="rgb(99,99,99)"/></svg>
\ No newline at end of file
diff --git a/catalog-ui/src/assets/styles/variables.less b/catalog-ui/src/assets/styles/variables.less
index 1637374..e800da9 100644
--- a/catalog-ui/src/assets/styles/variables.less
+++ b/catalog-ui/src/assets/styles/variables.less
@@ -26,7 +26,9 @@
@main_color_o: #d2d2d2;
@main_color_p: #ffffff;
@main_color_q: #999999;
-
+@main_color_r: #162F90;
+@main_color_s: #666666;
+@main_color_t: #979797;
/* Functional Colors */
@func_color_q: #cf2a2a;
@func_color_r: #f2f2f2;
diff --git a/catalog-ui/src/third-party/cytoscape.js-edge-editation/CytoscapeEdgeEditation.js b/catalog-ui/src/third-party/cytoscape.js-edge-editation/CytoscapeEdgeEditation.js
index 0e6ca8b..ca88b3d 100644
--- a/catalog-ui/src/third-party/cytoscape.js-edge-editation/CytoscapeEdgeEditation.js
+++ b/catalog-ui/src/third-party/cytoscape.js-edge-editation/CytoscapeEdgeEditation.js
@@ -123,21 +123,47 @@
exports.CytoscapeEdgeEditation = Class({
- init: function (cy, handleSize) {
+ init: function (cy) {
this.DOUBLE_CLICK_INTERVAL = 300;
- this.HANDLE_SIZE = handleSize ? handleSize : 5;
+ this.HANDLE_SIZE = 18;
this.ARROW_END_ID = "ARROW_END_ID";
this._handles = {};
this._dragging = false;
this._hover = null;
-
+ this._tagMode = false;
this._cy = cy;
this._$container = $(cy.container());
- this._cy.on('mouseover tap', 'node', this._mouseOver.bind(this));
- this._cy.on('mouseout', 'node', this._mouseOut.bind(this));
+ this._$canvas = $('<canvas></canvas>');
+ this._$canvas.css("top", 0);
+
+ this._ctx = this._$canvas[0].getContext('2d');
+ this._$container.children("div").append(this._$canvas);
+
+ this._resizeCanvas();
+
+ this.initContainerEvents();
+
+ },
+ initContainerEvents: function () {
+ this._cy.on("resize", this._resizeCanvas.bind(this));
+ /*$(window).bind('resize', this._resizeCanvas.bind(this));
+ $(window).bind('resize', this._resizeCanvas.bind(this));*/
+
+ this._$container.bind('resize', function () {
+ this._resizeCanvas();
+ }.bind(this));
+
+ this._cy.bind('zoom pan', this._redraw.bind(this));
+
+ this._cy.on('showhandle', function (cy, target, customHandle) {
+ this.permanentHandle = true;
+ this._showHandles(target, customHandle);
+ }.bind(this));
+
+ this._cy.on('hidehandles', this._hideHandles.bind(this));
this._$container.on('mouseout', function (e) {
if (this.permanentHandle) {
@@ -147,16 +173,25 @@
this._clear();
}.bind(this));
- this._$container.on('mouseover', function (e) {
- if (this._hover) {
- this._mouseOver({cyTarget: this._hover});
- }
- }.bind(this));
- this._cy.on("select", "node", this._redraw.bind(this))
+ },
+ initNodeEvents: function (){
+
+ this._$canvas.on("mousedown", this._mouseDown.bind(this));
+ this._$canvas.on("mousemove", this._mouseMove.bind(this));
+ this._$canvas.on('mouseup', this._mouseUp.bind(this));
+
+ this._cy.on('tapdragover', 'node', this._mouseOver.bind(this));
+ this._cy.on('tapdragout', 'node', this._mouseOut.bind(this));
+
+
+
+ //this._cy.on("select", "node", this._redraw.bind(this))
this._cy.on("mousedown", "node", function () {
- this._nodeClicked = true;
+ if(!this._tagMode) {
+ this._nodeClicked = true;
+ }
}.bind(this));
this._cy.on("mouseup", "node", function () {
@@ -168,65 +203,43 @@
this._clear();
}.bind(this));
- this._cy.on('showhandle', function (cy, target) {
- this.permanentHandle = true;
- this._showHandles(target);
+ // this._$container.on('mouseover', function (e) {
+ // if (this._hover) {
+ // this._mouseOver({cyTarget: this._hover});
+ // }
+ // }.bind(this));
+
+ this._cy.on('tagstart', function(){
+ this._tagMode = true;
}.bind(this));
- this._cy.on('hidehandles', this._hideHandles.bind(this));
-
- this._cy.bind('zoom pan', this._redraw.bind(this));
-
-
- this._$canvas = $('<canvas></canvas>');
- this._$canvas.css("top", 0);
- this._$canvas.on("mousedown", this._mouseDown.bind(this));
- this._$canvas.on("mousemove", this._mouseMove.bind(this));
-
- this._ctx = this._$canvas[0].getContext('2d');
- this._$container.children("div").append(this._$canvas);
-
- $(window).bind('mouseup', this._mouseUp.bind(this));
-
- /*$(window).bind('resize', this._resizeCanvas.bind(this));
- $(window).bind('resize', this._resizeCanvas.bind(this));*/
-
- this._cy.on("resize", this._resizeCanvas.bind(this));
-
- this._$container.bind('resize', function () {
- this._resizeCanvas();
- }.bind(this));
-
- this._resizeCanvas();
-
-
+ this._cy.on('tagend', function(){
+ this._tagMode = false;
+ }.bind(this))
},
registerHandle: function (handle) {
- if (handle.nodeTypeNames) {
- for (var i in handle.nodeTypeNames) {
- var nodeTypeName = handle.nodeTypeNames[i];
- this._handles[nodeTypeName] = this._handles[nodeTypeName] || [];
- this._handles[nodeTypeName].push(handle);
- }
- } else {
- this._handles["*"] = this._handles["*"] || [];
- this._handles["*"].push(handle);
+
+ if (handle.imageUrl) {
+
+ var base_image = new Image();
+ base_image.src = handle.imageUrl;
+ base_image.onload = function() {
+ handle.image = base_image;
+ };
}
+
+ this._handles[handle.type] = this._handles[handle.type] || [];
+ this._handles[handle.type] = handle;
+
},
- _showHandles: function (target) {
- var nodeTypeName = target.data().type;
- if (nodeTypeName) {
+ _showHandles: function (target, handleType) {
- var handles = this._handles[nodeTypeName] ? this._handles[nodeTypeName] : this._handles["*"];
-
- for (var i in handles) {
- if (handles[i].type != null) {
- this._drawHandle(handles[i], target);
- }
- }
+ if(!handleType){
+ handleType = 'add-edge'; //ie, CanvasHandleTypes.ADD_EDGE, which is the default
}
+ this._drawHandle(this._handles[handleType], target);
},
_clear: function () {
@@ -237,24 +250,14 @@
},
_drawHandle: function (handle, target) {
- var position = this._getHandlePosition(handle, target);
+ target.data().handleType = handle.type;
+ var position = this._getHandlePosition(target);
var handleSize = this.HANDLE_SIZE * this._cy.zoom();
+ this._ctx.clearRect(position.x, position.y, handleSize, handleSize);
- this._ctx.beginPath();
-
- if (handle.imageUrl) {
- var base_image = new Image();
- base_image.src = handle.imageUrl;
- this._ctx.drawImage(base_image, position.x, position.y, handleSize, handleSize);
- } else {
- this._ctx.arc(position.x, position.y, this.HANDLE_SIZE, 0, 2 * Math.PI, false);
- this._ctx.fillStyle = handle.color;
- this._ctx.strokeStyle = "white";
- this._ctx.lineWidth = 0;
- this._ctx.fill();
- this._ctx.stroke();
+ if (handle.image) {
+ this._ctx.drawImage(handle.image, position.x, position.y, handleSize, handleSize);
}
-
},
_drawArrow: function (fromNode, toPosition, handle) {
var toNode;
@@ -322,7 +325,10 @@
});
},
_mouseDown: function (e) {
- this._hit = this._hitTestHandles(e);
+ if(this._tagMode){
+ return;
+ }
+ //this._hit = this._hitTestHandles(e);
if (this._hit) {
this._lastClick = Date.now();
@@ -330,18 +336,22 @@
this._hover = null;
e.stopImmediatePropagation();
}
+
},
_hideHandles: function () {
this.permanentHandle = false;
this._clear();
- if(this._hover){
- this._showHandles(this._hover);
- }
},
- _mouseUp: function () {
+ _mouseUp: function (e) {
if (this._hover) {
- if (this._hit) {
+ if(this._tagMode){
+ if(this._hitTestHandles(e))
+ this._cy.trigger('handletagclick', {
+ nodeId: this._hover.data().id
+ });
+ //this._hover = null;
+ } else if (this._hit && this._dragging) {
//check if custom listener was passed, if so trigger it and do not add edge
var listeners = this._cy._private.listeners;
for (var i = 0; i < listeners.length; i++) {
@@ -371,7 +381,7 @@
data: {
source: this._dragging.id(),
target: this._hover.id(),
- type: this._hit.handle.type
+ type: "default"
}
});
this._initEdgeEvents(edge);
@@ -387,22 +397,22 @@
_mouseMove: function (e) {
if (this._hover) {
if (!this._dragging) {
- var hit = this._hitTestHandles(e);
- if (hit) {
+ this._hit = this._hitTestHandles(e);
+ if (this._hit) {
this._cy.trigger('handlemouseover', {
node: this._hover
});
$("body").css("cursor", "pointer");
-
} else {
this._cy.trigger('handlemouseout', {
node: this._hover
});
+ if(!this._tagMode){
+ this._showHandles(this._hover);
+ }
$("body").css("cursor", "inherit");
}
}
- } else {
- $("body").css("cursor", "inherit");
}
if (this._dragging && this._hit.handle) {
@@ -416,21 +426,24 @@
_mouseOver: function (e) {
if (this._dragging) {
- if ( (e.cyTarget.id() != this._dragging.id()) && e.cyTarget.data().allowConnection || this._hit.handle.allowLoop) {
+ if ( (e.cyTarget.id() != this._dragging.id()) && e.cyTarget.data().allowConnection) {
this._hover = e.cyTarget;
}
} else {
this._hover = e.cyTarget;
- this._showHandles(this._hover);
+ if (!this._tagMode) {
+ this._showHandles(this._hover);
+ }
}
},
_mouseOut: function (e) {
if(!this._dragging) {
- if (this.permanentHandle) {
- return;
+ if (!this.permanentHandle) {
+ this._clear();
}
-
- this._clear();
+ this._cy.trigger('handlemouseout', {
+ node: this._hover
+ });
}
this._hover = null;
},
@@ -450,63 +463,26 @@
_hitTestHandles: function (e) {
var mousePoisition = this._getRelativePosition(e);
- if (this._hover) {
- var nodeTypeName = this._hover.data().type;
- if (nodeTypeName) {
- var handles = this._handles[nodeTypeName] ? this._handles[nodeTypeName] : this._handles["*"];
-
- for (var i in handles) {
- var handle = handles[i];
-
- var position = this._getHandlePosition(handle, this._hover);
- var renderedHandleSize = this.HANDLE_SIZE * this._cy.zoom(); //actual number of pixels that handle uses.
- if (VectorMath.distance(position, mousePoisition) < renderedHandleSize) {
- return {
- handle: handle,
- position: position
- };
- }
- }
+ //if (this._hover) {
+ var position = this._getHandlePosition(this._hover);
+ var renderedHandleSize = this.HANDLE_SIZE * this._cy.zoom(); //actual number of pixels that handle uses.
+ if (VectorMath.distance(position, mousePoisition) < renderedHandleSize) {
+ var handleType = this._hover.data().handleType;
+ return {
+ handle: this._handles[handleType]
+ };
}
- }
+ //}
},
- _getHandlePosition: function (handle, target) { //returns the upper left point at which to begin drawing the handle
+ _getHandlePosition: function (target) { //returns the upper left point at which to begin drawing the handle
var position = target.renderedPosition();
var width = target.renderedWidth();
var height = target.renderedHeight();
var renderedHandleSize = this.HANDLE_SIZE * this._cy.zoom(); //actual number of pixels that handle will use.
- var xpos = null;
- var ypos = null;
+ var xpos = position.x + width / 2 - renderedHandleSize;
+ var ypos = position.y - height / 2;
- switch (handle.positionX) {
- case "left":
- xpos = position.x - width / 2;
- break;
- case "right": //position.x is the exact center of the node. Need to add half the width to get to the right edge. Then, subtract renderedHandleSize to get handle position
- xpos = position.x + width / 2 - renderedHandleSize;
- break;
- case "center":
- xpos = position.x;
- break;
- }
-
- switch (handle.positionY) {
- case "top":
- ypos = position.y - height / 2;
- break;
- case "center":
- ypos = position.y;
- break;
- case "bottom":
- ypos = position.y + height / 2;
- break;
- }
-
- //Determine if handle will be too big and require offset to prevent it from covering too much of the node icon (in which case, move it over by 1/2 the renderedHandleSize, so half the handle overlaps).
- //Need to use target.width(), which is the size of the node, unrelated to rendered size/zoom
- var offsetX = (target.width() < 30) ? renderedHandleSize / 2 : 0;
- var offsetY = (target.height() < 30) ? renderedHandleSize /2 : 0;
- return {x: xpos + offsetX, y: ypos - offsetY};
+ return {x: xpos, y: ypos};
},
_getEdgeCSSByHandle: function (handle) {
var color = handle.lineColor ? handle.lineColor : handle.color;
@@ -517,17 +493,6 @@
"width": handle.width? handle.width : 3
};
},
- _getHandleByType: function (type) {
- for (var i in this._handles) {
- var byNodeType = this._handles[i];
- for (var i2 in byNodeType) {
- var handle = byNodeType[i2];
- if (handle.type == type) {
- return handle;
- }
- }
- }
- },
_getRelativePosition: function (e) {
var containerPosition = this._$container.offset();
return {
@@ -559,8 +524,8 @@
},
_redraw: function () {
this._clear();
- if (this._hover) {
- this._showHandles(this._hover);
+ if(this._tagMode) {
+ this._cy.trigger('canvasredraw');
}
}
});
diff --git a/catalog-ui/src/typings/angularjs/angular.d.ts b/catalog-ui/src/typings/angularjs/angular.d.ts
index a5f56c0..36d68e1 100644
--- a/catalog-ui/src/typings/angularjs/angular.d.ts
+++ b/catalog-ui/src/typings/angularjs/angular.d.ts
@@ -1305,7 +1305,6 @@
interface IHttpPromise<T> extends IPromise<IHttpPromiseCallbackArg<T>> {
success(callback: IHttpPromiseCallback<T>): IHttpPromise<T>;
error(callback: IHttpPromiseCallback<any>): IHttpPromise<T>;
- then<TResult>(successCallback: (response: IHttpPromiseCallbackArg<T>) => IPromise<TResult>|TResult, errorCallback?: (response: IHttpPromiseCallbackArg<any>) => any): IPromise<TResult>;
}
/**