2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 import * as _ from "lodash";
21 import {Component, IAppMenu, LeftPanelModel, NodesFactory, LeftPaletteComponent, CompositionCiNodeBase, ComponentInstance, Point} from "app/models";
22 import {CompositionGraphGeneralUtils} from "../composition-graph/utils/composition-graph-general-utils";
23 import {EventListenerService} from "app/services";
24 import {ResourceType, GRAPH_EVENTS, EVENTS, ComponentInstanceFactory, ModalsHandler} from "app/utils";
25 import 'sdc-angular-dragdrop';
26 import {LeftPaletteLoaderService} from "../../../services/components/utils/composition-left-palette-service";
27 import {Resource} from "app/models/components/resource";
28 import {ComponentType} from "app/utils/constants";
29 import {LeftPaletteMetadataTypes} from "../../../models/components/displayComponent";
32 interface IPaletteScope {
33 components:Array<LeftPaletteComponent>;
34 currentComponent:Component;
36 displaySortedCategories:any;
37 expandedSection:string;
40 event:JQueryEventObject,
41 components:LeftPaletteComponent,
45 addInstanceClick: ()=>void; // added code
46 onPopupMouseOver: ()=>void // added code
47 onPopupMouseOut: ()=>void // added code
49 sectionClick:(section:string)=>void;
50 searchComponents:(searchText:string)=>void;
51 onMouseOver:(displayComponent:LeftPaletteComponent, elem: HTMLElement)=>void;
52 onMouseOut:(displayComponent:LeftPaletteComponent)=>void;
54 dragStartCallback:(event:JQueryEventObject, ui, displayComponent:LeftPaletteComponent)=>void;
55 dragStopCallback:()=>void;
56 onDragCallback:(event:JQueryEventObject) => void;
58 setElementTemplate:(e:JQueryEventObject)=>void;
66 export class Palette implements ng.IDirective {
67 constructor(private $log:ng.ILogService,
68 private LeftPaletteLoaderService: LeftPaletteLoaderService,
70 private ComponentFactory,
71 private ComponentInstanceFactory:ComponentInstanceFactory,
72 private NodesFactory:NodesFactory,
73 private CompositionGraphGeneralUtils:CompositionGraphGeneralUtils,
74 private EventListenerService:EventListenerService,
75 private sdcMenu:IAppMenu,
76 private ModalsHandler:ModalsHandler
80 private fetchingComponentFromServer:boolean = false;
81 private nodeHtmlSubstitute:JQuery;
84 currentComponent: '=',
89 template = require('./palette.html');
91 link = (scope:IPaletteScope, el:JQuery) => {
92 this.nodeHtmlSubstitute = $('<div class="node-substitute"><span></span><img /></div>');
93 el.append(this.nodeHtmlSubstitute);
94 this.registerEventListenerForLeftPalette(scope);
96 this.initComponents(scope);
97 this.initEvents(scope);
98 this.initDragEvents(scope);
99 this._initExpandedSection(scope, '');
100 el.on('$destroy', ()=> {
101 //remove listener of download event
102 this.unRegisterEventListenerForLeftPalette(scope);
107 private registerEventListenerForLeftPalette = (scope:IPaletteScope):void => {
108 this.EventListenerService.registerObserverCallback(EVENTS.LEFT_PALETTE_UPDATE_EVENT, () => {
109 this.updateLeftPanelDisplay(scope);
113 private unRegisterEventListenerForLeftPalette = (scope:IPaletteScope):void => {
114 this.EventListenerService.unRegisterObserver(EVENTS.LEFT_PALETTE_UPDATE_EVENT);
117 private leftPanelResourceFilter(resourcesNotAbstract:Array<LeftPaletteComponent>, resourceFilterTypes:Array<string>):Array<LeftPaletteComponent> {
118 let filterResources = _.filter(resourcesNotAbstract, (component) => {
119 return resourceFilterTypes.indexOf(component.getComponentSubType()) > -1;
121 return filterResources;
124 private initLeftPanel(leftPanelComponents:Array<LeftPaletteComponent>, resourceFilterTypes:Array<string>):LeftPanelModel {
125 let leftPanelModel = new LeftPanelModel();
127 if (resourceFilterTypes && resourceFilterTypes.length) {
128 leftPanelComponents = this.leftPanelResourceFilter(leftPanelComponents, resourceFilterTypes);
130 leftPanelModel.numberOfElements = leftPanelComponents && leftPanelComponents.length || 0;
132 if (leftPanelComponents && leftPanelComponents.length) {
134 let categories:any = _.groupBy(leftPanelComponents, 'mainCategory');
135 for (let category in categories)
136 categories[category] = _.groupBy(categories[category], 'subCategory');
138 leftPanelModel.sortedCategories = categories;
140 return leftPanelModel;
144 private initEvents(scope:IPaletteScope) {
146 scope.sectionClick = (section:string) => {
147 if (section === scope.expandedSection) {
148 scope.expandedSection = '';
151 scope.expandedSection = section;
154 scope.onMouseOver = (displayComponent:LeftPaletteComponent, sectionElem: HTMLElement) => {
155 if (this.isGroupOrPolicy(displayComponent)) {
156 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_SHOW_POPUP_PANEL, scope.currentComponent, displayComponent, sectionElem);
158 if (scope.isOnDrag) {
161 scope.isOnDrag = true;
162 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_IN, displayComponent);
163 this.$log.debug('palette::onMouseOver:: fired');
168 scope.onMouseOut = (displayComponent:LeftPaletteComponent) => {
169 if(this.isGroupOrPolicy(displayComponent)) {
170 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HIDE_POPUP_PANEL);
172 scope.isOnDrag = false;
173 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_OUT);
178 private isGroupOrPolicy(component:LeftPaletteComponent): boolean {
180 (component.categoryType === LeftPaletteMetadataTypes.Group ||
181 component.categoryType === LeftPaletteMetadataTypes.Policy)) {
187 private initComponents(scope:IPaletteScope) {
188 scope.searchComponents = (searchText:any):void => {
189 scope.displaySortedCategories = this._searchComponents(searchText, scope.model.sortedCategories);
190 this._initExpandedSection(scope, searchText);
193 scope.isDragable = scope.currentComponent.isComplex();
194 this.updateLeftPanelDisplay(scope);
197 private updateLeftPanelDisplay(scope:IPaletteScope) {
198 let entityType:string = scope.currentComponent.componentType.toLowerCase();
199 let resourceFilterTypes:Array<string> = this.sdcConfig.resourceTypesFilter[entityType];
200 scope.components = this.LeftPaletteLoaderService.getLeftPanelComponentsForDisplay(scope.currentComponent);
201 //remove the container component from the list
202 let componentTempToDisplay = angular.copy(scope.components);
203 componentTempToDisplay = _.remove(componentTempToDisplay, function (leftPalettecomponent) {
204 return leftPalettecomponent.invariantUUID !== scope.currentComponent.invariantUUID;
206 scope.model = this.initLeftPanel(componentTempToDisplay, resourceFilterTypes);
207 scope.displaySortedCategories = angular.copy(scope.model.sortedCategories);
210 private _initExpandedSection(scope:IPaletteScope, searchText:string):void {
211 if (searchText == '') {
212 let isContainingCategory:boolean = false;
213 let categoryToExpand:string;
214 if (scope.currentComponent && scope.currentComponent.categories && scope.currentComponent.categories[0]) {
215 categoryToExpand = this.sdcMenu.categoriesDictionary[scope.currentComponent.categories[0].name];
216 for (let category in scope.model.sortedCategories) {
217 if (categoryToExpand == category) {
218 isContainingCategory = true;
223 isContainingCategory ? scope.expandedSection = categoryToExpand : scope.expandedSection = 'Generic';
226 scope.expandedSection = Object.keys(scope.displaySortedCategories).sort()[0];
230 private initDragEvents(scope:IPaletteScope) {
231 scope.dragStartCallback = (event:IDragDropEvent, ui, displayComponent:LeftPaletteComponent):void => {
232 if (scope.isLoading || !scope.isDragable || scope.isViewOnly || this.isGroupOrPolicy(displayComponent)) {
236 let component = _.find(this.LeftPaletteLoaderService.getLeftPanelComponentsForDisplay(scope.currentComponent), (componentFullData:LeftPaletteComponent) => {
237 return displayComponent.uniqueId === componentFullData.uniqueId;
239 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_DRAG_START, scope.dragElement, component);
241 scope.isOnDrag = true;
243 // this.graphUtils.showMatchingNodes(component, myDiagram, scope.sdcConfig.imagesPath);
244 // document.addEventListener('mousemove', moveOnDocument);
245 event.dataTransfer.component = component;
248 scope.dragStopCallback = () => {
249 scope.isOnDrag = false;
252 scope.onDragCallback = (event:IDragDropEvent):void => {
253 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_DRAG_ACTION, event);
255 scope.setElementTemplate = (e) => {
256 let dragComponent:LeftPaletteComponent = _.find(this.LeftPaletteLoaderService.getLeftPanelComponentsForDisplay(scope.currentComponent),
257 (fullComponent:LeftPaletteComponent) => {
258 return (<any>angular.element(e.currentTarget).scope()).component.uniqueId === fullComponent.uniqueId;
260 let componentInstance:ComponentInstance = this.ComponentInstanceFactory.createComponentInstanceFromComponent(dragComponent);
261 let node:CompositionCiNodeBase = this.NodesFactory.createNode(componentInstance);
263 // myDiagram.dragFromPalette = node;
264 this.nodeHtmlSubstitute.find("img").attr('src', node.img);
265 scope.dragElement = this.nodeHtmlSubstitute.clone().show();
267 return scope.dragElement;
271 private _searchComponents = (searchText:string, categories:any):void => {
272 let displaySortedCategories = angular.copy(categories);
273 if (searchText != '') {
274 angular.forEach(categories, function (category:any, categoryKey) {
276 angular.forEach(category, function (subcategory:Array<LeftPaletteComponent>, subcategoryKey) {
277 let filteredResources = [];
278 angular.forEach(subcategory, function (component:LeftPaletteComponent) {
280 let resourceFilterTerm:string = component.searchFilterTerms;
281 if (resourceFilterTerm.indexOf(searchText.toLowerCase()) >= 0) {
282 filteredResources.push(component);
285 if (filteredResources.length > 0) {
286 displaySortedCategories[categoryKey][subcategoryKey] = filteredResources;
289 delete displaySortedCategories[categoryKey][subcategoryKey];
292 if (!(Object.keys(displaySortedCategories[categoryKey]).length > 0)) {
293 delete displaySortedCategories[categoryKey];
298 return displaySortedCategories;
301 public static factory = ($log,
302 LeftPaletteLoaderService,
305 ComponentInstanceFactory,
307 CompositionGraphGeneralUtils,
308 EventListenerService,
312 return new Palette($log,
313 LeftPaletteLoaderService,
316 ComponentInstanceFactory,
318 CompositionGraphGeneralUtils,
319 EventListenerService,
326 Palette.factory.$inject = [
328 'LeftPaletteLoaderService',
331 'ComponentInstanceFactory',
333 'CompositionGraphGeneralUtils',
334 'EventListenerService',