All files / src/components/zd-tree-grid tree-data-selector.ts

100% Statements 61/61
100% Branches 26/26
100% Functions 16/16
100% Lines 53/53

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122  93x     93x           46x 46x       13x       2x 2x 2x             2x 2x 2x 5x 5x 5x         11x 11x   4x   4x 4x 8x 8x 8x 2x   4x 4x 4x   4x 2x   2x   4x       10x 10x   4x   4x 4x 4x 4x       15x 15x         15x 7x   8x     15x 23x     15x   13x   7x   6x         1x       1x       1x       1x       1x      
import { IDictionary } from '@zeedhi/core';
import { DataSelector, IDataSelector } from '../zd-grid';
import { ITreeDataSelector, ITreeGrid } from './interfaces';
 
export class TreeDataSelector implements ITreeDataSelector {
	private treeGrid: ITreeGrid;
 
	private dataSelector: IDataSelector;
 
	constructor(treeGrid: ITreeGrid) {
		this.treeGrid = treeGrid;
		this.dataSelector = new DataSelector(treeGrid);
	}
 
	private removeDuplicates<T extends { [key: string]: unknown }>(arr: T[], key: string): T[] {
		return [...new Map(arr.map((item: T) => [item[key], item])).values()];
	}
 
	selectChildren(row: IDictionary<any>): void {
		const childrenRows = this.treeGrid.getChildren(row);
		const rows = this.treeGrid.flat ? childrenRows : [row, ...childrenRows];
		this.treeGrid.selectedRows = this.removeDuplicates(
			this.treeGrid.selectedRows.concat(rows),
			this.treeGrid.datasource.uniqueKey,
		);
	}
 
	unselectChildren(row: IDictionary<any>): void {
		const childrenRows = this.treeGrid.getChildren(row);
		const rows = this.treeGrid.flat ? childrenRows : [row, ...childrenRows];
		rows.forEach((item: IDictionary<any>) => {
			const key = this.treeGrid.getRowKey(item);
			const index = this.treeGrid.findDataIndex(this.treeGrid.selectedRows, key);
			if (index > -1) this.treeGrid.selectedRows.splice(index, 1);
		});
	}
 
	private selectParents(row: IDictionary<any>) {
		const { parentField, selectAllPages } = this.treeGrid;
		if (!row[parentField]) return;
 
		let arrSelection = selectAllPages ? this.treeGrid.selectionState.except : this.treeGrid.selectedRows;
 
		const parentRow = this.treeGrid.getParentRow(row);
		const every = this.treeGrid.getChildren(parentRow).every((item: IDictionary<any>) => {
			const key = this.treeGrid.getRowKey(item);
			const index = this.treeGrid.findDataIndex(arrSelection, key);
			if (index > -1) return true;
			return false;
		});
		const rows = [];
		if (every || (selectAllPages && this.treeGrid.selectionState.allSelected)) rows.push(parentRow);
		arrSelection = this.removeDuplicates(arrSelection.concat(rows), this.treeGrid.datasource.uniqueKey);
 
		if (selectAllPages) {
			this.treeGrid.selectionState.except = arrSelection;
		} else {
			this.treeGrid.selectedRows = arrSelection;
		}
		this.selectParents(parentRow);
	}
 
	private unselectParents(row: IDictionary<any>) {
		const { parentField, selectAllPages, selectionState, selectedRows } = this.treeGrid;
		if (!row[parentField]) return;
 
		const arrSelection = selectAllPages ? selectionState.except : selectedRows;
 
		const index = this.treeGrid.findDataIndex(arrSelection, row[parentField]);
		if (index > -1) arrSelection.splice(index, 1);
		const parentRow = this.treeGrid.getParentRow(row);
		this.unselectParents(parentRow);
	}
 
	selectRow(row: IDictionary<any>, select: boolean) {
		const childrenRows = !this.treeGrid.flat ? this.treeGrid.getChildren(row) : [];
		const rows = [row, ...childrenRows];
 
		// stores whether this row should be added/removed from arrSelection
		let shouldBeSelected: boolean;
 
		if (this.treeGrid.selectAllPages) {
			shouldBeSelected = select !== this.treeGrid.selectionState.allSelected;
		} else {
			shouldBeSelected = select;
		}
 
		rows.forEach((rowToSelect) => {
			this.dataSelector.selectRow(rowToSelect, select);
		});
 
		if (this.treeGrid.flat) return;
 
		if (shouldBeSelected) {
			// check if all the children of the parent are selected.
			this.selectParents(row);
		} else {
			this.unselectParents(row);
		}
	}
 
	selectAll(isSelected: boolean): void {
		this.dataSelector.selectAll(isSelected);
	}
 
	toggleRow(row: IDictionary): void {
		this.dataSelector.toggleRow(row);
	}
 
	callDisableSelection(row: IDictionary): boolean {
		return this.dataSelector.callDisableSelection(row);
	}
 
	selectClick(row: IDictionary<any>, isSelected: boolean, event: Event, element?: HTMLElement): void {
		this.dataSelector.selectClick(row, isSelected, event, element);
	}
 
	selectAllClick(isSelected: boolean, event: Event, element?: HTMLElement): void {
		this.dataSelector.selectAllClick(isSelected, event, element);
	}
}