All files / src/components/zd-grid table-action-builder.ts

100% Statements 53/53
100% Branches 15/15
100% Functions 11/11
100% Lines 48/48

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 11593x 93x             93x       253x                 13x   13x 1x     12x       17x 9x 9x 9x 5x                 8x       107x       107x 16x       16x 16x 16x   16x   6x       16x 16x 16x 16x 16x   16x   16x   16x 16x   16x 16x 16x 16x   16x   16x 16x 6x   13x     16x 7x     16x   16x 1x         1x 1x       16x      
import { Accessor, Event as EventFactory, IDictionary, Metadata } from '@zeedhi/core';
import merge from 'lodash.merge';
import { Component } from '../zd-component/component';
import { IComponent } from '../zd-component/interfaces';
import { Iterable } from '../zd-iterable/iterable';
import { GridColumn } from './grid-column';
import { ITableActionBuilder } from './interfaces';
 
export class TableActionBuilder implements ITableActionBuilder {
	protected iterable: Iterable;
 
	constructor(iterable: Iterable) {
		this.iterable = iterable;
	}
 
	public getActionComponent(
		actionComponent: IComponent,
		column: GridColumn,
		row: IDictionary,
		parentPath = '',
	): IComponent {
		const { props, instance } = this.getActionProps(actionComponent, column, row, parentPath);
 
		if (instance) {
			return instance;
		}
 
		return props;
	}
 
	private setGridRowsInEvents(comp: IComponent, column: GridColumn, row: IDictionary) {
		if (comp.events?.click) {
			const compEvents = EventFactory.factory(comp.events);
			if (typeof compEvents.click === 'function') {
				return ({ component, event, element }: any) =>
					(compEvents as any).click({
						component,
						event,
						element,
						row,
						column,
					});
			}
		}
		return undefined;
	}
 
	private filterObject<T>(obj: Record<string, T>, callback: (key: string, value: T) => boolean): Record<string, T> {
		return Object.fromEntries(Object.entries(obj).filter(([key, value]) => callback(key, value as T)));
	}
 
	private deleteAccessorProps(newComponent: IComponent) {
		const filteredProps = this.filterObject(newComponent, (_key, value) => !Accessor.isAccessorDefinition(value));
		return filteredProps;
	}
 
	protected updateActionInstance(instanceName: string, newComponent: IComponent) {
		const updatedComponent: any = this.deleteAccessorProps(newComponent);
		updatedComponent.datasource = undefined;
		updatedComponent.events = undefined;
 
		const instance = Metadata.updateInstance<Component>(instanceName, updatedComponent);
 
		return instance;
	}
 
	protected getActionProps(actionComponent: IComponent, column: GridColumn, row: IDictionary, parentPath: string) {
		const rowKey = this.iterable.getRowKey(row);
		const compName = actionComponent.name;
		const instanceName = `${compName}_${rowKey}`;
		const path = parentPath ? `${parentPath}.${compName}` : compName;
		const compActivator: IComponent = actionComponent.activator ?? undefined;
 
		const props: IComponent = merge({}, actionComponent, this.iterable.getAppliedConditions({ row, column, path }));
 
		const newClickEvt: undefined | ((params: any) => boolean) = this.setGridRowsInEvents(props, column, row);
 
		const children = props.children || [];
		const newChildren = children.map((child) => this.getActionProps(child, column, row, path).props);
 
		props.children = newChildren;
		props.name = instanceName;
		props.allowDuplicate = true;
		props.autoRegister = false;
 
		let instance: Component | null = null;
 
		try {
			instance = this.updateActionInstance(instanceName, props);
			if (newClickEvt) instance.events.click = newClickEvt;
		} catch (_e) {
			instance = null;
		}
 
		if (!props.events) {
			props.events = {};
		}
 
		if (newClickEvt) props.events.click = newClickEvt;
 
		if (compActivator) {
			const newActivatorClickEvt: undefined | ((params: any) => boolean) = this.setGridRowsInEvents(
				compActivator,
				column,
				row,
			);
			if (newActivatorClickEvt) {
				props.activator.events.click = newActivatorClickEvt;
			}
		}
 
		return { props, instance };
	}
}