[SDC] rebase 1710
Change-Id: I07fced02f40a57700d9d35ed3ba498bca351fb13
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 707d7e4..805e5f0 100644
--- a/catalog-ui/src/app/app.ts
+++ b/catalog-ui/src/app/app.ts
@@ -53,6 +53,7 @@
import {AppModule} from './ng2/app.module';
import {PropertiesAssignmentComponent} from "./ng2/pages/properties-assignment/properties-assignment.page.component";
+import { SearchWithAutoCompleteComponent } from "./ng2/shared/search-with-autocomplete/search-with-autocomplete.component";
import {Component} from "./models/components/component";
import {ComponentServiceNg2} from "./ng2/services/component-services/component.service";
import {ComponentMetadata} from "./models/component-metadata";
@@ -145,6 +146,13 @@
export const ng1appModule:ng.IModule = angular.module(moduleName, dependentModules);
angular.module('sdcApp').directive('propertiesAssignment', downgradeComponent({component: PropertiesAssignmentComponent}) as angular.IDirectiveFactory);
+angular.module('sdcApp').directive('ng2SearchWithAutocomplete',
+ downgradeComponent({
+ component: SearchWithAutoCompleteComponent,
+ inputs: ['searchPlaceholder', 'searchBarClass', 'autoCompleteValues'],
+ outputs: ['searchChanged', 'searchButtonClicked']
+ }) as angular.IDirectiveFactory);
+
ng1appModule.config([
'$stateProvider',
@@ -161,7 +169,7 @@
NotificationProvider:any):void => {
NotificationProvider.setOptions({
- delay: 10000,
+ delay: 5000,
startTop: 10,
startRight: 10,
closeOnClick: true,
@@ -170,6 +178,7 @@
positionX: 'right',
positionY: 'top'
});
+ NotificationProvider.options.templateUrl = 'notification-custom-template.html';
$translateProvider.useStaticFilesLoader({
prefix: pathPrefix + 'assets/languages/',
@@ -617,6 +626,7 @@
'LeftPaletteLoaderService',
'Sdc.Services.DataTypesService',
'AngularJSBridge',
+ '$templateCache',
($http:ng.IHttpService,
cacheService:CacheService,
cookieService:CookieService,
@@ -632,8 +642,9 @@
ecompHeaderService:EcompHeaderService,
LeftPaletteLoaderService:LeftPaletteLoaderService,
DataTypesService:DataTypesService,
- AngularJSBridge):void => {
-
+ AngularJSBridge,
+ $templateCache:ng.ITemplateCacheService):void => {
+ $templateCache.put('notification-custom-template.html', require('./view-models/shared/notification-custom-template.html'));
//handle cache data - version
let initAsdcVersion:Function = ():void => {
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 0dcc93d..6419759 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
@@ -231,7 +231,7 @@
public static getBasicNodeHanlde = () => {
return {
- positionX: "center",
+ positionX: "right",
positionY: "top",
offsetX: 15,
offsetY: -20,
@@ -248,7 +248,7 @@
public static getBasicSmallNodeHandle = () => {
return {
- positionX: "center",
+ positionX: "right",
positionY: "top",
offsetX: 3,
offsetY: -25,
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 651a428..9aa7941 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
@@ -47,7 +47,8 @@
component:Component;
isLoading: boolean;
- isViewOnly:boolean;
+ isViewOnly: boolean;
+ withSidebar: boolean;
// Link menu - create link menu
relationMenuDirectiveObj:RelationMenuDirectiveObj;
isLinkMenuOpen:boolean;
@@ -65,6 +66,14 @@
//Links menus
deleteRelation(link:Cy.CollectionEdges):void;
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;
+
/*//asset popover menu
assetPopoverObj:AssetPopoverObj;
assetPopoverOpen:boolean;
@@ -101,7 +110,8 @@
template = require('./composition-graph.html');
scope = {
component: '=',
- isViewOnly: '='
+ isViewOnly: '=',
+ withSidebar: '='
};
link = (scope:ICompositionGraphScope, el:JQuery) => {
@@ -147,7 +157,11 @@
this._cy = cytoscape({
container: graphEl,
style: ComponentInstanceNodesStyle.getCompositionGraphStyle(),
- zoomingEnabled: false,
+ zoomingEnabled: true,
+ maxZoom: 2.5,
+ minZoom: .1,
+ userZoomingEnabled: false,
+ userPanningEnabled: true,
selectionType: 'single',
boxSelectionEnabled: true,
autolock: isViewOnly,
@@ -270,6 +284,40 @@
this.loadGraphData(scope);
});
+ scope.zoom = (zoomIn: boolean):void => {
+ let currentZoom: number = this._cy.zoom();
+ if (zoomIn) {
+ this.GeneralGraphUtils.zoomGraphTo(this._cy, currentZoom + .1);
+ } else {
+ this.GeneralGraphUtils.zoomGraphTo(this._cy, currentZoom - .1);
+ }
+ }
+
+ //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) => {
+ scope.withSidebar = false;
+ this._cy.animate({
+ fit: { eles: nodes, padding: 20 },
+ center: { eles: nodes }
+ }, { duration: 400 });
+ };
+
+ 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);
+ scope.componentInstanceNames = _.map(nodes, node => node.data('name'));
+ } else {
+ scope.componentInstanceNames = [];
+ }
+ };
+
+ scope.highlightSearchMatches = (searchTerm: string) => {
+ if (searchTerm === undefined) return; //dont zoom & highlight if click on Search initially (searchTerm will be undefined). However, allow highlights to be cleared after subsequent search (searchTerm will be "")
+
+ this.NodesGraphUtils.highlightMatchingNodesByName(this._cy, searchTerm);
+ let matchingNodes: Cy.CollectionNodes = this.NodesGraphUtils.getMatchingNodesByName(this._cy, searchTerm);
+ scope.zoomAll(matchingNodes);
+ };
scope.createLinkFromMenu = (chosenMatch:MatchBase):void => {
scope.isLinkMenuOpen = false;
@@ -367,7 +415,7 @@
});*/
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
+ 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;
}
let nodesData = this.NodesGraphUtils.getAllNodesData(this._cy.nodes());
@@ -377,9 +425,9 @@
let filteredNodesData = this.matchCapabilitiesRequirementsUtils.findByMatchingCapabilitiesToRequirements(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();*/
+ /*scope.hideAssetPopover();*/
});
this._cy.on('handlemouseout', () => {
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 1e69d33..248f19f 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
@@ -20,4 +20,11 @@
</div>
+ <div class="w-sdc-search-menu" data-ng-class="{'with-sidebar': withSidebar}">
+ <ng2-search-with-autocomplete [search-placeholder]="'Type to search'" [auto-complete-values]="componentInstanceNames" (search-changed)="getAutoCompleteValues($event)" (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 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>-->
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 6080314..0ea38af 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
@@ -64,6 +64,14 @@
};
+ public zoomGraphTo = (cy:Cy.Instance, zoomLevel: number):void => {
+ let zy = cy.height() / 2;
+ let zx = cy.width() / 2;
+ cy.zoom({
+ level: zoomLevel,
+ renderedPosition: { x: zx, y: zy }
+ });
+ }
/**
* will return true/false if two nodes overlapping
*
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 feb6ac9..449d551 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
@@ -48,6 +48,21 @@
})
};
+
+ public highlightMatchingNodesByName = (cy: Cy.Instance, nameToMatch: string) => {
+
+ cy.batch(() => {
+ cy.nodes("[name !@^= '" + nameToMatch + "']").style({ 'background-image-opacity': 0.4 });
+ cy.nodes("[name @^= '" + nameToMatch + "']").style({ 'background-image-opacity': 1 });
+ })
+
+ }
+
+ //Returns all nodes whose name starts with searchTerm
+ public getMatchingNodesByName = (cy: Cy.Instance, nameToMatch: string): Cy.CollectionNodes => {
+ return cy.nodes("[name @^= '" + nameToMatch + "']");
+ };
+
/**
* Deletes component instances on server and then removes it from the graph as well
* @param cy
diff --git a/catalog-ui/src/app/models/components/component.ts b/catalog-ui/src/app/models/components/component.ts
index 9b2c942..53e8f05 100644
--- a/catalog-ui/src/app/models/components/component.ts
+++ b/catalog-ui/src/app/models/components/component.ts
@@ -923,16 +923,17 @@
}
public toJSON = ():any => {
- this.componentService = undefined;
- this.filterTerm = undefined;
- this.iconSprite = undefined;
- this.mainCategory = undefined;
- this.subCategory = undefined;
- this.selectedInstance = undefined;
- this.showMenu = undefined;
- this.$q = undefined;
- this.selectedCategory = undefined;
- return this;
+ 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;
+ return temp;
};
}
diff --git a/catalog-ui/src/app/models/components/resource.ts b/catalog-ui/src/app/models/components/resource.ts
index 138b413..cd83978 100644
--- a/catalog-ui/src/app/models/components/resource.ts
+++ b/catalog-ui/src/app/models/components/resource.ts
@@ -163,17 +163,18 @@
};
public toJSON = ():any => {
- this.componentService = undefined;
- this.filterTerm = undefined;
- this.iconSprite = undefined;
- this.mainCategory = undefined;
- this.subCategory = undefined;
- this.selectedInstance = undefined;
- this.showMenu = undefined;
- this.$q = undefined;
- this.selectedCategory = undefined;
- this.importedFile = undefined;
- return this;
+ 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.importedFile = undefined;
+ return temp;
};
}
diff --git a/catalog-ui/src/app/ng2/app.module.ts b/catalog-ui/src/app/ng2/app.module.ts
index 09b40e9..57adb8f 100644
--- a/catalog-ui/src/app/ng2/app.module.ts
+++ b/catalog-ui/src/app/ng2/app.module.ts
@@ -40,6 +40,8 @@
import { InterceptorService } from 'ng2-interceptors';
import { XHRBackend, RequestOptions } from '@angular/http';
import {HttpInterceptor} from "./services/http.interceptor.service";
+import { SearchBarComponent } from './shared/search-bar/search-bar.component';
+import { SearchWithAutoCompleteComponent } from './shared/search-with-autocomplete/search-with-autocomplete.component';
export const upgradeAdapter = new UpgradeAdapter(forwardRef(() => AppModule));
@@ -60,7 +62,9 @@
@NgModule({
declarations: [
- AppComponent
+ AppComponent,
+ SearchBarComponent,
+ SearchWithAutoCompleteComponent
],
imports: [
BrowserModule,
@@ -70,7 +74,7 @@
PropertiesAssignmentModule
],
exports: [],
- entryComponents: [],
+ entryComponents: [SearchWithAutoCompleteComponent],
providers: [
DataTypesServiceProvider,
SharingServiceProvider,
diff --git a/catalog-ui/src/app/ng2/components/inputs-table/inputs-table.component.less b/catalog-ui/src/app/ng2/components/inputs-table/inputs-table.component.less
index 05378f0..89c7287 100644
--- a/catalog-ui/src/app/ng2/components/inputs-table/inputs-table.component.less
+++ b/catalog-ui/src/app/ng2/components/inputs-table/inputs-table.component.less
@@ -85,7 +85,7 @@
border-right:#d2d2d2 solid 1px;
}
&.col1 {
- flex: 0 0 300px;
+ flex: 1 0 200px;
max-width:300px;
display: flex;
justify-content: space-between;
diff --git a/catalog-ui/src/app/ng2/components/properties-table/properties-table.component.less b/catalog-ui/src/app/ng2/components/properties-table/properties-table.component.less
index 3eb7e96..9ede84f 100644
--- a/catalog-ui/src/app/ng2/components/properties-table/properties-table.component.less
+++ b/catalog-ui/src/app/ng2/components/properties-table/properties-table.component.less
@@ -91,7 +91,7 @@
border-right:#d2d2d2 solid 1px;
}
&.col1 {
- flex: 0 0 300px;
+ flex: 1 0 210px;
max-width:300px;
display: flex;
justify-content: space-between;
@@ -100,7 +100,7 @@
.property-name {
flex: 1;
display: flex;
- max-width: 270px;
+ max-width: 90%;
}
.property-description-icon {
@@ -123,7 +123,7 @@
}
&.valueCol {
- flex: 1 0 350px;
+ flex: 2 0 300px;
display: flex;
@media @smaller-screen { flex: 1 0 40%;}
}
diff --git a/catalog-ui/src/app/ng2/shared/search-bar/search-bar.component.html b/catalog-ui/src/app/ng2/shared/search-bar/search-bar.component.html
new file mode 100644
index 0000000..3662959
--- /dev/null
+++ b/catalog-ui/src/app/ng2/shared/search-bar/search-bar.component.html
@@ -0,0 +1,5 @@
+<div class="search-bar-container {{class}}">
+ <input class="search-bar-input" type="text" [placeholder]="placeholder" [(ngModel)]="searchQuery" (ngModelChange)="searchQueryChange($event)"/>
+ <span class="clear-search-x" *ngIf="searchQuery" (click)="clearSearchQuery()">x</span>
+ <button class="search-bar-button" (click)="searchButtonClick()"></button>
+</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/shared/search-bar/search-bar.component.less b/catalog-ui/src/app/ng2/shared/search-bar/search-bar.component.less
new file mode 100644
index 0000000..cfeb8d3
--- /dev/null
+++ b/catalog-ui/src/app/ng2/shared/search-bar/search-bar.component.less
@@ -0,0 +1,58 @@
+.search-bar-container {
+ display:flex;
+ border-radius: 4px;
+ box-shadow: 0px 2px 3.88px 0.12px rgba(0, 0, 0, 0.29);
+
+ .search-bar-input {
+ border: 1px solid #cdcdcd;
+ border-radius: 4px;
+ border-right:none;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ outline:none;
+ padding:2px 50px 2px 10px;
+ color: #5a5a5a;
+ font-size: 1em;
+ font-style: italic;
+ }
+
+ .clear-search-x {
+ position:absolute;
+ right:40px;
+ top:5px;
+ padding: 0 5px;
+
+ &:hover {
+ border-radius:2px;
+ background-color: #ebebeb;
+ cursor:pointer;
+ }
+ }
+
+ .search-bar-button {
+ //background: url('../../../../assets/styles/svg/source/search-magnify.svg') no-repeat 50%;
+ background: url('../../../../assets/styles/images/sprites/sprite-global.png') no-repeat -206px -1275px;
+ background-color: rgba(234, 234, 234, 0.88);
+ width: 30px;
+ height: 30px;
+ padding: 0;
+ cursor:pointer;
+ border:solid 1px #cdcdcd;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+
+ &:hover {
+ background-position:-126px -1275px;
+ }
+
+ &:active {
+ background-color: rgba(31, 171, 223, 0.88);
+ background-position:-45px -1275px;
+ border-left:none;
+ }
+ &:focus {
+ outline:none;
+ }
+
+ }
+}
diff --git a/catalog-ui/src/app/ng2/shared/search-bar/search-bar.component.ts b/catalog-ui/src/app/ng2/shared/search-bar/search-bar.component.ts
new file mode 100644
index 0000000..2835d20
--- /dev/null
+++ b/catalog-ui/src/app/ng2/shared/search-bar/search-bar.component.ts
@@ -0,0 +1,30 @@
+import { Component, Input, Output, EventEmitter, ViewEncapsulation } from '@angular/core';
+
+@Component({
+ selector: 'search-bar',
+ templateUrl: './search-bar.component.html',
+ styleUrls: ['./search-bar.component.less'],
+ encapsulation: ViewEncapsulation.None
+})
+export class SearchBarComponent {
+
+ @Input() placeholder: string;
+ @Input() class: string;
+ @Input() searchQuery: string;
+ @Output() searchChanged: EventEmitter<any> = new EventEmitter<any>();
+ @Output() searchButtonClicked: EventEmitter<string> = new EventEmitter<string>();
+
+ searchButtonClick = (): void => {
+ this.searchButtonClicked.emit(this.searchQuery);
+ }
+
+ searchQueryChange = ($event): void => {
+ this.searchChanged.emit($event);
+ }
+
+ private clearSearchQuery = (): void => {
+ this.searchQuery = "";
+ this.searchButtonClick();
+ }
+}
+
diff --git a/catalog-ui/src/app/ng2/shared/search-with-autocomplete/search-with-autocomplete.component.html b/catalog-ui/src/app/ng2/shared/search-with-autocomplete/search-with-autocomplete.component.html
new file mode 100644
index 0000000..c9769ba
--- /dev/null
+++ b/catalog-ui/src/app/ng2/shared/search-with-autocomplete/search-with-autocomplete.component.html
@@ -0,0 +1,6 @@
+<div class="search-with-autocomplete-container {{searchBarClass}}" [class.autocomplete-visible]="autoCompleteValues && autoCompleteValues.length" [class.active]="searchQuery && searchQuery.length">
+ <search-bar [placeholder]="searchPlaceholder" [searchQuery]="searchQuery" (searchButtonClicked)="updateSearch($event)" (searchChanged)="searchChange($event)"></search-bar>
+ <div class="autocomplete-results">
+ <div *ngFor="let item of autoCompleteValues" class="autocomplete-result-item" (click)="updateSearch(item)">{{item}}</div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/shared/search-with-autocomplete/search-with-autocomplete.component.less b/catalog-ui/src/app/ng2/shared/search-with-autocomplete/search-with-autocomplete.component.less
new file mode 100644
index 0000000..92b054c
--- /dev/null
+++ b/catalog-ui/src/app/ng2/shared/search-with-autocomplete/search-with-autocomplete.component.less
@@ -0,0 +1,35 @@
+
+.search-with-autocomplete-container{
+ &.autocomplete-visible {
+
+ .search-bar-input {
+ border-bottom-left-radius: 0;
+ }
+ .search-bar-button {
+ border-bottom-right-radius: 0;
+ }
+ .autocomplete-results {
+ border: solid 1px #d2d2d2;
+ border-top:none;
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ background-color: #fff;
+ padding: 10px 20px;
+ width:100%;
+ position:absolute;
+ max-height: 200px;
+ overflow-y: scroll;
+ }
+
+ .autocomplete-result-item {
+ color:#5a5a5a;
+ padding: 5px 0;
+ cursor:pointer;
+
+ &:hover {
+ color: #999;
+ }
+ }
+ }
+}
+
diff --git a/catalog-ui/src/app/ng2/shared/search-with-autocomplete/search-with-autocomplete.component.ts b/catalog-ui/src/app/ng2/shared/search-with-autocomplete/search-with-autocomplete.component.ts
new file mode 100644
index 0000000..ced056d
--- /dev/null
+++ b/catalog-ui/src/app/ng2/shared/search-with-autocomplete/search-with-autocomplete.component.ts
@@ -0,0 +1,30 @@
+import { Component, Input, Output, EventEmitter, ViewEncapsulation } from '@angular/core';
+import { SearchBarComponent } from '../search-bar/search-bar.component';
+
+@Component({
+ selector: 'search-with-autocomplete',
+ templateUrl: './search-with-autocomplete.component.html',
+ styleUrls: ['./search-with-autocomplete.component.less'],
+ encapsulation: ViewEncapsulation.None
+})
+export class SearchWithAutoCompleteComponent {
+
+ @Input() searchPlaceholder: string;
+ @Input() searchBarClass: string;
+ @Input() searchQuery: string;
+ @Input() autoCompleteValues: Array<string>;
+ @Output() searchChanged: EventEmitter<any> = new EventEmitter<any>();
+ @Output() searchButtonClicked: EventEmitter<string> = new EventEmitter<string>();
+
+ searchChange = (searchTerm: string) => {
+ this.searchQuery = searchTerm;
+ this.searchChanged.emit(searchTerm);
+ }
+
+ updateSearch = (searchTerm: string) => {
+ this.searchQuery = searchTerm;
+ this.searchButtonClicked.emit(searchTerm);
+ this.autoCompleteValues = [];
+ }
+}
+
diff --git a/catalog-ui/src/app/view-models/shared/notification-custom-template.html b/catalog-ui/src/app/view-models/shared/notification-custom-template.html
new file mode 100644
index 0000000..d8fdf13
--- /dev/null
+++ b/catalog-ui/src/app/view-models/shared/notification-custom-template.html
@@ -0,0 +1,14 @@
+<div class="ui-notification">
+ <div class="notification-container">
+ <div class="icon-container">
+ <div class="icon-circle">
+ <div class="icon sprite-new">
+ </div>
+ </div>
+ </div>
+ <div class="msg-content">
+ <h3 ng-show="title" ng-bind-html="title"></h3>
+ <div class="message" ng-bind-html="message"></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 fbd32cc..0e5a5fc 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
@@ -30,7 +30,8 @@
export interface ICompositionViewModelScope extends IWorkspaceViewModelScope {
currentComponent:Component;
- selectedComponent:Component;
+ selectedComponent: Component;
+ componentInstanceNames: Array<string>;
isLoading:boolean;
graphApi:any;
sharingService:SharingService;
@@ -130,7 +131,6 @@
private openUpdateComponentInstanceNameModal = ():void => {
this.ModalsHandler.openUpdateComponentInstanceNameModal(this.$scope.currentComponent).then(()=> {
this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_COMPONENT_INSTANCE_NAME_CHANGED, this.$scope.currentComponent.selectedInstance);
-
});
};
@@ -225,7 +225,7 @@
this.$scope.openUpdateModal = ():void => {
this.openUpdateComponentInstanceNameModal();
};
-
+
this.$scope.deleteSelectedComponentInstance = ():void => {
let state = "deleteInstance";
let onOk = ():void => {
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 cef942e..e05574e 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
@@ -6,7 +6,7 @@
is-loading="isLoading"></palette>
<composition-graph component="currentComponent" data-tests-id="canvas"
- is-view-only="isViewOnly"></composition-graph>
+ is-view-only="isViewOnly" with-sidebar="displayDesignerRightSidebar"></composition-graph>
</div>
<div class="w-sdc-designer-sidebar-toggle" data-ng-class="{'active': displayDesignerRightSidebar}"
@@ -21,7 +21,7 @@
<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, 'smaller-icon': selectedComponent.icon==='vl' || selectedComponent.icon==='cp'}"
+ data-ng-class="{'non-certified':'CERTIFIED' !== selectedComponent.lifecycleState}"
tooltips tooltip-side="top" tooltip-content="Not certified"></div>
</div>
</div>
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 7a775bd..262dfd9 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
@@ -781,6 +781,71 @@
line-height: 18px;
}
+ //Canvas search menu
+ .w-sdc-search-menu {
+ position:absolute;
+ right: 18px;
+ top:53px;
+ transition: right 0.2s;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ margin-right:10px;
+
+ &.with-sidebar {
+ right:320px;
+ }
+
+ .search-with-autocomplete-container.composition-search {
+ margin-top: 12px;
+
+ .search-bar-input {
+ width: 250px;
+ padding:2px 50px 2px 10px;
+ transition:all 0.4s;
+ }
+ .clear-search-x {
+ top: 17px
+ }
+
+ &:not(:hover):not(.autocomplete-visible):not(.active){
+ border-radius: 0;
+ box-shadow:none;
+
+ .search-bar-input:not(:focus){
+ width: 0px;
+ padding:0;
+ border:none;
+ }
+ .clear-search-x {
+ display:none;
+ }
+ .search-bar-input:not(:focus) ~ .search-bar-button {
+ border-radius: 2px;
+ border:solid 1px #fff;
+ }
+ }
+ }
+
+ .zoom-icons {
+ border:solid 1px #fff;
+ border-radius: 2px;
+ box-shadow: 0px 2px 3.88px 0.12px rgba(0, 0, 0, 0.29);
+ background-color: rgba(234, 234, 234, 0.88);
+ background-repeat: no-repeat;
+ margin-top: 10px;
+
+ &:hover {
+ cursor:pointer;
+ }
+
+ &:active {
+ border:none;
+ background-color: rgba(31, 171, 223, 0.88);
+ }
+ }
+ }
+
// ---------------------------------------------------------------------------------------------------
// Canvas inline menu
// ---------------------------------------------------------------------------------------------------
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view-model.ts
index 83e4653..c4c63fa 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view-model.ts
+++ b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view-model.ts
@@ -33,13 +33,14 @@
import {ArtifactsUtils, ModalsHandler, ArtifactGroupType} from "app/utils";
import {GRAPH_EVENTS} from "app/utils/constants";
import {EventListenerService} from "app/services/event-listener-service";
+import {Dictionary} from "../../../../../../utils/dictionary/dictionary";
export interface IArtifactsViewModelScope extends ICompositionViewModelScope {
artifacts:Array<ArtifactModel>;
artifactType:string;
downloadFile:IFileDownload;
isLoading:boolean;
-
+ displayDeleteButtonMap:Dictionary<string, boolean>;
getTitle():string;
addOrUpdate(artifact:ArtifactModel):void;
delete(artifact:ArtifactModel):void;
@@ -125,6 +126,10 @@
}
}
this.$scope.artifacts = artifacts;
+ this.$scope.displayDeleteButtonMap = new Dictionary<string, boolean>();
+ _.forEach(this.$scope.artifacts, (artifact:ArtifactModel)=>{
+ this.$scope.displayDeleteButtonMap[artifact.artifactLabel] = this.displayDeleteButton(artifact);
+ });
this.$scope.isLoading = false;
};
@@ -229,6 +234,17 @@
});
};
+ private displayDeleteButton = (artifact:ArtifactModel):boolean => {
+ if(!this.$scope.isViewMode() && artifact.esId){
+ if(this.$scope.isComponentInstanceSelected()){//is artifact of instance
+ return !this.$scope.selectedComponent.deploymentArtifacts || !this.$scope.selectedComponent.deploymentArtifacts[artifact.artifactLabel];//if the artifact is not from instance parent
+ }else{//is artifact of main component
+ return (!artifact.isHEAT() && !artifact.isThirdParty() && !this.$scope.isLicenseArtifact(artifact));
+ }
+ }
+ return false;
+};
+
private initScope = ():void => {
this.$scope.isLoading = false;
diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view.html b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view.html
index 8221c67..dfbd639 100644
--- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view.html
+++ b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view.html
@@ -36,7 +36,7 @@
<span class="i-sdc-designer-sidebar-section-content-item-artifact-details-desc-label" data-ng-show="artifact.description">Description:</span>{{artifact.description}}
</div>
</div>
- <button ng-if="!isViewMode() && artifact.esId && !isComponentInstanceSelected() && !artifact.isHEAT() && !artifact.isThirdParty() && !isLicenseArtifact(artifact)" class="i-sdc-designer-sidebar-section-content-item-button delete sprite e-sdc-small-icon-delete"
+ <button ng-if="displayDeleteButtonMap[artifact.artifactLabel]" class="i-sdc-designer-sidebar-section-content-item-button delete sprite e-sdc-small-icon-delete"
data-tests-id="delete_{{artifact.artifactDisplayName}}" data-ng-click="delete(artifact)" type="button"></button>
<button ng-if="!isViewMode() && artifact.isHEAT() && isComponentInstanceSelected() && artifact.heatParameters.length"
class="i-sdc-designer-sidebar-section-content-item-button attach sprite e-sdc-small-icon-pad"
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 8607d65..0418515 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
@@ -23,9 +23,9 @@
<span class="i-sdc-designer-sidebar-section-content-item-label">Version:</span>
<span class="i-sdc-designer-sidebar-section-content-item-value"
- data-ng-if="!isComponentInstanceSelected() || selectedComponent.isVl()" data-tests-id="rightTab_version" data-ng-bind="selectedComponent.version"></span>
+ data-ng-if="!isComponentInstanceSelected()" data-tests-id="rightTab_version" data-ng-bind="selectedComponent.version"></span>
- <ng-form name="editForm" data-ng-if="isComponentInstanceSelected() && !selectedComponent.isVl()">
+ <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"
class="i-sdc-designer-sidebar-section-content-item-value i-sdc-form-select"
data-ng-class="{'minor': (editResourceVersion.changeVersion)%1}"
diff --git a/catalog-ui/src/app/view-models/workspace/workspace.less b/catalog-ui/src/app/view-models/workspace/workspace.less
index b7331b5..d0799f4 100644
--- a/catalog-ui/src/app/view-models/workspace/workspace.less
+++ b/catalog-ui/src/app/view-models/workspace/workspace.less
@@ -170,6 +170,9 @@
line-height: 110px;
.f-type ._28;
}
+ &.composition .w-sdc-main-container-body-content {
+ height: calc(~'100% - @{action_nav_height}'); //composition is the only tab without a tab title. need to exclude from calculation.
+ }
.w-sdc-main-container-body-content {
height:calc(~'100% - @{action_nav_height} - @{tab_title}');
align-items: center;
diff --git a/catalog-ui/src/assets/styles/app.less b/catalog-ui/src/assets/styles/app.less
index 13d88a3..fde4cc8 100644
--- a/catalog-ui/src/assets/styles/app.less
+++ b/catalog-ui/src/assets/styles/app.less
@@ -34,6 +34,7 @@
@import 'welcome-sprite.less';
@import 'welcome-style.less';
@import 'sdc-ui.css';
+@import 'notification-template.less';
// Less insides specific files.
@import '../../app/directives/ecomp-footer/ecomp-footer.less';
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 962478f..87e5d43 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/notification-template.less b/catalog-ui/src/assets/styles/notification-template.less
new file mode 100644
index 0000000..5baf10d
--- /dev/null
+++ b/catalog-ui/src/assets/styles/notification-template.less
@@ -0,0 +1,53 @@
+.notification-container{
+ display: flex;
+ padding: 15px 11px;
+ float: left;
+ .icon-container{
+ flex-grow: 1;
+ margin-right: 20px;
+ .icon-circle{
+ background-color: black;
+ height: 40px;
+ width: 40px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ margin-right: 0;
+ background-color: rgba(255, 255, 255, 0.3);
+ .icon{
+ margin: 0 auto;
+ display: block;
+ }
+ }
+ }
+ .msg-content{
+ flex-grow: 3;
+ h3{
+ border-bottom: none;
+ font-weight: 400;
+ .f-type._18_m;
+ }
+ .message{
+ font-weight: 300;
+ .f-type._14_m;
+ }
+ }
+}
+.ui-notification.success{
+ background-color: @main_color_d;
+ .icon{
+ .notification-success-icon;
+ }
+}
+.ui-notification.error{
+ background-color: @func_color_q;
+ .icon{
+ .notification-error-icon;
+ }
+}
+.ui-notification.info{
+ background-color: @main_color_a;
+ .icon{
+ .notification-process-icon;
+ }
+}
diff --git a/catalog-ui/src/assets/styles/sprite.less b/catalog-ui/src/assets/styles/sprite.less
index 2076744..3f82e48 100644
--- a/catalog-ui/src/assets/styles/sprite.less
+++ b/catalog-ui/src/assets/styles/sprite.less
@@ -238,8 +238,12 @@
.round-expand-icon:hover { background-position: -100px -1188px; width: 15px; height: 15px; }
.round-expand-icon.open { background-position: -50px -1216px; width: 15px; height: 15px; }
.round-expand-icon.open:hover { background-position: -100px -1216px; width: 15px; height: 15px; }
-.update-component-icon { background-position: -140px -1183px; width: 20px; height: 20px;}
-.update-component-icon:hover { background-position: -170px -1183px; width: 20px; height: 20px;}
+.update-component-icon { background-position: -140px -1213px; width: 20px; height: 20px;}
+.update-component-icon:hover { background-position: -169px -1213px; width: 20px; height: 20px;}
+.notification-user-icon{ background-position: -206px -1211px; width: 18px; height: 22px;}
+.notification-error-icon{ background-position: -244px -1216px; width: 17px; height: 17px;}
+.notification-success-icon{ background-position: -281px -1215px; width: 21px; height: 19px;}
+.notification-process-icon{ background-position: -322px -1206px; width: 28px; height: 28px;}
/*
.sprite-new.expand-asset-icon { background-position: -740px -590px; width: 40px; height: 40px; }
.sprite-new.view-info-icon { background-position: -739px -621px; width: 40px; height: 40px; }
@@ -259,3 +263,20 @@
.sprite-new.vl-icon:active, .sprite-new.vl-icon.disabled-icon { background-position: -820px -682px; }
.sprite-new.trash-icon:active, .sprite-new.trash-icon.disabled-icon { background-position: -820px -712px; }
*/
+
+
+.sprite-new.magnify-search { background-position: -206px -1276px; width: 30px; height: 30px; }
+.sprite-new.magnify-search:hover { background-position: -125px -1276px; }
+.sprite-new.magnify-search:active { background-position: -46px -1275px; }
+
+.sprite-new.zoom-plus { background-position: -208px -1380px; width: 30px; height: 30px; }
+.sprite-new.zoom-plus:hover { background-position: -128px -1380px; }
+.sprite-new.zoom-plus:active { background-position: -47px -1379px; }
+
+.sprite-new.zoom-minus { background-position: -208px -1433px; width: 30px; height: 30px; }
+.sprite-new.zoom-minus:hover { background-position: -128px -1433px; }
+.sprite-new.zoom-minus:active { background-position: -47px -1432px; }
+
+.sprite-new.canvas-fit-all { background-position: -208px -1326px; width: 30px; height: 30px;}
+.sprite-new.canvas-fit-all:hover { background-position: -128px -1326px; }
+.sprite-new.canvas-fit-all:active { background-position: -47px -1325px;}
diff --git a/catalog-ui/src/assets/styles/svg/source/fit-all.svg b/catalog-ui/src/assets/styles/svg/source/fit-all.svg
new file mode 100644
index 0000000..dbea909
--- /dev/null
+++ b/catalog-ui/src/assets/styles/svg/source/fit-all.svg
@@ -0,0 +1,5 @@
+<?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">
+<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
new file mode 100644
index 0000000..4ced110
--- /dev/null
+++ b/catalog-ui/src/assets/styles/svg/source/minus.svg
@@ -0,0 +1,5 @@
+<?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">
+<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
new file mode 100644
index 0000000..dff172c
--- /dev/null
+++ b/catalog-ui/src/assets/styles/svg/source/plus.svg
@@ -0,0 +1,5 @@
+<?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">
+<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
new file mode 100644
index 0000000..279c13f
--- /dev/null
+++ b/catalog-ui/src/assets/styles/svg/source/search-magnify.svg
@@ -0,0 +1,5 @@
+<?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">
+<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/third-party/cytoscape.js-edge-editation/CytoscapeEdgeEditation.js b/catalog-ui/src/third-party/cytoscape.js-edge-editation/CytoscapeEdgeEditation.js
index 2da6f78..9be07f2 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
@@ -250,13 +250,14 @@
_drawHandle: function (handle, target) {
var position = this._getHandlePosition(handle, target);
-
+ var handleSize = target.renderedWidth() / 4;
+
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, this.HANDLE_SIZE, this.HANDLE_SIZE);
+ 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;
@@ -461,17 +462,17 @@
},
_getHandlePosition: function (handle, target) {
var position = target.renderedPosition();
- var width = target.renderedOuterWidth();
- var height = target.renderedOuterHeight();
+ var width = target.renderedWidth();
+ var height = target.renderedHeight();
var xpos = null;
var ypos = null;
switch (handle.positionX) {
case "left":
- xpos = position.x - width / 2 + this.HANDLE_SIZE;
+ xpos = position.x - width / 4;
break;
case "right":
- xpos = position.x + width / 2 - this.HANDLE_SIZE;
+ xpos = position.x + width / 4;
break;
case "center":
xpos = position.x;
@@ -480,18 +481,18 @@
switch (handle.positionY) {
case "top":
- ypos = position.y - height / 2 + this.HANDLE_SIZE;
+ ypos = position.y - width / 2;
break;
case "center":
ypos = position.y;
break;
case "bottom":
- ypos = position.y + height / 2 - this.HANDLE_SIZE;
+ ypos = position.y + width / 2;
break;
}
- var offsetX = handle.offsetX ? handle.offsetX : 0;
- var offsetY = handle.offsetY ? handle.offsetY : 0;
+ var offsetX = 0;
+ var offsetY = 0;
return {x: xpos + offsetX, y: ypos + offsetY};
},
_getEdgeCSSByHandle: function (handle) {