UNPKG

armisa-models

Version:
482 lines (441 loc) 17.4 kB
import { AxiosError, AxiosInstance, AxiosResponse } from "axios"; import { MainStateManager } from "../../MainStateManager"; import { ElementsOfFormFactory } from "../../Page/ElementsOfFormFactory"; import { SelfCheckedIDs } from "../../SelfModels/SelfCheckedIDs"; import { ISelfCheckTree } from "../../SelfModels/SelfCheckTree"; import { IMainStateFactory } from "../../Types"; import { ISpecifierCheckTreeView, IStructrulCodeTreeViewJson, StructrulCodeTreeViewCode } from "./StructrulCodeTreeViewCode"; import { TREECODE } from "amisa-paths"; import { StructureCoding } from "../../StructureCoding"; export interface IStructuralCodeFactoryForTreeView { urls: TREECODE; apiAxios: AxiosInstance; onlyLastLevel: boolean required: boolean; coding: StructureCoding; code: string; focusToElement: () => void; onChangeHandlerCode: (code: string) => void; getCodeData: () => void; } export class StructrulCodeTreeView { public forceUpdate = () => { } public mainStateManager: MainStateManager; public elementsOfForm; public get any() { return this as any; } public refForm?: React.RefObject<HTMLFormElement>; constructor( public mainStateFactory: IMainStateFactory, public selfStructuralCode: IStructuralCodeFactoryForTreeView, public onlyLastLevel: boolean, public closeModal: () => void, ) { this.mainStateManager = this.mainStateFactory.mainStateManager; this.elementsOfForm = new ElementsOfFormFactory(this.mainStateFactory); this.code = selfStructuralCode.code; } public code: string = ''; private _nodes: StructrulCodeTreeViewCode[] = []; private _flatten?: StructrulCodeTreeViewCode[]; public checkStates?: ISpecifierCheckTreeView[]; public waitForLoad: boolean = true; public currentNodeWaitForLoading: boolean = false; public waitForEndLoading = (): Promise<void> => { return new Promise((resolve) => { if (this.waitForLoad || this.currentNodeWaitForLoading) { this.endingWaitForEndLoading = () => { resolve(); }; } else { resolve(); } }); }; public endingWaitForEndLoading = () => { } public selectedRow: StructrulCodeTreeViewCode | null = null; get nodes(): StructrulCodeTreeViewCode[] { return this._nodes; } get flatten(): StructrulCodeTreeViewCode[] { const flatten = this._flatten; if (flatten) { return flatten; } else { return this.getFlatten(this.nodes); } } private getFlatten = (nodes: StructrulCodeTreeViewCode[] | null): StructrulCodeTreeViewCode[] => { if (nodes === null) { return []; } return nodes.reduce((result: StructrulCodeTreeViewCode[], item: StructrulCodeTreeViewCode) => { return [...result, item, ...this.getFlatten(item.children)]; }, []); } loadData = () => { this.waitForLoad = true; this.selfStructuralCode.apiAxios.get(this.selfStructuralCode.urls.tree) .then(response => { const result = response.data as IStructrulCodeTreeViewJson[]; this.checkStates = SelfCheckedIDs.deserialize(result).checkStates; this.loadTreeView(); }) .catch(e => { console.error(e); this.waitForLoad = false; this.endingWaitForEndLoading(); //this.events.trigger('form.wasErrored', e); }); } loadTreeView = (): void => { const _findPropriateNodeByThisCodeForSelect = (code: string): void => { if (!code && this.flatten && this.flatten.length) { this.selectedRow = this.flatten[0]; return; } let lastFind: StructrulCodeTreeViewCode | null = null; const _set = (item: StructrulCodeTreeViewCode) => { this.selectedRow = item; if (item.childCount && item.children && item.children.length) { item.isExpanded = true; } }; this.flatten.forEach((item: StructrulCodeTreeViewCode) => { if (code === item.code) { _set(item); return; } else if ( code.length > item.code.length && code.substring(0, item.code.length) === item.code ) { _set(item); lastFind = item; } }); if (lastFind) { this._expandParent(lastFind); } }; this.waitForLoad = true; this.selfStructuralCode.apiAxios.get(this.selfStructuralCode.urls.search, { params: { code: this.code } }) .then((response: AxiosResponse): void => { const nodes: StructrulCodeTreeViewCode[] = response.data.map((item: StructrulCodeTreeViewCode) => this.deserializeRow(item) ); this._nodes = nodes; this.checkStates = []; this._updateFlatten(); _findPropriateNodeByThisCodeForSelect(this.code); this.waitForLoad = false; this.endingWaitForEndLoading(); this.forceUpdate() }) .catch((error: AxiosError): void => { this.waitForLoad = false; this.endingWaitForEndLoading(); this.forceUpdate(); console.error(error); }); } selectPreviousNode(): void { const currentNode = this.currentNode(); if (currentNode) { const siblingNodes = this.flatten.filter( (i) => i.parentId === currentNode.parentId ); if (siblingNodes && siblingNodes.length > 1) { const currentNodeIndex = siblingNodes.indexOf(currentNode); if (currentNodeIndex > 0) { this.selectThisNode(siblingNodes[currentNodeIndex - 1]); } else if (currentNodeIndex === 0) { this.selectThisNode(siblingNodes[siblingNodes.length - 1]); } } } else { this.selectThisNode(this.flatten[0]); } } selectNextNode(): void { const currentNode = this.currentNode(); if (currentNode) { const siblingNodes = this.flatten.filter( (i) => i.parentId === currentNode.parentId ); if (siblingNodes && siblingNodes.length > 1) { const currentNodeIndex = siblingNodes.indexOf(currentNode); if ( currentNodeIndex > -1 && currentNodeIndex < siblingNodes.length - 1 ) { this.selectThisNode(siblingNodes[currentNodeIndex + 1]); } else if (currentNodeIndex === siblingNodes.length - 1) { this.selectThisNode(siblingNodes[0]); } } } else { this.selectThisNode(this.flatten[0]); } } nodeCheckChange = (node: IStructrulCodeTreeViewJson) => { if (!this.checkStates) { this.checkStates = []; } if (this.flatten.find((i) => i.id === node.id && node.check === 1)) { this.removeCheckToNode(node); } else { this.addCheckToNode(node); } this.forceUpdate(); }; private removeCheckToNode(node: IStructrulCodeTreeViewJson) { if (node.parentId) { this.removeCheckToParent(node); } this.removeCheckToChild(node); this.checkStates = this.checkStates?.filter((i) => i.id !== node.id); node.check = 0; } private removeCheckToParent(node: IStructrulCodeTreeViewJson) { if (node.parentId) { const child = this.flatten.filter( (i) => i.parentId === node.parentId && i.check > 0 ); if (child.length === 1) { const parent = this.flatten.find((i) => i.id === node.parentId)!; this.removeCheckToParent(parent); this.checkStates = this.checkStates?.filter((i) => i.id !== parent.id); parent.check = 0; } } } private removeCheckToChild(node: IStructrulCodeTreeViewJson) { const children = this.flatten.filter((i) => i.parentId === node.id); if (children && children.length) { for (const child of children) { this.removeCheckToChild(child); } } this.checkStates = this.checkStates?.filter((i) => i.id !== node.id); node.check = 0; } private addCheckToNode(node: IStructrulCodeTreeViewJson) { if (this.onlyLastLevel && node.childCount > 0) { return; } if (node.parentId) { this.addCheckType4ToParent(this.flatten.find((i) => i.id === node.parentId)!); } this.addCheckType4ToChild(node); this.checkStates?.push({ id: node.id, isFromChild: false, isFromParent: false, code: node as any, }); node.check = 1; } private addCheckType4ToParent(node: IStructrulCodeTreeViewJson) { if (node.parentId) { this.addCheckType4ToParent( this.flatten.find((i) => i.id === node.parentId)! ); } this.checkStates?.push({ id: node.id, isFromChild: true, isFromParent: false, code: node as any, }); node.check = 4; } private addCheckType4ToChild(node: IStructrulCodeTreeViewJson) { const children = this.flatten.filter((i) => i.parentId === node.id); if (children && children.length) { for (const child of children) { this.addCheckType4ToChild(child); } } this.checkStates?.push({ id: node.id, isFromChild: true, isFromParent: false, code: node as any, }); node.check = 4; } private _setUnCheckNodeCheckType(mainNode: IStructrulCodeTreeViewJson) { mainNode.check = 0; if (mainNode.children && mainNode.children.length) { mainNode.children.map((i) => this._setUnCheckNodeCheckType(i)); } } private _setParentCheckNodeCheckType(mainNode: IStructrulCodeTreeViewJson, check: ISelfCheckTree) { mainNode.check = check; if (mainNode.children && mainNode.children.length) { mainNode.children.map((i) => this._setParentCheckNodeCheckType(i, 4)); } } private _setDoubleCheckNodeCheckType(mainNode: IStructrulCodeTreeViewJson) { mainNode.check = 2; if (mainNode.children && mainNode.children.length) { mainNode.children.map((i) => this._setDoubleCheckNodeCheckType(i)); } } private _setSingleCheckNodeCheckType(mainNode: IStructrulCodeTreeViewJson) { mainNode.check = 3; if (mainNode.children && mainNode.children.length) { mainNode.children.map((i) => this._setSingleCheckNodeCheckType(i)); } } selectFirstNode(): void { if (this.nodes.length > 0) { this.selectThisNode(this.nodes[0]); } } selectLastNode(): void { if (this.nodes.length > 0) { this.selectThisNode(this.nodes[this.nodes.length - 1]); } } expandCurrentNode = (): void => { const currentNode = this.currentNode(); if (currentNode) { this.expandThisNode(currentNode); } }; expandThisNode = (node: StructrulCodeTreeViewCode): void => { if (node.childCount && node.children && node.children.length) { node.isExpanded = true; this.selectThisNodeFirstChild(node); } else if (node.childCount && !(node.children && node.children.length)) { node.isExpanded = true; node.isLoading = true; this.forceUpdate(); this.getTreeViewChildren(node); } }; getTreeViewChildren = (node: StructrulCodeTreeViewCode): void => { node.isLoading = true; node.isExpanded = true; this.currentNodeWaitForLoading = true; this.forceUpdate(); this.selfStructuralCode.apiAxios .get(`${this.selfStructuralCode.urls.treeChild}/${node.id}`) .then((response: AxiosResponse): void => { node.children = response.data.map((item: IStructrulCodeTreeViewJson) => this.deserializeRow(item) ); node.isLoading = false; this.currentNodeWaitForLoading = false; this._updateFlatten(); this.selectThisNodeFirstChild(node); this.forceUpdate(); }) .catch((error: AxiosError): void => { this.currentNodeWaitForLoading = false; node.isLoading = false; console.error(error); this.forceUpdate(); }); }; get canCloseItsModal(): boolean { const currentNode = this.currentNode(); if (currentNode) { if (currentNode.parentId) { const parentNode = this.flatten.find( (i) => i.id === currentNode.parentId ); if (parentNode && parentNode.isExpanded) { return false; } } } return true; } collapseCurrentNode = () => { const currentNode = this.currentNode(); if (currentNode) { this.collapseThisNode(currentNode); } }; collapseThisNode = (node: IStructrulCodeTreeViewJson) => { if (node.isExpanded) { node.isExpanded = false; this.forceUpdate(); } else { if (node.parentId) { const parentNode = this.flatten.find((i) => i.id === node.parentId); if (parentNode) { this.selectThisNode(parentNode); } } } }; toggleThisNode = (node: StructrulCodeTreeViewCode): void => { if (node.isExpanded) { this.collapseThisNode(node); } else { this.expandThisNode(node); } }; private _updateFlatten = (): void => { this._flatten = this.getFlatten(this.nodes); }; currentNode = (): StructrulCodeTreeViewCode | undefined => { return this.flatten.find((i) => i === this.selectedRow); }; selectThisNodeFirstChild(node: StructrulCodeTreeViewCode) { if (node.children && node.children.length) { const firstChild = (node.children)[0]; this.selectThisNode(firstChild); } } selectThisNode = (node: StructrulCodeTreeViewCode): void => { this.selectedRow = node; this.forceUpdate(); }; private _expandParent = (node: IStructrulCodeTreeViewJson): void => { if (!node.parentId) { return; } const parentNode = this.flatten.find((i) => i.id === node.parentId); if (parentNode) { parentNode.isExpanded = true; this._expandParent(parentNode); } }; deserializeRow = (json: IStructrulCodeTreeViewJson): StructrulCodeTreeViewCode => { if (this.checkStates) { if (this.checkStates.find((i) => i.id === json.id && !i.isFromChild)) { json.check = 1; } else if (this.checkStates.find((i) => i.id === json.id && i.isFromChild)) { json.check = 4; } else if (this.checkStates.find((i) => i.id === json.parentId && !i.isFromChild) ) { this.checkStates?.push({ id: json.id, isFromChild: false, isFromParent: true, code: json as any }); json.check = 4; } } const result = StructrulCodeTreeViewCode.deserialize(json, json.children || []); return result; }; acceptCurrentRow = () => { if (this.selectedRow) { this.closeModal(); this.selfStructuralCode.focusToElement(); this.selfStructuralCode.onChangeHandlerCode(this.selectedRow.code); this.selfStructuralCode.getCodeData(); } } cancelForm = () => { this.closeModal(); this.selfStructuralCode.focusToElement(); } }