UNPKG

ag-grid-enterprise

Version:

ag-Grid Enterprise Features

163 lines (130 loc) 5.59 kB
import {Utils as _, PopupService, MenuItemDef, Component, Autowired, Context} from "ag-grid-community"; import {MenuItemComponent, MenuItemSelectedEvent} from "./menuItemComponent"; export class MenuList extends Component { @Autowired('context') private context: Context; @Autowired('popupService') private popupService: PopupService; // private instance = Math.random(); private static TEMPLATE = '<div class="ag-menu-list"></div>'; private static SEPARATOR_TEMPLATE = `<div class="ag-menu-separator"> <span class="ag-menu-separator-cell"></span> <span class="ag-menu-separator-cell"></span> <span class="ag-menu-separator-cell"></span> <span class="ag-menu-separator-cell"></span> </div>`; private activeMenuItemParams: MenuItemDef; private activeMenuItem: MenuItemComponent; private timerCount = 0; private removeChildFuncs: Function[] = []; private subMenuParentDef: MenuItemDef; constructor() { super(MenuList.TEMPLATE); // console.log('MenuList->constructor() ' + this.instance); } public clearActiveItem(): void { this.removeActiveItem(); this.removeChildPopup(); } public addMenuItems(menuItems: (MenuItemDef|string)[]): void { if (_.missing(menuItems)) { return; } menuItems.forEach( (menuItemOrString: MenuItemDef|string)=> { if (menuItemOrString === 'separator') { this.addSeparator(); } else if (typeof menuItemOrString === 'string') { console.warn(`ag-Grid: unrecognised menu item ` + menuItemOrString); } else { let menuItem = <MenuItemDef> menuItemOrString; this.addItem(menuItem); } }); } public addItem(menuItemDef: MenuItemDef): void { let cMenuItem = new MenuItemComponent(menuItemDef); this.context.wireBean(cMenuItem); this.getGui().appendChild(cMenuItem.getGui()); this.addDestroyFunc( ()=> cMenuItem.destroy() ); cMenuItem.addEventListener(MenuItemComponent.EVENT_ITEM_SELECTED, (event: MenuItemSelectedEvent) => { if (menuItemDef.subMenu) { this.showChildMenu(menuItemDef, cMenuItem, event.mouseEvent); } else { this.dispatchEvent(event); } }); cMenuItem.addGuiEventListener('mouseenter', this.mouseEnterItem.bind(this, menuItemDef, cMenuItem)); cMenuItem.addGuiEventListener('mouseleave', ()=> this.timerCount++ ); } private mouseEnterItem(menuItemParams: MenuItemDef, menuItem: MenuItemComponent): void { if (menuItemParams.disabled) { return; } if (this.activeMenuItemParams!==menuItemParams) { this.removeChildPopup(); } this.removeActiveItem(); this.activeMenuItemParams = menuItemParams; this.activeMenuItem = menuItem; _.addCssClass(this.activeMenuItem.getGui(), 'ag-menu-option-active'); if (menuItemParams.subMenu) { this.addHoverForChildPopup(menuItemParams, menuItem); } } private removeActiveItem(): void { if (this.activeMenuItem) { _.removeCssClass(this.activeMenuItem.getGui(), 'ag-menu-option-active'); this.activeMenuItem = null; this.activeMenuItemParams = null; } } private addHoverForChildPopup(menuItemDef: MenuItemDef, menuItemComp: MenuItemComponent): void { let timerCountCopy = this.timerCount; setTimeout( ()=> { let shouldShow = timerCountCopy===this.timerCount; let showingThisMenu = this.subMenuParentDef === menuItemDef; if (shouldShow && !showingThisMenu) { this.showChildMenu(menuItemDef, menuItemComp, null); } }, 500); } public addSeparator(): void { this.getGui().appendChild(_.loadTemplate(MenuList.SEPARATOR_TEMPLATE)); } private showChildMenu(menuItemDef: MenuItemDef, menuItemComp: MenuItemComponent, mouseEvent: MouseEvent): void { this.removeChildPopup(); let childMenu = new MenuList(); this.context.wireBean(childMenu); childMenu.addMenuItems(menuItemDef.subMenu); let ePopup = _.loadTemplate('<div class="ag-menu"></div>'); ePopup.appendChild(childMenu.getGui()); let hidePopupFunc = this.popupService.addAsModalPopup( ePopup, true, null, mouseEvent ); this.popupService.positionPopupForMenu({ eventSource: menuItemComp.getGui(), ePopup: ePopup }); this.subMenuParentDef = menuItemDef; let selectedListener = (event: MenuItemSelectedEvent)=> { this.dispatchEvent(event); }; childMenu.addEventListener(MenuItemComponent.EVENT_ITEM_SELECTED, selectedListener); this.removeChildFuncs.push( ()=> { childMenu.clearActiveItem(); childMenu.destroy(); this.subMenuParentDef = null; childMenu.removeEventListener(MenuItemComponent.EVENT_ITEM_SELECTED, selectedListener); hidePopupFunc(); }); } private removeChildPopup(): void { this.removeChildFuncs.forEach( func => func() ); this.removeChildFuncs = []; } public destroy(): void { // console.log('MenuList->destroy() ' + this.instance); this.removeChildPopup(); super.destroy(); } }