drip-table
Version:
A tiny and powerful enterprise-class solution for building tables.
467 lines (367 loc) • 20 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
require("./index.less");
var _get = _interopRequireDefault(require("lodash/get"));
var _react = _interopRequireDefault(require("react"));
var _uuid = require("uuid");
var _ajv = require("../utils/ajv");
var _hooks = require("../utils/hooks");
var _sandbox = require("../utils/sandbox");
var _cellComponents = _interopRequireDefault(require("../components/cell-components"));
var _hooks2 = require("../components/cell-components/hooks");
var _utils = require("../components/cell-components/utils");
var _hooks3 = require("../hooks");
var _ = require("./..");
var _layouts = _interopRequireDefault(require("../layouts"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var DripTableWrapper = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
var _props$createEvaluato;
// 旧版参数兼容
var tablePropsMigrated = _react.default.useMemo(function () {
var _rtp$schema, _rtp$schema$columns;
var rtp = props; // 兼容旧版本数据
if ((_rtp$schema = rtp.schema) !== null && _rtp$schema !== void 0 && (_rtp$schema$columns = _rtp$schema.columns) !== null && _rtp$schema$columns !== void 0 && _rtp$schema$columns.some(function (c) {
return c['ui:type'] || c['ui:props'];
})) {
var _rtp$schema2, _rtp$schema2$columns;
rtp = _objectSpread(_objectSpread({}, rtp), {}, {
schema: Object.assign({}, rtp.schema, {
columns: (_rtp$schema2 = rtp.schema) === null || _rtp$schema2 === void 0 ? void 0 : (_rtp$schema2$columns = _rtp$schema2.columns) === null || _rtp$schema2$columns === void 0 ? void 0 : _rtp$schema2$columns.map(function (c) {
var column = c;
if ('ui:type' in column || 'ui:props' in column) {
var key = column.key;
if ('ui:type' in column) {
console.warn("[DripTable] Column ".concat(key, " \"ui:type\" is deprecated, please use \"component\" instead."));
}
if ('ui:props' in column) {
console.warn("[DripTable] Column ".concat(key, " \"ui:props\" is deprecated, please use \"options\" instead."));
}
return _objectSpread(_objectSpread({}, Object.fromEntries(Object.entries(column).filter(function (_ref) {
var _ref2 = _slicedToArray(_ref, 1),
k = _ref2[0];
return k !== 'ui:type' && k !== 'ui:props';
}))), {}, {
options: column['ui:props'] || column.options || void 0,
component: column['ui:type'] || column.component
});
}
return column;
})
})
});
}
return rtp;
}, [props]); // 列 ajv 校验
var tableProps = _react.default.useMemo(function () {
var rtp = tablePropsMigrated;
var ajv = rtp.ajv;
if (ajv !== false) {
var _rtp$schema3, _rtp$schema3$columns;
var validateColumnSchema = function validateColumnSchema(column) {
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'column';
var errorMessage = null;
var schema;
var BuiltInComponent = rtp.defaultComponentLib ? null : _cellComponents.default[column === null || column === void 0 ? void 0 : column.component];
if (BuiltInComponent) {
schema = BuiltInComponent.schema;
if (!schema) {
errorMessage = "Built-in component must contains a valid options ajv schema! (component: ".concat(column.component, ")");
}
} else {
var _column$component;
var _ref3 = (column === null || column === void 0 ? void 0 : (_column$component = column.component) === null || _column$component === void 0 ? void 0 : _column$component.split('::')) || [],
_ref4 = _slicedToArray(_ref3, 2),
libName = _ref4[0],
componentName = _ref4[1];
if (!componentName && rtp.defaultComponentLib) {
componentName = libName;
libName = rtp.defaultComponentLib;
}
if (libName && componentName) {
var _rtp$components, _rtp$components$libNa, _rtp$components$libNa2;
schema = (_rtp$components = rtp.components) === null || _rtp$components === void 0 ? void 0 : (_rtp$components$libNa = _rtp$components[libName]) === null || _rtp$components$libNa === void 0 ? void 0 : (_rtp$components$libNa2 = _rtp$components$libNa[componentName]) === null || _rtp$components$libNa2 === void 0 ? void 0 : _rtp$components$libNa2.schema;
}
}
if (schema && !errorMessage) {
var columnErrorMessage = (0, _ajv.validateDripTableColumnSchema)(column, schema, ajv);
if (columnErrorMessage) {
errorMessage = columnErrorMessage.replace(/^column/, path);
} else if (column.component === 'group') {
var items = column.options.items;
var _iterator = _createForOfIteratorHelper(items.entries()),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var _step$value = _slicedToArray(_step.value, 2),
index = _step$value[0],
item = _step$value[1];
var itemSchema = item && 'schema' in item ? item.schema : item;
var message = validateColumnSchema(itemSchema, "".concat(path !== null && path !== void 0 ? path : '', "/options/items/").concat(index));
if (message) {
errorMessage = message;
break;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
}
return errorMessage;
};
rtp = _objectSpread(_objectSpread({}, rtp), {}, {
schema: Object.assign({}, rtp.schema, {
columns: (_rtp$schema3 = rtp.schema) === null || _rtp$schema3 === void 0 ? void 0 : (_rtp$schema3$columns = _rtp$schema3.columns) === null || _rtp$schema3$columns === void 0 ? void 0 : _rtp$schema3$columns.map(function (column) {
var errorMessage = validateColumnSchema(column);
if (errorMessage) {
return {
key: column.key,
title: column.title,
dataIndex: column.dataIndex,
component: 'text',
options: {
mode: 'static',
static: errorMessage,
className: 'jfe-drip-table-wrapper-column-ajv-error'
}
};
}
return column;
})
})
});
}
return rtp;
}, [tablePropsMigrated]); // 创建上下文
var _useState = (0, _hooks.useState)((0, _hooks3.createTableState)()),
_useState2 = _slicedToArray(_useState, 2),
state = _useState2[0],
setState = _useState2[1];
var _useState3 = (0, _hooks.useState)((0, _hooks2.createTableComponentState)()),
_useState4 = _slicedToArray(_useState3, 2),
componentState = _useState4[0],
setComponentState = _useState4[1];
var _React$useState = _react.default.useState((0, _uuid.v4)()),
_React$useState2 = _slicedToArray(_React$useState, 1),
tableUUID = _React$useState2[0];
var tableInfo = _react.default.useMemo(function () {
return {
uuid: tableUUID,
schema: props.schema,
dataSource: props.dataSource,
parent: props.__PARENT_INFO__
};
}, [props.schema, props.dataSource, props.__PARENT_INFO__]);
var createEvaluator = (_props$createEvaluato = props.createEvaluator) !== null && _props$createEvaluato !== void 0 ? _props$createEvaluato : _sandbox.createEvaluator;
var execute = function execute(script) {
var _createEvaluator;
var ctx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return (_createEvaluator = createEvaluator(script, Object.keys(ctx))) === null || _createEvaluator === void 0 ? void 0 : _createEvaluator.apply(void 0, _toConsumableArray(Object.values(ctx)));
};
var safeExecute = function safeExecute(script) {
var ctx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : void 0;
try {
return execute(script, ctx);
} catch (error) {
console.warn(error);
}
return defaultValue;
};
var finalizeString = function finalizeString(mode, text, record, recordIndex, ext) {
var value = '';
if (!mode || mode === 'plain') {
value = (0, _utils.stringify)(text);
} else if (mode === 'key') {
value = (0, _utils.stringify)((0, _get.default)(record, text, ''));
} else if (mode === 'pattern') {
value = (0, _utils.stringify)(text).replace(/\{\{((?:[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+?)\}\}/gi, function (s, s1) {
try {
return execute("return ".concat(s1), {
props: {
record: record,
recordIndex: recordIndex,
ext: ext
},
rec: record
});
} catch (error) {
return error instanceof Error ? "{{Render Error: ".concat(error.message, "}}") : '{{Unknown Render Error}}';
}
});
} else if (mode === 'script') {
try {
value = (0, _utils.stringify)(execute(text, {
props: {
record: record,
recordIndex: recordIndex,
ext: ext
},
rec: record
}));
} catch (error) {
value = error instanceof Error ? "Render Error: ".concat(error.message) : 'Unknown Render Error';
}
}
return value;
};
var context = _react.default.useMemo(function () {
return {
props: tableProps,
info: tableInfo,
state: state,
setState: setState,
createEvaluator: createEvaluator,
evaluate: execute,
safeEvaluate: safeExecute,
finalizeString: finalizeString
};
}, [props, tableInfo, state, setState, createEvaluator, execute, safeExecute, finalizeString]);
var componentContext = _react.default.useMemo(function () {
return {
props: tableProps,
info: tableInfo,
state: componentState,
setState: setComponentState
};
}, [props, tableInfo, componentState, setComponentState]); // 组件提供给外部的公共接口
_react.default.useImperativeHandle(ref, function () {
return {
select: function select(selectedRowKeys) {
setState({
selectedRowKeys: selectedRowKeys
});
},
selectedRowKeys: context.state.selectedRowKeys,
setDisplayColumnKeys: function setDisplayColumnKeys(displayColumnKeys) {
setState({
displayColumnKeys: displayColumnKeys
});
},
displayColumnKeys: context.state.displayColumnKeys,
sorter: context.state.sorter,
setSorter: function setSorter(sorter) {
if (sorter) {
var columnSchema = tableInfo.schema.columns.find(function (c) {
return c.key === sorter.key;
});
if (!(columnSchema !== null && columnSchema !== void 0 && columnSchema.sorter)) {
return;
}
setState({
sorter: {
key: sorter.key,
direction: sorter.direction,
comparer: function comparer(a, b) {
var multiply = context.safeEvaluate(columnSchema.sorter || '', {
props: {
column: columnSchema,
leftRecord: a,
rightRecord: b,
leftValue: (0, _.indexValue)(a, columnSchema.dataIndex),
rightValue: (0, _.indexValue)(b, columnSchema.dataIndex),
ext: tableProps.ext
}
}, 1);
if (typeof multiply !== 'number') {
multiply = 1;
}
return (sorter.direction === 'ascend' ? 1 : -1) * multiply;
}
},
sorterChanged: true
});
} else {
setState({
sorter: {
key: null,
direction: null,
comparer: null
},
sorterChanged: true
});
}
}
};
}, [setState, _.indexValue, context.safeEvaluate, context.state.selectedRowKeys, context.state.displayColumnKeys, context.state.sorter, tableInfo.schema.columns]); // 校验参数
var errorMessage = [props.ajv !== false && (0, _ajv.validateDripTableRequiredProps)(props, props.ajv) || ''].concat(_toConsumableArray((0, _ajv.getDripTableValidatePropsKeys)(props, props.ajv === false ? void 0 : props.ajv).map(function (k) {
return _react.default.useMemo(function () {
return props.ajv !== false && (0, _ajv.validateDripTableProp)(k, props[k], props.ajv) || '';
}, [k, props[k], props.ajv]);
}))).filter(Boolean).join('\n');
if (errorMessage) {
return /*#__PURE__*/_react.default.createElement("pre", {
className: "jfe-drip-table-wrapper-column-ajv-error"
}, "Props validate failed: ".concat(errorMessage.includes('\n') ? '\n' : '').concat(errorMessage));
}
_react.default.useEffect(function () {
var _tableProps$component;
var sorter = tableInfo.schema.initialSorter;
if (sorter) {
var columnSchema = tableInfo.schema.columns.find(function (c) {
return c.key === sorter.key;
});
if (!(columnSchema !== null && columnSchema !== void 0 && columnSchema.sorter)) {
return;
}
setState({
sorter: {
key: sorter.key,
direction: sorter.direction,
comparer: function comparer(a, b) {
var multiply = context.safeEvaluate(columnSchema.sorter || '', {
props: {
column: columnSchema,
leftRecord: a,
rightRecord: b,
leftValue: (0, _.indexValue)(a, columnSchema.dataIndex),
rightValue: (0, _.indexValue)(b, columnSchema.dataIndex),
ext: tableProps.ext
}
}, 1);
if (typeof multiply !== 'number') {
multiply = 1;
}
return (sorter.direction === 'ascend' ? 1 : -1) * multiply;
}
},
sorterChanged: true
});
}
(_tableProps$component = tableProps.componentDidMount) === null || _tableProps$component === void 0 ? void 0 : _tableProps$component.call(tableProps, tableInfo);
return function () {
var _tableProps$component2;
(_tableProps$component2 = tableProps.componentWillUnmount) === null || _tableProps$component2 === void 0 ? void 0 : _tableProps$component2.call(tableProps, tableInfo);
};
}, []);
_react.default.useEffect(function () {
var _tableProps$component3;
(_tableProps$component3 = tableProps.componentDidUpdate) === null || _tableProps$component3 === void 0 ? void 0 : _tableProps$component3.call(tableProps, tableInfo);
});
return /*#__PURE__*/_react.default.createElement(_hooks3.DripTableContext.Provider, {
value: context
}, /*#__PURE__*/_react.default.createElement(_hooks2.DripTableComponentContext.Provider, {
value: componentContext
}, /*#__PURE__*/_react.default.createElement(_layouts.default, null)));
});
var _default = DripTableWrapper;
exports.default = _default;