All files / src/components/tek-grid tek-grid-column.ts

100% Statements 62/62
100% Branches 13/13
100% Functions 13/13
100% Lines 60/60

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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194112x 112x             112x   172x     172x           172x     172x     172x     172x           172x         172x                                                           2x 2x 2x 4x 1x 1x     3x 3x 1x 1x 1x     2x     2x 1x   1x 2x 2x       2x             8x 1x     7x 7x 4x 3x       3x         3x   3x     7x 7x     7x           7x   7x       292x       175x 175x 175x 15x         436x       176x 176x 176x 19x         237x       173x 173x 173x 3x                                 37x 3x        
import { Datasource, DatasourceFactory, IDictionary } from '@zeedhi/core';
import { GridColumnEditable } from '..';
import { IFilterPropsComponent, ITekGridColumn, ITekGridColumnAggregation } from './interfaces';
import { TekGrid } from './tek-grid';
 
/**
 * Base class for TekGrid column
 */
export class TekGridColumn extends GridColumnEditable implements ITekGridColumn {
	/* filter component props */
	public filterProps: IFilterPropsComponent | IFilterPropsComponent[] = [];
 
	/* column can be use to filter */
	public filterable = true;
 
	/* Index of the column inside filter modal */
	public filterIndex?: number;
 
	/* should not consider lookup column on search */
	public skipLookupSearch = false;
 
	/* column is grouped */
	private groupedValue = false;
 
	/* column group is opened */
	private groupOpenedValue?: boolean = false;
 
	/* Value to show when grouped value is empty */
	public groupLabelForEmptyValue = '';
 
	/* column has aggregation */
	private aggregationValue?: ITekGridColumnAggregation;
 
	/* column is visible */
	private isVisibleValue = true;
 
	/**
	 * Defines if the column should store the componentProps datasource.data in memory
	 */
	public storeData = true;
 
	private grid: TekGrid;
 
	/* istanbul ignore next */
	/**
	 * Creates a new TekGrid Column.
	 * @param props TekGrid column properties
	 */
	constructor(props: ITekGridColumn, grid: TekGrid) {
		super(props);
		this.grid = grid;
		this.isVisible = this.getInitValue('isVisible', props.isVisible, this.isVisible);
		this.filterProps = this.getInitValue('filterProps', props.filterProps, this.filterProps);
		this.filterable = this.getInitValue('filterable', props.filterable, this.filterable);
		this.filterIndex = this.getInitValue('filterIndex', props.filterIndex, this.filterIndex);
		this.skipLookupSearch = this.getInitValue('skipLookupSearch', props.skipLookupSearch, this.skipLookupSearch);
		this.grouped = this.getInitValue('grouped', props.grouped, this.grouped);
		this.groupOpened = this.getInitValue('groupOpened', props.groupOpened, this.groupOpened);
		this.aggregation = this.getInitValue('aggregation', props.aggregation, this.aggregation);
		this.groupLabelForEmptyValue = this.getInitValue(
			'groupLabelForEmptyValue',
			props.groupLabelForEmptyValue,
			this.groupLabelForEmptyValue,
		);
		this.storeData = this.getInitValue('storeData', props.storeData, this.storeData);
		this.createAccessors();
	}
 
	public async getBatchLookupData(lookupColumn: string, values: any[]): Promise<IDictionary[]> {
		const batch: IDictionary[] = [];
		const dataToLookup: any[] = [];
		values.forEach((value) => {
			if (this.lookupData[value]) {
				batch.push(this.lookupData[value]);
				return;
			}
 
			const dataIndex = this.lookupDatasource!.data.findIndex((row) => row[lookupColumn] === value);
			if (dataIndex !== -1) {
				this.lookupData[value] = this.lookupDatasource!.data[dataIndex];
				batch.push(this.lookupData[value]);
				return;
			}
 
			dataToLookup.push(value);
		});
 
		if (dataToLookup.length > 0) {
			await this.lookupFn(lookupColumn, dataToLookup);
 
			dataToLookup.forEach((value) => {
				const row = this.lookupData[value];
				if (row) batch.push(row);
			});
		}
 
		return batch;
	}
 
	/**
	 * Memory search, without changing lookupDatasource
	 */
	public async memorySearch(search: string): Promise<any> {
		if (!this.lookupDatasource) {
			throw new Error("Can't search in a column that doesn't have a datasource");
		}
 
		let { data } = this.lookupDatasource;
		if (this.storeData) {
			if (!data.length) {
				data = await this.lookupDatasource.get();
			}
		} else {
			// datasource without the lookup filters
			const defaultDs = DatasourceFactory.factory({
				...this.componentProps.datasource,
				lazyLoad: true,
				loadAll: true,
			});
			defaultDs.initialize();
 
			data = await defaultDs.get();
		}
 
		const { dataText } = this.componentProps;
		const searchIn = Array.isArray(dataText) ? dataText : [dataText];
 
		// get datasource as memory
		const datasource: Datasource = DatasourceFactory.factory({
			searchIn,
			data,
			type: 'memory',
			loadAll: true,
		});
		datasource.initialize();
 
		return datasource.setSearch(search);
	}
 
	get grouped() {
		return this.groupedValue;
	}
 
	set grouped(value: boolean) {
		const changed = value !== this.groupedValue;
		this.groupedValue = value;
		if (changed) {
			this.changeGrouping();
		}
	}
 
	get aggregation() {
		return this.aggregationValue;
	}
 
	set aggregation(value: ITekGridColumnAggregation) {
		const changed = value !== this.aggregationValue;
		this.aggregationValue = value;
		if (changed) {
			this.changeGrouping();
		}
	}
 
	get groupOpened() {
		return this.groupOpenedValue;
	}
 
	set groupOpened(value: boolean | undefined) {
		const changed = value !== this.groupOpenedValue;
		this.groupOpenedValue = value;
		if (changed) {
			this.changeGrouping();
		}
	}
 
	/* istanbul ignore next */
	// @ts-ignore
	get isVisible() {
		return this.isVisibleValue && !this.grouped;
	}
 
	/* istanbul ignore next */
	set isVisible(value: boolean) {
		this.isVisibleValue = value;
	}
 
	private changeGrouping() {
		// wait for grid.constructor to be fully executed
		setTimeout(() => {
			this.grid.updateGrouping();
		});
	}
}