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";
30 import { IDirectiveLinkFn, IScope } from "angular";
33 interface IPaletteScope extends IScope{
34 components:Array<LeftPaletteComponent>;
35 currentComponent:Component;
37 displaySortedCategories:any;
38 expandedSection:string;
41 event:JQueryEventObject,
42 components:LeftPaletteComponent,
46 addInstanceClick: ()=>void; // added code
47 onPopupMouseOver: ()=>void // added code
48 onPopupMouseOut: ()=>void // added code
50 sectionClick:(section:string)=>void;
51 searchComponents:(searchText:string)=>void;
52 onMouseOver:(displayComponent:LeftPaletteComponent, elem: HTMLElement)=>void;
53 onMouseOut:(displayComponent:LeftPaletteComponent)=>void;
55 dragStartCallback:(event:JQueryEventObject, ui, displayComponent:LeftPaletteComponent)=>void;
56 dragStopCallback:()=>void;
57 onDragCallback:(event:JQueryEventObject) => void;
59 setElementTemplate:(e:JQueryEventObject)=>void;
67 export class Palette implements ng.IDirective {
68 constructor(private $log:ng.ILogService,
69 private LeftPaletteLoaderService: LeftPaletteLoaderService,
71 private ComponentFactory,
72 private ComponentInstanceFactory:ComponentInstanceFactory,
73 private NodesFactory:NodesFactory,
74 private CompositionGraphGeneralUtils:CompositionGraphGeneralUtils,
75 private EventListenerService:EventListenerService,
76 private sdcMenu:IAppMenu,
77 private ModalsHandler:ModalsHandler
81 private fetchingComponentFromServer:boolean = false;
82 private nodeHtmlSubstitute:JQuery;
85 currentComponent: '=',
90 template = require('./palette.html');
92 link:IDirectiveLinkFn = (scope:IPaletteScope, el:JQuery) => {
93 this.LeftPaletteLoaderService.loadLeftPanel(scope.currentComponent);
94 this.nodeHtmlSubstitute = $('<div class="node-substitute"><span></span><img /></div>');
95 el.append(this.nodeHtmlSubstitute);
96 this.registerEventListenerForLeftPalette(scope);
98 this.initComponents(scope);
99 this.initEvents(scope);
100 this.initDragEvents(scope);
101 this._initExpandedSection(scope, '');
102 el.on('$destroy', ()=> {
103 //remove listener of download event
104 this.unRegisterEventListenerForLeftPalette(scope);
109 private registerEventListenerForLeftPalette = (scope:IPaletteScope):void => {
110 this.EventListenerService.registerObserverCallback(EVENTS.LEFT_PALETTE_UPDATE_EVENT, () => {
111 this.updateLeftPanelDisplay(scope);
115 private unRegisterEventListenerForLeftPalette = (scope:IPaletteScope):void => {
116 this.EventListenerService.unRegisterObserver(EVENTS.LEFT_PALETTE_UPDATE_EVENT);
119 private leftPanelResourceFilter(resourcesNotAbstract:Array<LeftPaletteComponent>, resourceFilterTypes:Array<string>):Array<LeftPaletteComponent> {
120 let filterResources = _.filter(resourcesNotAbstract, (component) => {
121 return resourceFilterTypes.indexOf(component.getComponentSubType()) > -1;
123 return filterResources;
126 private initLeftPanel(leftPanelComponents:Array<LeftPaletteComponent>, resourceFilterTypes:Array<string>):LeftPanelModel {
127 let leftPanelModel = new LeftPanelModel();
129 if (resourceFilterTypes && resourceFilterTypes.length) {
130 leftPanelComponents = this.leftPanelResourceFilter(leftPanelComponents, resourceFilterTypes);
132 leftPanelModel.numberOfElements = leftPanelComponents && leftPanelComponents.length || 0;
134 if (leftPanelComponents && leftPanelComponents.length) {
136 let categories:any = _.groupBy(leftPanelComponents, 'mainCategory');
137 for (let category in categories)
138 categories[category] = _.groupBy(categories[category], 'subCategory');
140 leftPanelModel.sortedCategories = categories;
142 return leftPanelModel;
146 private initEvents(scope:IPaletteScope) {
148 scope.sectionClick = (section:string) => {
149 if (section === scope.expandedSection) {
150 scope.expandedSection = '';
153 scope.expandedSection = section;
156 scope.onMouseOver = (displayComponent:LeftPaletteComponent, sectionElem: HTMLElement) => {
157 if (this.isGroupOrPolicy(displayComponent)) {
158 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_SHOW_POPUP_PANEL, scope.currentComponent, displayComponent, sectionElem);
160 if (scope.isOnDrag) {
163 scope.isOnDrag = true;
164 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_IN, displayComponent);
165 this.$log.debug('palette::onMouseOver:: fired');
170 scope.onMouseOut = (displayComponent:LeftPaletteComponent) => {
171 if(this.isGroupOrPolicy(displayComponent)) {
172 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HIDE_POPUP_PANEL);
174 scope.isOnDrag = false;
175 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_OUT);
180 private isGroupOrPolicy(component:LeftPaletteComponent): boolean {
182 (component.categoryType === LeftPaletteMetadataTypes.Group ||
183 component.categoryType === LeftPaletteMetadataTypes.Policy)) {
189 private initComponents(scope:IPaletteScope) {
190 scope.searchComponents = (searchText:any):void => {
191 scope.displaySortedCategories = this._searchComponents(searchText, scope.model.sortedCategories);
192 this._initExpandedSection(scope, searchText);
195 scope.isDragable = scope.currentComponent.isComplex();
196 this.updateLeftPanelDisplay(scope);
199 private updateLeftPanelDisplay(scope:IPaletteScope) {
200 let entityType:string = scope.currentComponent.componentType.toLowerCase();
201 let resourceFilterTypes:Array<string> = this.sdcConfig.resourceTypesFilter[entityType];
202 scope.components = this.LeftPaletteLoaderService.getLeftPanelComponentsForDisplay(scope.currentComponent);
203 //remove the container component from the list
204 let componentTempToDisplay = angular.copy(scope.components);
205 componentTempToDisplay = _.remove(componentTempToDisplay, function (leftPalettecomponent) {
206 return leftPalettecomponent.invariantUUID !== scope.currentComponent.invariantUUID;
208 scope.model = this.initLeftPanel(componentTempToDisplay, resourceFilterTypes);
209 scope.displaySortedCategories = angular.copy(scope.model.sortedCategories);
212 private _initExpandedSection(scope:IPaletteScope, searchText:string):void {
213 if (searchText == '') {
214 let isContainingCategory:boolean = false;
215 let categoryToExpand:string;
216 if (scope.currentComponent && scope.currentComponent.categories && scope.currentComponent.categories[0]) {
217 categoryToExpand = this.sdcMenu.categoriesDictionary[scope.currentComponent.categories[0].name];
218 for (let category in scope.model.sortedCategories) {
219 if (categoryToExpand == category) {
220 isContainingCategory = true;
225 isContainingCategory ? scope.expandedSection = categoryToExpand : scope.expandedSection = 'Generic';
228 scope.expandedSection = Object.keys(scope.displaySortedCategories).sort()[0];
232 private initDragEvents(scope:IPaletteScope) {
233 scope.dragStartCallback = (event:IDragDropEvent, ui, displayComponent:LeftPaletteComponent):void => {
234 if (scope.isLoading || !scope.isDragable || scope.isViewOnly || this.isGroupOrPolicy(displayComponent)) {
238 let component = _.find(this.LeftPaletteLoaderService.getLeftPanelComponentsForDisplay(scope.currentComponent), (componentFullData:LeftPaletteComponent) => {
239 return displayComponent.uniqueId === componentFullData.uniqueId;
241 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_DRAG_START, scope.dragElement, component);
243 scope.isOnDrag = true;
245 // this.graphUtils.showMatchingNodes(component, myDiagram, scope.sdcConfig.imagesPath);
246 // document.addEventListener('mousemove', moveOnDocument);
247 event.dataTransfer.component = component;
250 scope.dragStopCallback = () => {
251 scope.isOnDrag = false;
254 scope.onDragCallback = (event:IDragDropEvent):void => {
255 this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_DRAG_ACTION, event);
257 scope.setElementTemplate = (e) => {
258 let dragComponent:LeftPaletteComponent = _.find(this.LeftPaletteLoaderService.getLeftPanelComponentsForDisplay(scope.currentComponent),
259 (fullComponent:LeftPaletteComponent) => {
260 return (<any>angular.element(e.currentTarget).scope()).component.uniqueId === fullComponent.uniqueId;
262 let componentInstance:ComponentInstance = this.ComponentInstanceFactory.createComponentInstanceFromComponent(dragComponent);
263 let node:CompositionCiNodeBase = this.NodesFactory.createNode(componentInstance);
265 // myDiagram.dragFromPalette = node;
266 this.nodeHtmlSubstitute.find("img").attr('src', node.img);
267 scope.dragElement = this.nodeHtmlSubstitute.clone().show();
269 return scope.dragElement;
273 private _searchComponents = (searchText:string, categories:any):void => {
274 let displaySortedCategories = angular.copy(categories);
275 if (searchText != '') {
276 angular.forEach(categories, function (category:any, categoryKey) {
278 angular.forEach(category, function (subcategory:Array<LeftPaletteComponent>, subcategoryKey) {
279 let filteredResources = [];
280 angular.forEach(subcategory, function (component:LeftPaletteComponent) {
282 let resourceFilterTerm:string = component.searchFilterTerms.toLowerCase();
283 if (resourceFilterTerm.indexOf(searchText.toLowerCase()) >= 0) {
284 filteredResources.push(component);
287 if (filteredResources.length > 0) {
288 displaySortedCategories[categoryKey][subcategoryKey] = filteredResources;
291 delete displaySortedCategories[categoryKey][subcategoryKey];
294 if (!(Object.keys(displaySortedCategories[categoryKey]).length > 0)) {
295 delete displaySortedCategories[categoryKey];
300 return displaySortedCategories;
303 public static factory = ($log,
304 LeftPaletteLoaderService,
307 ComponentInstanceFactory,
309 CompositionGraphGeneralUtils,
310 EventListenerService,
314 return new Palette($log,
315 LeftPaletteLoaderService,
318 ComponentInstanceFactory,
320 CompositionGraphGeneralUtils,
321 EventListenerService,
328 Palette.factory.$inject = [
330 'LeftPaletteLoaderService',
333 'ComponentInstanceFactory',
335 'CompositionGraphGeneralUtils',
336 'EventListenerService',