import {ColumnUtils} from "./columnUtils"; import {Column} from "../entities/column"; import {OriginalColumnGroupChild} from "../entities/originalColumnGroupChild"; import {GroupInstanceIdCreator} from "./groupInstanceIdCreator"; import {ColumnGroupChild} from "../entities/columnGroupChild"; import {ColumnGroup} from "../entities/columnGroup"; import {OriginalColumnGroup} from "../entities/originalColumnGroup"; import {Bean, Context} from "../context/context"; import {Utils as _} from "../utils"; import {Autowired} from "../context/context"; // takes in a list of columns, as specified by the column definitions, and returns column groups @Bean('displayedGroupCreator') export class DisplayedGroupCreator { @Autowired('columnUtils') private columnUtils: ColumnUtils; @Autowired('context') private context: Context; public createDisplayedGroups( // all displayed columns sorted - this is the columns the grid should show sortedVisibleColumns: Column[], // the tree of columns, as provided by the users, used to know what groups columns roll up into balancedColumnTree: OriginalColumnGroupChild[], // create's unique id's for the group groupInstanceIdCreator: GroupInstanceIdCreator, // we try to reuse old groups if we can, to allow gui to do animation oldDisplayedGroups?: ColumnGroupChild[]): ColumnGroupChild[] { let result: ColumnGroupChild[] = []; let previousRealPath: ColumnGroup[]; let previousOriginalPath: OriginalColumnGroup[]; let oldColumnsMapped = this.mapOldGroupsById(oldDisplayedGroups); // go through each column, then do a bottom up comparison to the previous column, and start // to share groups if they converge at any point. sortedVisibleColumns.forEach( (currentColumn: Column)=> { let currentOriginalPath = this.getOriginalPathForColumn(balancedColumnTree, currentColumn); let currentRealPath: ColumnGroup[] = []; let firstColumn = !previousOriginalPath; for (let i = 0; i instanceId -> ColumnGroup private mapOldGroupsById(displayedGroups: ColumnGroupChild[]): {[uniqueId: string]: ColumnGroup} { let result: {[uniqueId: string]: ColumnGroup} = {}; let recursive = (columnsOrGroups: ColumnGroupChild[])=> { columnsOrGroups.forEach( columnOrGroup => { if (columnOrGroup instanceof ColumnGroup) { let columnGroup = columnOrGroup; result[columnOrGroup.getUniqueId()] = columnGroup; recursive(columnGroup.getChildren()); } }); }; if (displayedGroups) { recursive(displayedGroups); } return result; } private setupParentsIntoColumns(columnsOrGroups: ColumnGroupChild[], parent: ColumnGroup): void { columnsOrGroups.forEach( columnsOrGroup => { columnsOrGroup.setParent(parent); if (columnsOrGroup instanceof ColumnGroup) { let columnGroup = columnsOrGroup; this.setupParentsIntoColumns(columnGroup.getChildren(), columnGroup); } }); } // private createFakePath(balancedColumnTree: OriginalColumnGroupChild[], column: Column): OriginalColumnGroup[] { // let fakePath: OriginalColumnGroup[] = []; // let currentChildren = balancedColumnTree; // // this while loop does search on the balanced tree, so our result is the right length // let index = 0; // while (currentChildren && currentChildren[0] && currentChildren[0] instanceof OriginalColumnGroup) { // // putting in a deterministic fake id, in case the API in the future needs to reference the col // let fakeGroup = new OriginalColumnGroup(null, 'FAKE_PATH_' + index, true); // this.context.wireBean(fakeGroup); // // // fakePath.setChildren(children); // // fakePath.push(fakeGroup); // currentChildren = (currentChildren[0]).getChildren(); // index++; // } // // fakePath.forEach( (fakePathGroup: OriginalColumnGroup, i: number) => { // let lastItemInList = i === fakePath.length-1; // let child = lastItemInList ? column : fakePath[i+1]; // fakePathGroup.setChildren([child]); // }); // // return fakePath; // } private getOriginalPathForColumn(balancedColumnTree: OriginalColumnGroupChild[], column: Column): OriginalColumnGroup[] { let result: OriginalColumnGroup[] = []; let found = false; recursePath(balancedColumnTree, 0); // it's possible we didn't find a path. this happens if the column is generated // by the grid (auto-group), in that the definition didn't come from the client. in this case, // we create a fake original path. if (found) { return result; } else { console.log('could not get path'); return null; // return this.createFakePath(balancedColumnTree, column); } function recursePath(balancedColumnTree: OriginalColumnGroupChild[], dept: number): void { for (let i = 0; i node; recursePath(nextNode.getChildren(), dept+1); result[dept] = node; } else { if (node === column) { found = true; } } } } } }