UNPKG

choerodon-ui

Version:

An enterprise-class UI design language and React-based implementation

801 lines (724 loc) 26.9 kB
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _objectSpread from "@babel/runtime/helpers/objectSpread2"; import _extends from "@babel/runtime/helpers/extends"; var _excluded = ["lock", "columnGroups", "snapshot", "dragRowHeight"]; import React, { cloneElement, useCallback, useContext, useEffect, useLayoutEffect } from 'react'; import { observer } from 'mobx-react-lite'; import { action } from 'mobx'; import { Draggable, Droppable } from 'react-beautiful-dnd'; import classNames from 'classnames'; import isFunction from 'lodash/isFunction'; import { pxToRem } from '../../../es/_util/UnitConvertor'; import ReactResizeObserver from '../../../es/_util/resizeObserver'; import ObserverCheckBox from '../check-box/CheckBox'; import TableContext from './TableContext'; import TableRow from './TableRow'; import { ColumnLock, DragColumnAlign, GroupType } from './enum'; import ExpandedRow from './ExpandedRow'; import { DataSetStatus, RecordCachedType } from '../data-set/enum'; import { instance } from './Table'; import { getHeader, isStickySupport } from './utils'; import TableRowGroup from './TableRowGroup'; import { $l } from '../locale-context'; import Button from '../button/Button'; import { Size } from '../core/enum'; import { ButtonColor, FuncType } from '../button/enum'; import { defaultAggregationRenderer } from './Column'; import VirtualVerticalContainer from './VirtualVerticalContainer'; import useComputed from '../use-computed'; import VirtualRowMetaData from './VirtualRowMetaData'; import { toTransformValue } from '../_util/transform'; import { useRenderClone } from './hooks'; import TableVirtualRow from './TableVirtualRow'; import { cachedTypeIntlMap } from './SelectionTips'; function generateRowGroup(props) { var tableStore = props.tableStore, columnGroups = props.columnGroups, lock = props.lock, children = props.children, statistics = props.statistics, key = props.key, rowGroupLevel = props.rowGroupLevel; var level = rowGroupLevel ? rowGroupLevel.count : 0; var node = /*#__PURE__*/React.createElement(TableRowGroup, { key: key, columnGroups: columnGroups, lock: lock, level: level }, children); if (statistics) { var rowMetaData = statistics.rowMetaData, lastRowMetaData = statistics.lastRowMetaData; var currentRowMetaData = new VirtualRowMetaData(tableStore, 'group', lastRowMetaData); if (lastRowMetaData) { lastRowMetaData.next = currentRowMetaData; } currentRowMetaData.groupLevel = level; currentRowMetaData.node = node; rowMetaData.push(currentRowMetaData); statistics.lastRowMetaData = currentRowMetaData; } return node; } function generateRow(props) { var tableStore = props.tableStore, record = props.record, parentExpanded = props.parentExpanded, lock = props.lock, columnGroups = props.columnGroups, groupPath = props.groupPath, index = props.index, isFixedRowHeight = props.isFixedRowHeight, statistics = props.statistics, expandIconColumnIndex = props.expandIconColumnIndex, children = props.children, headerGroup = props.headerGroup, draggableId = props.draggableId, dragRowHeight = props.dragRowHeight, virtualCell = props.virtualCell; var key = record.key; var hidden = !parentExpanded; var tableRowProps = { columnGroups: columnGroups, record: record, index: index.count, key: key, hidden: hidden, lock: lock, expandIconColumnIndex: expandIconColumnIndex, groupPath: groupPath, children: children, isFixedRowHeight: isFixedRowHeight, virtualCell: virtualCell }; if (statistics) { var rowMetaData = statistics.rowMetaData, lastRowMetaData = statistics.lastRowMetaData; tableRowProps.virtualIndex = statistics.count; statistics.count++; var currentRowMetaData = new VirtualRowMetaData(tableStore, 'row', lastRowMetaData, record); if (lastRowMetaData) { lastRowMetaData.next = currentRowMetaData; } rowMetaData.push(currentRowMetaData); statistics.lastRowMetaData = currentRowMetaData; tableRowProps.metaData = currentRowMetaData; } index.count++; if (headerGroup) { tableRowProps.headerGroupIndex = headerGroup.count; headerGroup.count++; } if (dragRowHeight && statistics && !statistics.dragTargetFound) { if (draggableId && String(key) === String(draggableId)) { statistics.dragTargetFound = true; } else { tableRowProps.style = { transform: toTransformValue({ translateY: pxToRem(-dragRowHeight, true) }) }; } } if (isFixedRowHeight && virtualCell && !hidden) { return /*#__PURE__*/React.createElement(TableVirtualRow, _extends({}, tableRowProps)); } return /*#__PURE__*/React.createElement(TableRow, _extends({}, tableRowProps)); } function renderExpandedRows(rowProps) { var index = { count: 0 }; var rows = []; var parent = rowProps.record, treeFilter = rowProps.tableStore.treeFilter; (parent.children || []).forEach(function (record) { if (typeof treeFilter === 'function' && !treeFilter(record)) { return; } generateRowAndChildRows(rows, _objectSpread(_objectSpread({}, rowProps), {}, { record: record, index: index })); }); return rows; } function generateDraggableRow(props) { var tableStore = props.tableStore, record = props.record, lock = props.lock, index = props.index, rowDragRender = props.rowDragRender, statistics = props.statistics, isTree = props.isTree, virtual = props.virtual, rowDraggable = props.rowDraggable; var prefixCls = tableStore.prefixCls; var children = isTree && !virtual && /*#__PURE__*/React.createElement(ExpandedRow, _extends({}, props, { renderExpandedRows: renderExpandedRows })); var draggableIndex = rowDraggable && isTree && statistics ? statistics.count : index.count; var row = generateRow(_objectSpread(_objectSpread({}, props), {}, { children: children })); if (rowDraggable) { var dragColumnAlign = tableStore.dragColumnAlign; if (!dragColumnAlign || dragColumnAlign === DragColumnAlign.right && lock !== ColumnLock.left || dragColumnAlign === DragColumnAlign.left && lock !== ColumnLock.right) { var key = record.key; var dragDisabled; if (rowDragRender && rowDragRender.draggableProps && rowDragRender.draggableProps.isDragDisabled) { var isDragDisabled = rowDragRender.draggableProps.isDragDisabled; dragDisabled = isFunction(isDragDisabled) ? isDragDisabled(record) : isDragDisabled; } return /*#__PURE__*/React.createElement(Draggable, { draggableId: String(key), index: draggableIndex, isDragDisabled: dragDisabled, key: key }, function (provided, snapshot) { return /*#__PURE__*/cloneElement(row, _objectSpread(_objectSpread({ provided: provided, snapshot: snapshot }, rowDragRender && rowDragRender.draggableProps), {}, { className: classNames(_defineProperty({}, "".concat(prefixCls, "-row-drag-disabled"), dragDisabled)) })); }); } } return row; } function generateRowAndChildRows(rows, props) { var tableStore = props.tableStore, record = props.record, isTree = props.isTree, virtual = props.virtual; var treeFilter = tableStore.treeFilter, showRemovedRow = tableStore.showRemovedRow; if (showRemovedRow || !record.isRemoved) { rows.push(generateDraggableRow(props)); } if (isTree && virtual && tableStore.isRowExpanded(record)) { (record.children || []).forEach(function (record) { if (typeof treeFilter === 'function' && !treeFilter(record)) { return; } generateRowAndChildRows(rows, _objectSpread(_objectSpread({}, props), {}, { index: { count: 0 }, record: record })); }); } return rows; } function generateCachedRows(props, handleClearCache, statistics) { var tableStore = props.tableStore; var showCachedTips = tableStore.showCachedTips, _tableStore$computedR = tableStore.computedRecordCachedType, computedRecordCachedType = _tableStore$computedR === void 0 ? showCachedTips ? RecordCachedType.selected : undefined : _tableStore$computedR; var records = showCachedTips ? tableStore.cachedDataInType : tableStore.cachedData; if (records.length) { var index = { count: 0 }; var rows = [generateRowGroup(_objectSpread(_objectSpread({}, props), {}, { key: '$$group-cached-rows', statistics: statistics, children: /*#__PURE__*/React.createElement(React.Fragment, null, showCachedTips && /*#__PURE__*/React.createElement(ObserverCheckBox, { className: "".concat(tableStore.prefixCls, "-cached-group-check"), checked: tableStore.allCachedChecked, indeterminate: tableStore.cachedIndeterminate, onChange: function onChange() { if (tableStore.allCachedChecked) { tableStore.unCheckAllCached(); } else { tableStore.checkAllCached(); } } }), /*#__PURE__*/React.createElement("span", null, $l('Table', computedRecordCachedType ? cachedTypeIntlMap[computedRecordCachedType] : 'cached_records')), !showCachedTips && /*#__PURE__*/React.createElement(Button, { funcType: FuncType.link, color: ButtonColor.primary, icon: "delete", size: Size.small, onClick: function onClick() { return handleClearCache(computedRecordCachedType); } })) }))]; records.forEach(function (record) { return rows.push(generateRow(_objectSpread(_objectSpread({}, props), {}, { record: record, index: index, statistics: statistics, parentExpanded: true }))); }); return rows; } return []; } function generateNormalRows(rows, records, props, statistics) { var index = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : { count: 0 }; records.forEach(function (record) { return generateRowAndChildRows(rows, _objectSpread(_objectSpread({}, props), {}, { record: record, index: index, statistics: statistics, parentExpanded: true })); }); return rows; } function generateGroupRows(rows, groups, props, hasCached, statistics) { var groupPath = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : []; var index = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : { count: 0 }; var isParentLast = arguments.length > 7 ? arguments[7] : undefined; var columnGroups = props.columnGroups, lock = props.lock, tableStore = props.tableStore; var tableGroups = tableStore.groups, dataSet = tableStore.dataSet, prefixCls = tableStore.prefixCls; var length = groups.length; groups.forEach(function (group, i) { var subGroups = group.subGroups, records = group.records, name = group.name, subHGroups = group.subHGroups, children = group.children; var hasChildren = children && tableStore.isGroupExpanded(group); var isLastInTreeNode = i === length - 1 && isParentLast !== false; var isLast = isLastInTreeNode && !hasChildren; var path = [].concat(_toConsumableArray(groupPath), [[group, isLast]]); var tableGroup = tableGroups && tableGroups.find(function (g) { return g.name === name; }); if (tableGroup && tableGroup.type === GroupType.row) { var columnProps = tableGroup.columnProps; var _ref = columnProps || {}, _ref$renderer = _ref.renderer, renderer = _ref$renderer === void 0 ? defaultAggregationRenderer : _ref$renderer; var groupName = tableGroup.name; var header = getHeader(_objectSpread(_objectSpread({}, columnProps), {}, { name: groupName, dataSet: dataSet, group: group, groups: groups })); rows.push(generateRowGroup({ key: "$group-".concat(path.map(function (_ref2) { var _ref3 = _slicedToArray(_ref2, 1), g = _ref3[0]; return g.value; }).join('-')), columnGroups: columnGroups, lock: lock, tableStore: tableStore, statistics: statistics, children: /*#__PURE__*/React.createElement(React.Fragment, null, header, header && /*#__PURE__*/React.createElement("span", { className: "".concat(prefixCls, "-row-group-divider") }), renderer({ text: group.value, rowGroup: group, name: groupName, dataSet: dataSet, record: group.totalRecords[0] })), rowGroupLevel: { count: path.length - (hasCached ? 0 : 1) } })); } if (subHGroups) { var $index = { count: 0 }; subHGroups.forEach(function (group) { group.records.slice($index.count).forEach(function (record) { generateRowAndChildRows(rows, _objectSpread(_objectSpread({}, props), {}, { record: record, index: index, statistics: statistics, headerGroup: $index, groupPath: path, parentExpanded: true })); }); }); } else { if (subGroups && subGroups.length) { generateGroupRows(rows, subGroups, props, hasCached, statistics, path, index, isLast); } records.forEach(function (record) { generateRowAndChildRows(rows, _objectSpread(_objectSpread({}, props), {}, { record: record, index: index, statistics: statistics, groupPath: path, parentExpanded: true })); }); } if (hasChildren) { generateGroupRows(rows, children, props, hasCached, statistics, groupPath, undefined, isLastInTreeNode); } }); return rows; } function generateRows(props, hasCached, statistics) { var tableStore = props.tableStore; var currentData = tableStore.currentData, groupedData = tableStore.groupedData, showCachedTips = tableStore.showCachedTips; var rows = []; if (hasCached && currentData.length) { var columnGroups = props.columnGroups, lock = props.lock; rows.push(generateRowGroup({ key: '$$group-rows', columnGroups: columnGroups, lock: lock, tableStore: tableStore, statistics: statistics, children: /*#__PURE__*/React.createElement(React.Fragment, null, showCachedTips && /*#__PURE__*/React.createElement(ObserverCheckBox, { className: "".concat(tableStore.prefixCls, "-cached-group-check"), checked: tableStore.allCurrentChecked, indeterminate: tableStore.currentIndeterminate, onChange: function onChange() { if (tableStore.allCurrentChecked) { tableStore.unCheckAllCurrent(); } else { tableStore.checkAllCurrent(); } } }), $l('Table', showCachedTips ? 'current_page' : 'current_page_records')) })); } if (groupedData.length) { generateGroupRows(rows, groupedData, props, hasCached, statistics); } else if (currentData.length) { generateNormalRows(rows, currentData, props, statistics); } return rows; } function getEmptyRow(props) { var tableStore = props.tableStore, columnGroups = props.columnGroups, lock = props.lock; var emptyText = tableStore.emptyText, width = tableStore.width, prefixCls = tableStore.prefixCls, dataSet = tableStore.dataSet; var styles = width ? { position: isStickySupport() ? 'sticky' : 'relative', left: pxToRem(width / 2, true) } : { transform: 'none', display: 'inline-block' }; var tdStyle = width ? undefined : { textAlign: 'center' }; return /*#__PURE__*/React.createElement("tr", { className: "".concat(prefixCls, "-empty-row") }, /*#__PURE__*/React.createElement("td", { colSpan: columnGroups.leafs.length, style: tdStyle }, /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-empty-text-wrapper"), style: styles }, !lock && dataSet.status === DataSetStatus.ready && emptyText))); } function findRowMeta(rowMetaData, count) { var index = count.index; var meta = rowMetaData[index]; while (meta) { if (meta.type === 'row') { return meta; } index += 1; count.index = index; meta = rowMetaData[index]; } } var VirtualRows = function VirtualRows(props) { var lock = props.lock, columnGroups = props.columnGroups, onClearCache = props.onClearCache, expandIconColumnIndex = props.expandIconColumnIndex, tableStore = props.tableStore, rowDragRender = props.rowDragRender, isTree = props.isTree, rowDraggable = props.rowDraggable, snapshot = props.snapshot, dragRowHeight = props.dragRowHeight, isFixedRowHeight = props.isFixedRowHeight, virtualCell = props.virtualCell; var draggableId = snapshot && snapshot.draggingFromThisWith; var _useComputed = useComputed(function () { var $statistics = { count: 0, rowMetaData: [] }; var cachedRows = generateCachedRows({ tableStore: tableStore, columnGroups: columnGroups, lock: lock, isTree: isTree, rowDraggable: rowDraggable, virtual: true, isFixedRowHeight: isFixedRowHeight, virtualCell: virtualCell }, onClearCache, $statistics); var rows = generateRows({ tableStore: tableStore, columnGroups: columnGroups, expandIconColumnIndex: expandIconColumnIndex, lock: lock, rowDragRender: rowDragRender, isTree: isTree, rowDraggable: rowDraggable, draggableId: draggableId, dragRowHeight: dragRowHeight, virtual: true, isFixedRowHeight: isFixedRowHeight, virtualCell: virtualCell }, cachedRows.length > 0, $statistics); return [cachedRows.concat(rows), $statistics]; }, [tableStore, columnGroups, expandIconColumnIndex, lock, isTree, rowDraggable, rowDragRender, onClearCache, draggableId, dragRowHeight, isFixedRowHeight, virtualCell]), _useComputed2 = _slicedToArray(_useComputed, 2), totalRows = _useComputed2[0], statistics = _useComputed2[1]; var renderGroup = useCallback(function (startIndex) { var groups = []; var rowMetaData = statistics.rowMetaData; var first = rowMetaData[startIndex]; if (first && first.type === 'group' && first.groupLevel === 0) { return groups; } var level; rowMetaData.slice(0, startIndex).reverse().some(function (metaData) { if (metaData.type === 'group') { var _metaData$groupLevel = metaData.groupLevel, groupLevel = _metaData$groupLevel === void 0 ? 0 : _metaData$groupLevel; if (level === undefined || groupLevel < level) { level = groupLevel; groups.unshift(metaData.node); } return groupLevel === 0; } return false; }); return groups; }, [statistics]); var renderRow = useCallback(function (rIndex) { return totalRows[rIndex]; }, [totalRows]); useEffect(action(function () { var oldRowMetaData = tableStore.rowMetaData, tableAggregation = tableStore.aggregation; var rowMetaData = statistics.rowMetaData; if (oldRowMetaData) { var count = { index: -1 }; oldRowMetaData.every(function (_ref4) { var actualHeight = _ref4.actualHeight, type = _ref4.type, aggregation = _ref4.aggregation; if (type === 'group') { return true; } count.index += 1; if (actualHeight !== undefined && aggregation === tableAggregation) { var newMeta = findRowMeta(rowMetaData, count); if (newMeta) { newMeta.setHeight(actualHeight); return true; } } tableStore.lastMeasuredIndex = Math.max(count.index - 1, 0); return false; }); } else { tableStore.lastMeasuredIndex = 0; } tableStore.rowMetaData = rowMetaData; }), [statistics, tableStore]); return totalRows.length ? /*#__PURE__*/React.createElement(VirtualVerticalContainer, { renderBefore: tableStore.hasRowGroups ? renderGroup : undefined }, renderRow) : getEmptyRow({ tableStore: tableStore, lock: lock, columnGroups: columnGroups }); }; VirtualRows.displayName = 'VirtualRows'; var Rows = function Rows(props) { var lock = props.lock, columnGroups = props.columnGroups, onClearCache = props.onClearCache, expandIconColumnIndex = props.expandIconColumnIndex, tableStore = props.tableStore, rowDragRender = props.rowDragRender, isTree = props.isTree, rowDraggable = props.rowDraggable, isFixedRowHeight = props.isFixedRowHeight, virtualCell = props.virtualCell; var cachedRows = useComputed(function () { return generateCachedRows({ tableStore: tableStore, columnGroups: columnGroups, lock: lock, isTree: isTree, rowDraggable: rowDraggable, virtual: false, isFixedRowHeight: isFixedRowHeight, virtualCell: virtualCell }, onClearCache); }, [tableStore, columnGroups, onClearCache, lock, isTree, rowDraggable, isFixedRowHeight, virtualCell]); var hasCache = cachedRows.length > 0; var rows = useComputed(function () { return generateRows({ tableStore: tableStore, columnGroups: columnGroups, expandIconColumnIndex: expandIconColumnIndex, lock: lock, rowDragRender: rowDragRender, isTree: isTree, rowDraggable: rowDraggable, virtual: false, isFixedRowHeight: isFixedRowHeight, virtualCell: virtualCell }, hasCache); }, [tableStore, columnGroups, hasCache, expandIconColumnIndex, lock, isTree, rowDraggable, rowDragRender, isFixedRowHeight, virtualCell]); useEffect(action(function () { if (tableStore.actualRows !== undefined) { tableStore.actualRows = undefined; } if (tableStore.rowMetaData) { tableStore.rowMetaData = undefined; } }), [tableStore]); return cachedRows.length || rows.length ? /*#__PURE__*/React.createElement(React.Fragment, null, cachedRows, rows) : getEmptyRow({ tableStore: tableStore, lock: lock, columnGroups: columnGroups }); }; Rows.displayName = 'Rows'; var ObserverVirtualRows = observer(VirtualRows); var ObserverRows = observer(Rows); var TableTBody = function TableTBody(props) { var lock = props.lock, columnGroups = props.columnGroups, snapshot = props.snapshot, dragRowHeight = props.dragRowHeight, rest = _objectWithoutProperties(props, _excluded); var _useContext = useContext(TableContext), prefixCls = _useContext.prefixCls, tableStore = _useContext.tableStore, rowDragRender = _useContext.rowDragRender, dataSet = _useContext.dataSet, expandedRowRenderer = _useContext.expandedRowRenderer, isTree = _useContext.isTree; var rowDraggable = tableStore.rowDraggable, virtualCell = tableStore.virtualCell, isFixedRowHeight = tableStore.isFixedRowHeight; var expandIconColumnIndex = expandedRowRenderer || isTree ? lock === ColumnLock.right ? columnGroups.leafs.filter(function (group) { return group.column.lock !== ColumnLock.right; }).length : 0 : -1; var handleResize = useCallback(action(function (_width, height, target) { // why target is undefined ? if (target && target.offsetParent && height) { tableStore.calcBodyHeight = height; } }), [tableStore]); var handleClearCache = useCallback(action(function (type) { switch (type) { case RecordCachedType.selected: dataSet.setCachedSelected([]); break; case RecordCachedType.add: dataSet.setCachedCreated([]); break; case RecordCachedType.update: dataSet.setCachedUpdated([]); break; case RecordCachedType["delete"]: dataSet.setCachedDestroyed([]); break; default: dataSet.clearCachedRecords(); } tableStore.recordCachedType = undefined; }), [dataSet, tableStore]); useLayoutEffect(function () { if (!lock) { var node = tableStore.node; if (node.isFocus && !node.wrapper.contains(document.activeElement)) { node.focus(); } } }, [lock, tableStore]); var renderClone = useRenderClone(lock ? undefined : columnGroups); var body = tableStore.propVirtual ? /*#__PURE__*/React.createElement(ObserverVirtualRows, { onClearCache: handleClearCache, expandIconColumnIndex: expandIconColumnIndex, columnGroups: columnGroups, tableStore: tableStore, rowDragRender: rowDragRender, lock: lock, isTree: isTree, rowDraggable: rowDraggable, snapshot: snapshot, dragRowHeight: dragRowHeight, isFixedRowHeight: isFixedRowHeight, virtualCell: virtualCell }) : /*#__PURE__*/React.createElement(ObserverRows, { onClearCache: handleClearCache, expandIconColumnIndex: expandIconColumnIndex, columnGroups: columnGroups, tableStore: tableStore, rowDragRender: rowDragRender, lock: lock, isTree: isTree, rowDraggable: rowDraggable, isFixedRowHeight: isFixedRowHeight, virtualCell: virtualCell }); var tbody = rowDraggable && !tableStore.virtual ? /*#__PURE__*/React.createElement(Droppable, _extends({ droppableId: tableStore.node.props.id || "table", key: "table", isCombineEnabled: isTree, mode: "standard", renderClone: renderClone, getContainerForClone: function getContainerForClone() { return instance(tableStore.node.getClassName(), prefixCls).tbody; } }, rowDragRender && rowDragRender.droppableProps), function (droppableProvided) { return /*#__PURE__*/React.createElement("tbody", _extends({ ref: droppableProvided.innerRef }, droppableProvided.droppableProps, { className: "".concat(prefixCls, "-tbody") }, rest), body, droppableProvided.placeholder); }) : /*#__PURE__*/React.createElement("tbody", _extends({ className: "".concat(prefixCls, "-tbody") }, rest), body); return lock ? tbody : /*#__PURE__*/React.createElement(ReactResizeObserver, { onResize: handleResize, resizeProp: "height", immediately: true }, tbody); }; TableTBody.displayName = 'TableTBody'; export default observer(TableTBody); //# sourceMappingURL=TableTBody.js.map