UNPKG

ag-grid-enterprise

Version:

ag-Grid Enterprise Features

273 lines (217 loc) 9.75 kB
import { _, Autowired, Column, ColumnController, Component, Context, Events, EventService, GridOptionsWrapper, OriginalColumnGroup, OriginalColumnGroupChild, PostConstruct, Utils, } from "ag-grid-community/main"; import {ToolPanelColumnGroupComp} from "./toolPanelColumnGroupComp"; import {ToolPanelColumnComp} from "./toolPanelColumnComp"; import {BaseColumnItem} from "./primaryColsPanel"; import {SELECTED_STATE} from "./primaryColsHeaderPanel"; import {ToolPanelColumnCompParams} from "../../columnToolPanel"; export type ColumnItem = BaseColumnItem & Component; export class PrimaryColsListPanel extends Component { @Autowired('gridOptionsWrapper') private gridOptionsWrapper: GridOptionsWrapper; @Autowired('columnController') private columnController: ColumnController; @Autowired('eventService') private globalEventService: EventService; @Autowired('context') private context: Context; private props: { allowDragging: boolean; params: ToolPanelColumnCompParams; }; private columnTree: OriginalColumnGroupChild[]; private columnComps: { [key: string]: ColumnItem }; private filterText: string | null; private expandGroupsByDefault: boolean; public static TEMPLATE = `<div class="ag-primary-cols-list-panel"></div>`; constructor() { super(PrimaryColsListPanel.TEMPLATE); } @PostConstruct public init(): void { this.addDestroyableEventListener(this.globalEventService, Events.EVENT_COLUMN_EVERYTHING_CHANGED, this.onColumnsChanged.bind(this)); this.expandGroupsByDefault = !this.props.params.contractColumnSelection; if (this.columnController.isReady()) { this.onColumnsChanged(); } } public onColumnsChanged(): void { this.destroyColumnComps(); this.columnTree = this.columnController.getPrimaryColumnTree(); let groupsExist = this.columnController.isPrimaryColumnGroupsPresent(); this.recursivelyAddComps(this.columnTree, 0, groupsExist); this.updateVisibilityOfRows(); } private destroyColumnComps(): void { Utils.removeAllChildren(this.getGui()); if (this.columnComps) { Utils.iterateObject(this.columnComps, (key: string, renderedItem: Component) => renderedItem.destroy()); } this.columnComps = {}; } private recursivelyAddGroupComps(columnGroup: OriginalColumnGroup, dept: number, groupsExist: boolean): void { // only render group if user provided the definition let newDept: number; if (columnGroup.getColGroupDef() && columnGroup.getColGroupDef().suppressToolPanel) { return; } if (!columnGroup.isPadding()) { let renderedGroup = new ToolPanelColumnGroupComp(columnGroup, dept, this.onGroupExpanded.bind(this), this.props.allowDragging, this.expandGroupsByDefault); this.context.wireBean(renderedGroup); this.getGui().appendChild(renderedGroup.getGui()); // we want to indent on the gui for the children newDept = dept + 1; this.columnComps[columnGroup.getId()] = renderedGroup; } else { // no children, so no indent newDept = dept; } this.recursivelyAddComps(columnGroup.getChildren(), newDept, groupsExist); } public onGroupExpanded(): void { this.updateVisibilityOfRows(); this.fireExpandedEvent(); } private fireExpandedEvent(): void { let expandedCount = 0; let notExpandedCount = 0; let recursiveFunc = (items: OriginalColumnGroupChild[]) => { items.forEach(item => { // only interested in groups if (item instanceof OriginalColumnGroup) { let comp = <ToolPanelColumnGroupComp> this.columnComps[item.getId()]; if (comp) { if (comp.isExpanded()) { expandedCount++; } else { notExpandedCount++; } } let columnGroup = <OriginalColumnGroup> item; let groupChildren = columnGroup.getChildren(); recursiveFunc(groupChildren); } }); }; recursiveFunc(this.columnTree); let state: SELECTED_STATE; if (expandedCount > 0 && notExpandedCount > 0) { state = SELECTED_STATE.INDETERMINIATE; } else if (notExpandedCount > 0) { state = SELECTED_STATE.UNCHECKED; } else { state = SELECTED_STATE.CHECKED; } this.dispatchEvent({type: 'groupExpanded', state: state}); } private recursivelyAddColumnComps(column: Column, dept: number, groupsExist: boolean): void { if (column.getColDef() && column.getColDef().suppressToolPanel) { return; } let renderedColumn = new ToolPanelColumnComp(column, dept, this.props.allowDragging, groupsExist); this.context.wireBean(renderedColumn); this.getGui().appendChild(renderedColumn.getGui()); this.columnComps[column.getId()] = renderedColumn; } private recursivelyAddComps(tree: OriginalColumnGroupChild[], dept: number, groupsExist: boolean): void { tree.forEach(child => { if (child instanceof OriginalColumnGroup) { this.recursivelyAddGroupComps(<OriginalColumnGroup> child, dept, groupsExist); } else { this.recursivelyAddColumnComps(<Column> child, dept, groupsExist); } }); } public destroy(): void { super.destroy(); this.destroyColumnComps(); } public doSetExpandedAll(value: boolean): void { _.iterateObject(this.columnComps, (key, renderedItem) => { if (renderedItem.isExpandable()) { renderedItem.setExpanded(value); } }); } public setFilterText(filterText: string) { this.filterText = _.exists(filterText) ? filterText.toLowerCase() : null; this.updateVisibilityOfRows(); } private updateVisibilityOfRows(): void { // we have to create the filter results first as that requires dept first search, then setting // the visibility requires breadth first search. this is because a group passes filter if CHILDREN // pass filter, a column passes group open/closed visibility if a PARENT is open. so we need to do // two recursions. we pass the result of the first recursion to the second. let filterResults: { [id: string]: boolean } | null = _.exists(this.filterText) ? this.createFilterResults() : null; this.recursivelySetVisibility(this.columnTree, true, filterResults); } private createFilterResults(): { [id: string]: boolean } { let filterResults: { [id: string]: boolean } = {}; // we recurse dept first - as the item should show if any of the children are showing let recursivelyCheckFilter = (items: OriginalColumnGroupChild[]): boolean => { let atLeastOneThisLevelPassed = false; items.forEach(item => { let atLeastOneChildPassed = false; if (item instanceof OriginalColumnGroup) { let columnGroup = <OriginalColumnGroup> item; let groupChildren = columnGroup.getChildren(); atLeastOneChildPassed = recursivelyCheckFilter(groupChildren); } let filterPasses: boolean; if (atLeastOneChildPassed) { filterPasses = true; } else { let comp = this.columnComps[item.getId()]; if (comp && this.filterText) { filterPasses = comp.getDisplayName().toLowerCase().indexOf(this.filterText) >= 0; } else { filterPasses = true; } } filterResults[item.getId()] = filterPasses; if (filterPasses) { atLeastOneThisLevelPassed = true; } }); return atLeastOneThisLevelPassed; }; recursivelyCheckFilter(this.columnTree); return filterResults; } private recursivelySetVisibility(columnTree: any[], parentGroupsOpen: boolean, filterResults: { [id: string]: boolean } | null): void { columnTree.forEach(child => { let comp: ColumnItem = this.columnComps[child.getId()]; if (comp) { let passesFilter = filterResults ? filterResults[child.getId()] : true; comp.setVisible(parentGroupsOpen && passesFilter); } if (child instanceof OriginalColumnGroup) { let columnGroup = <OriginalColumnGroup> child; let childrenOpen: boolean; if (comp) { let expanded = (<ToolPanelColumnGroupComp>comp).isExpanded(); childrenOpen = parentGroupsOpen ? expanded : false; } else { childrenOpen = parentGroupsOpen; } let children = columnGroup.getChildren(); this.recursivelySetVisibility(children, childrenOpen, filterResults); } }); } public doSetSelectedAll(checked: boolean): void { _.iterateObject(this.columnComps, (key, column) => { column.onSelectAllChanged(checked); }); } }