@visactor/openinula-vtable
Version:
The openinula version of VTable
103 lines (94 loc) • 6.55 kB
JavaScript
import * as VTable from "@visactor/vtable";
import Inula, { useState, useEffect, useRef, useImperativeHandle, useCallback } from "openinula";
import withContainer from "../containers/withContainer";
import RootTableContext from "../context/table";
import { isEqual, isNil, pickWithout } from "@visactor/vutils";
import { toArray } from "../util";
import { INULA_PRIVATE_PROPS } from "../constants";
import { bindEventsToTable, TABLE_EVENTS_KEYS, TABLE_EVENTS } from "../eventsUtils";
const React = Inula, notOptionKeys = [ ...INULA_PRIVATE_PROPS, ...TABLE_EVENTS_KEYS, "skipFunctionDiff", "onError", "onReady", "option", "records", "container" ], getComponentId = (child, index) => `${child && child.type && (child.type.displayName || child.type.name)}-${index}`, parseOptionFromChildren = props => {
const optionFromChildren = {};
return toArray(props.children).map(((child, index) => {
const parseOption = child && child.type && child.type.parseOption;
if (parseOption && child.props) {
const optionResult = parseOption(isNil(child.props.componentId) ? Object.assign(Object.assign({}, child.props), {
componentId: getComponentId(child, index)
}) : child.props);
optionResult.isSingle ? optionFromChildren[optionResult.optionName] = optionResult.option : (optionFromChildren[optionResult.optionName] || (optionFromChildren[optionResult.optionName] = []),
optionFromChildren[optionResult.optionName].push(optionResult.option));
}
})), optionFromChildren;
}, BaseTable = Inula.forwardRef(((props, ref) => {
const [updateId, setUpdateId] = useState(0), tableContext = useRef({});
useImperativeHandle(ref, (() => {
var _a;
return null === (_a = tableContext.current) || void 0 === _a ? void 0 : _a.table;
}));
const hasOption = !!props.option, hasRecords = !!props.records, isUnmount = useRef(!1), prevOption = useRef(pickWithout(props, notOptionKeys)), optionFromChildren = useRef(null), prevRecords = useRef(props.records), eventsBinded = Inula.useRef(null), skipFunctionDiff = !!props.skipFunctionDiff, parseOption = useCallback((props => hasOption && props.option ? hasRecords && props.records ? Object.assign(Object.assign({}, props.option), {
records: props.records
}) : props.option : Object.assign(Object.assign({
records: props.records
}, prevOption.current), optionFromChildren.current)), [ hasOption, hasRecords ]), createTable = useCallback((props => {
let vtable;
vtable = "pivot-table" === props.type ? new VTable.PivotTable(props.container, parseOption(props)) : "pivot-chart" === props.type ? new VTable.PivotChart(props.container, parseOption(props)) : new VTable.ListTable(props.container, parseOption(props)),
tableContext.current = Object.assign(Object.assign({}, tableContext.current), {
table: vtable
}), isUnmount.current = !1;
}), [ parseOption ]), handleTableRender = useCallback((() => {
if (!isUnmount.current) {
if (!tableContext.current || !tableContext.current.table) return;
bindEventsToTable(tableContext.current.table, props, eventsBinded.current, TABLE_EVENTS),
setUpdateId(updateId + 1), props.onReady && props.onReady(tableContext.current.table, 0 === updateId);
}
}), [ updateId, setUpdateId, props ]), renderTable = useCallback((() => {
tableContext.current.table && (tableContext.current.table.render(), handleTableRender());
}), [ handleTableRender ]);
return useEffect((() => {
var _a, _b;
const newOptionFromChildren = hasOption ? null : parseOptionFromChildren(props);
if (!(null === (_a = tableContext.current) || void 0 === _a ? void 0 : _a.table)) return hasOption || (optionFromChildren.current = newOptionFromChildren),
createTable(props), renderTable(), void (eventsBinded.current = props);
if (hasOption) return void (isEqual(eventsBinded.current.option, props.option, {
skipFunction: skipFunctionDiff
}) ? hasRecords && !isEqual(eventsBinded.current.records, props.records, {
skipFunction: skipFunctionDiff
}) && (eventsBinded.current = props, tableContext.current.table.setRecords(props.records, {
restoreHierarchyState: props.option.restoreHierarchyState
}), handleTableRender()) : (eventsBinded.current = props, tableContext.current.table.updateOption(parseOption(props)),
handleTableRender()));
const newOption = pickWithout(props, notOptionKeys);
isEqual(newOption, prevOption.current, {
skipFunction: skipFunctionDiff
}) && isEqual(newOptionFromChildren, optionFromChildren.current, {
skipFunction: skipFunctionDiff
}) ? hasRecords && !isEqual(props.records, prevRecords.current, {
skipFunction: skipFunctionDiff
}) && (prevRecords.current = props.records, tableContext.current.table.setRecords(props.records, {
restoreHierarchyState: null === (_b = props.option) || void 0 === _b ? void 0 : _b.restoreHierarchyState
}), handleTableRender()) : (prevOption.current = newOption, optionFromChildren.current = newOptionFromChildren,
tableContext.current.table.updateOption(parseOption(props)), handleTableRender());
}), [ createTable, hasOption, hasRecords, parseOption, handleTableRender, renderTable, skipFunctionDiff, props ]),
useEffect((() => () => {
tableContext && tableContext.current && tableContext.current.table && (tableContext.current.table.release(),
tableContext.current = null), eventsBinded.current = null, isUnmount.current = !0;
}), []), React.createElement(RootTableContext.Provider, {
value: tableContext.current
}, toArray(props.children).map(((child, index) => {
if ("string" == typeof child) return;
const childId = getComponentId(child, index);
return React.createElement(Inula.Fragment, {
key: childId
}, Inula.cloneElement(child, {
updateId: updateId,
componentId: childId
}));
})));
}));
export const createTable = (componentName, type, callback) => {
const Com = withContainer(BaseTable, componentName, (props => (props.type = type,
callback ? callback(props) : type ? Object.assign(Object.assign({}, props), {
type: type
}) : props)));
return Com.displayName = componentName, Com;
};
//# sourceMappingURL=base-table.js.map