All files / src/components/zd-master-detail master-detail.ts

100% Statements 47/47
100% Branches 13/13
100% Functions 6/6
100% Lines 46/46

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 8393x   93x 93x   93x         93x 11x 11x 11x 11x 11x 11x     11x 11x 11x 11x 11x 11x 11x       6x 3x 3x   3x 4x 2x     4x   4x 6x 6x 4x 2x 2x 1x   1x     4x 2x     2x 1x   1x               6x 6x 4x   2x 1x   1x         7x 7x      
import { Datasource, IDictionary, InstanceNotFoundError, Metadata } from '@zeedhi/core';
import { Component } from '../zd-component/component';
import { ComponentRender } from '../zd-component/component-render';
import { DetailNotFoundError } from './detail-not-found';
import { IMasterDetail } from './interfaces';
import { MasterNotFoundError } from './master-not-found';
 
/**
 * Base class for Master Detail component.
 */
export class MasterDetail extends ComponentRender implements IMasterDetail {
	public config: IDictionary<any> = {};
	public lazyRelate = false;
	public height: string | number = 'auto';
	public minHeight: string | number = 'auto';
	public maxHeight: string | number = 'none';
	public fillHeight = false;
 
	constructor(props: IMasterDetail) {
		super(props);
		this.config = this.getInitValue('config', props.config, this.config);
		this.lazyRelate = this.getInitValue('lazyRelate', props.lazyRelate, this.lazyRelate);
		this.height = this.getInitValue('height', props.height, this.height);
		this.minHeight = this.getInitValue('minHeight', props.minHeight, this.minHeight);
		this.maxHeight = this.getInitValue('maxHeight', props.maxHeight, this.maxHeight);
		this.fillHeight = this.getInitValue('fillHeight', props.fillHeight, this.fillHeight);
	}
 
	private createRelationship(master: any, details: IDictionary<any>[] = []) {
		if (master.datasource && details.length) {
			const masterDatasource = master.datasource as Datasource;
			const { onChangeCurrentRow } = masterDatasource.events;
 
			masterDatasource.events.onChangeCurrentRow = ({ component }: any) => {
				if (onChangeCurrentRow) {
					onChangeCurrentRow({ component });
				}
 
				const key = masterDatasource.currentRow[masterDatasource.uniqueKey];
 
				details.forEach((detail: any) => {
					try {
						const detailComponent: any = Metadata.getInstance(detail.name);
						if (!detailComponent.datasource) {
							detailComponent.value = masterDatasource.currentRow;
						} else if (key) {
							detailComponent.datasource.addFilter(detail.column, key);
						} else {
							detailComponent.datasource.data = [];
						}
 
						if (detail.details) {
							this.createRelationship(detailComponent, detail.details);
						}
					} catch (e) {
						if (e instanceof InstanceNotFoundError) {
							throw new DetailNotFoundError(detail.name);
						}
						throw e;
					}
				});
			};
		}
	}
 
	public createRelationships() {
		try {
			const masterComponent: any = Metadata.getInstance<Component>(this.config.name);
			this.createRelationship(masterComponent, this.config.details);
		} catch (e) {
			if (e instanceof InstanceNotFoundError) {
				throw new MasterNotFoundError(this.config.name);
			}
			throw e;
		}
	}
 
	public onMounted(element: any) {
		super.onMounted(element);
		if (!this.lazyRelate) this.createRelationships();
	}
}