choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
723 lines (637 loc) • 25.1 kB
JavaScript
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
import _regeneratorRuntime from "@babel/runtime/regenerator";
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _extends from "@babel/runtime/helpers/extends";
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import React, { cloneElement, isValidElement, useCallback, useContext, useEffect, useMemo, useRef } from 'react';
import { observer } from 'mobx-react-lite';
import { isArrayLike } from 'mobx';
import raf from 'raf';
import classNames from 'classnames';
import isNil from 'lodash/isNil';
import isPlainObject from 'lodash/isPlainObject';
import isString from 'lodash/isString';
import isObject from 'lodash/isObject';
import { pxToRem } from '../../../es/_util/UnitConvertor';
import { getConfig } from '../../../es/configure';
import KeyCode from '../../../es/_util/KeyCode';
import measureScrollbar from '../../../es/_util/measureScrollbar';
import { getTooltip, getTooltipTheme } from '../../../es/_util/TooltipUtils';
import TableContext from './TableContext';
import { findCell, getColumnKey, getEditorByColumnAndRecord, isInCellEditor, isStickySupport } from './utils';
import { FieldType, RecordStatus } from '../data-set/enum';
import { SELECTION_KEY } from './TableStore';
import { ColumnAlign, SelectionMode, TableCommandType } from './enum';
import Tooltip from '../tooltip/Tooltip';
import ObserverCheckBox from '../check-box/CheckBox';
import { $l } from '../locale-context';
import Button from '../button/Button';
import { LabelLayout } from '../form/enum';
import { findFirstFocusableElement } from '../_util/focusable';
import SelectionTreeBox from './SelectionTreeBox';
import { getDateFormatByField, isFieldValueEmpty, processFieldValue, processValue as utilProcessValue, renderMultiLine, renderMultipleValues, renderRangeValue, renderValidationMessage as utilRenderValidationMessage, showValidationMessage, toMultipleValue, toRangeValue, transformHighlightProps } from '../field/utils';
import localeContext from '../locale-context/LocaleContext';
import isEmpty from '../_util/isEmpty';
import { Tooltip as TextTooltip } from '../core/enum';
import isOverflow from '../overflow-tip/util';
import { hide, show } from '../tooltip/singleton';
import useComputed from '../use-computed';
import { ShowHelp } from '../field/enum';
import { defaultOutputRenderer } from '../output/utils';
var inTab = false;
var TableCellInner = observer(function TableCellInner(props) {
var column = props.column,
record = props.record,
children = props.children,
style = props.style,
disabled = props.disabled,
inAggregation = props.inAggregation,
prefixCls = props.prefixCls,
colSpan = props.colSpan;
var multipleValidateMessageLengthRef = useRef(0);
var tooltipShownRef = useRef();
var _useContext = useContext(TableContext),
pristine = _useContext.pristine,
aggregation = _useContext.aggregation,
inlineEdit = _useContext.inlineEdit,
rowHeight = _useContext.rowHeight,
tableStore = _useContext.tableStore,
dataSet = _useContext.dataSet,
columnEditorBorder = _useContext.columnEditorBorder,
indentSize = _useContext.indentSize,
checkField = _useContext.checkField,
selectionMode = _useContext.selectionMode;
var innerPrefixCls = "".concat(prefixCls, "-inner");
var tooltip = tableStore.getColumnTooltip(column);
var name = column.name,
key = column.key,
lock = column.lock,
renderer = column.renderer,
command = column.command,
align = column.align;
var columnKey = getColumnKey(column);
var height = record.getState("__column_resize_height_".concat(name));
var currentEditRecord = tableStore.currentEditRecord;
var field = record.getField(name);
var fieldDisabled = disabled || field && field.get('disabled');
var columnCommand = useComputed(function () {
if (typeof command === 'function') {
return command({
dataSet: dataSet,
record: record,
aggregation: aggregation
});
}
return command;
}, [record, command, dataSet, aggregation]);
var canFocus = useMemo(function () {
return !fieldDisabled && (!inlineEdit || record === currentEditRecord);
}, [fieldDisabled, record, currentEditRecord, inlineEdit]);
var cellEditor = getEditorByColumnAndRecord(column, record);
var cellEditorInCell = isInCellEditor(cellEditor);
var hasEditor = !pristine && cellEditor && !cellEditorInCell;
var showEditor = useCallback(function (cell) {
if (name && hasEditor) {
if (!lock && tableStore.overflowX) {
var tableBodyWrap = tableStore.virtual ? cell.offsetParent.parentNode.parentNode : cell.offsetParent;
if (tableBodyWrap) {
var _tableStore$columnGro = tableStore.columnGroups,
leftLeafColumnsWidth = _tableStore$columnGro.leftLeafColumnsWidth,
rightLeafColumnsWidth = _tableStore$columnGro.rightLeafColumnsWidth;
var offsetLeft = cell.offsetLeft,
offsetWidth = cell.offsetWidth;
var scrollLeft = tableBodyWrap.scrollLeft;
var _tableBodyWrap$getBou = tableBodyWrap.getBoundingClientRect(),
width = _tableBodyWrap$getBou.width;
var leftSide = offsetLeft - leftLeafColumnsWidth;
var rightSide = offsetLeft + offsetWidth - width + rightLeafColumnsWidth + measureScrollbar();
var sl = scrollLeft;
if (sl < rightSide) {
sl = rightSide;
}
if (sl > leftSide) {
sl = leftSide;
}
if (sl !== scrollLeft) {
tableBodyWrap.scrollLeft = sl;
}
}
}
tableStore.showEditor(name);
var editor = tableStore.editors.get(name);
if (editor) {
if (editor.cellNode) {
if (tableStore.inlineEdit) {
if (editor.inTab) {
editor.inTab = false;
} else {
editor.focus();
}
} else {
editor.hideEditor();
}
} else if (tableStore.inlineEdit) {
editor.focus();
} else {
raf(function () {
editor.alignEditor(!isStickySupport() && lock ? findCell(tableStore, columnKey, lock) : cell);
editor.focus();
});
}
}
}
}, [column, name, hasEditor, columnKey, tableStore]);
var handleFocus = useCallback(function (e) {
if (canFocus) {
if (key !== SELECTION_KEY) {
dataSet.current = record;
}
showEditor(e.currentTarget);
if (!isStickySupport() && (key === SELECTION_KEY || !hasEditor)) {
var cell = findCell(tableStore, columnKey, lock);
if (cell && !cell.contains(document.activeElement)) {
var node = findFirstFocusableElement(cell);
if (node && !inTab) {
node.focus();
}
}
}
}
inTab = false;
}, [tableStore, dataSet, record, lock, columnKey, canFocus, hasEditor, showEditor]);
var handleEditorKeyDown = useCallback(function (e) {
switch (e.keyCode) {
case KeyCode.TAB:
{
var cell = findCell(tableStore, columnKey);
if (cell) {
if (cell.contains(document.activeElement)) {
inTab = true;
} else {
var node = findFirstFocusableElement(cell);
if (node) {
inTab = true;
node.focus();
}
}
}
break;
}
default:
}
}, [tableStore, columnKey]);
var handleCommandSave = useCallback(function () {
return dataSet.submit().then(function (result) {
if (result !== false) {
tableStore.currentEditRecord = undefined;
}
});
}, [tableStore, dataSet]);
var handleCommandCancel = useCallback(function () {
if (record.status === RecordStatus.add) {
dataSet.remove(record);
} else {
record.reset();
tableStore.currentEditRecord = undefined;
}
}, [tableStore, record, dataSet]);
var handleCommandEdit = useCallback(function () {
if (tableStore.inlineEdit) {
tableStore.currentEditRecord = record;
}
}, [tableStore, record]);
var handleCommandDelete = useCallback(function () {
dataSet["delete"](record);
}, [dataSet, record]);
var multiLine = field && field.get('multiLine');
var fieldType = !aggregation && rowHeight !== 'auto' && field && field.type;
var rows = multiLine ? _toConsumableArray(record.fields.values()).reduce(function (count, dsField) {
var bind = dsField.get('bind');
if (bind && bind.startsWith("".concat(name, "."))) {
return count + 1;
}
return count;
}, 0) : 0;
var checkBox = function () {
if (children) {
if (selectionMode === SelectionMode.treebox) {
return React.createElement(SelectionTreeBox, {
record: record
});
}
if (checkField && !tableStore.hasCheckFieldColumn) {
return React.createElement(ObserverCheckBox, {
name: checkField,
record: record,
disabled: disabled,
indeterminate: record.isIndeterminate
});
}
}
}();
var renderCommand = useCallback(function () {
var tableCommandProps = getConfig('tableCommandProps');
var classString = classNames("".concat(prefixCls, "-command"), tableCommandProps && tableCommandProps.className);
if (record.editing) {
return [React.createElement(Tooltip, {
key: "save",
title: $l('Table', 'save_button')
}, React.createElement(Button, _extends({}, tableCommandProps, {
className: classString,
icon: "finished",
onClick: handleCommandSave
}))), React.createElement(Tooltip, {
key: "cancel",
title: $l('Table', 'cancel_button')
}, React.createElement(Button, _extends({}, tableCommandProps, {
className: classString,
icon: "cancle_a",
onClick: handleCommandCancel
})))];
}
if (columnCommand) {
var commands = [];
columnCommand.forEach(function (button) {
var tableButtonProps = {};
if (isArrayLike(button)) {
tableButtonProps = button[1] || {};
button = button[0];
}
if (isString(button) && button in TableCommandType) {
var getButtonProps = function getButtonProps(type) {
switch (type) {
case TableCommandType.edit:
return {
icon: 'mode_edit',
onClick: handleCommandEdit,
disabled: disabled,
title: $l('Table', 'edit_button')
};
case TableCommandType["delete"]:
return {
icon: 'delete',
onClick: handleCommandDelete,
disabled: disabled,
title: $l('Table', 'delete_button')
};
default:
}
};
var defaultButtonProps = getButtonProps(button);
if (defaultButtonProps) {
var _tableButtonProps = tableButtonProps,
afterClick = _tableButtonProps.afterClick,
buttonProps = _objectWithoutProperties(_tableButtonProps, ["afterClick"]);
if (afterClick) {
var onClick = defaultButtonProps.onClick;
defaultButtonProps.onClick =
/*#__PURE__*/
function () {
var _ref = _asyncToGenerator(
/*#__PURE__*/
_regeneratorRuntime.mark(function _callee(e) {
return _regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
e.persist();
_context.prev = 1;
_context.next = 4;
return onClick(e);
case 4:
_context.prev = 4;
afterClick(e);
return _context.finish(4);
case 7:
case "end":
return _context.stop();
}
}
}, _callee, null, [[1,, 4, 7]]);
}));
return function (_x) {
return _ref.apply(this, arguments);
};
}();
}
var title = defaultButtonProps.title,
otherProps = _objectWithoutProperties(defaultButtonProps, ["title"]);
commands.push(React.createElement(Tooltip, {
key: button,
title: title
}, React.createElement(Button, _extends({}, tableCommandProps, otherProps, buttonProps, {
className: classNames(classString, otherProps.className, buttonProps.className)
}))));
}
} else if (isValidElement(button)) {
commands.push(cloneElement(button, _objectSpread({}, tableCommandProps, {}, button.props, {
className: classNames(classString, button.props.className)
})));
} else if (isObject(button)) {
commands.push(React.createElement(Button, _extends({}, tableCommandProps, button, {
className: classNames(classString, button.className)
})));
}
});
return commands;
}
}, [prefixCls, record, columnCommand, aggregation, disabled, handleCommandEdit, handleCommandDelete, handleCommandSave, handleCommandCancel]);
var renderEditor = useCallback(function () {
if (isValidElement(cellEditor)) {
/**
* 渲染多行编辑器
*/
if (multiLine) {
return cellEditor;
}
var newEditorProps = _objectSpread({}, cellEditor.props, {
record: record,
name: name,
pristine: pristine,
disabled: disabled || inlineEdit && !record.editing,
indeterminate: checkField && checkField === name && record.isIndeterminate,
labelLayout: LabelLayout.none,
showHelp: ShowHelp.none
});
return cloneElement(cellEditor, newEditorProps);
}
}, [disabled, cellEditor, checkField, multiLine, record, name, pristine, inlineEdit]);
var cellRenderer = useMemo(function () {
if (columnCommand) {
return renderCommand;
}
if (cellEditorInCell) {
return renderEditor;
}
if (aggregation && renderer) {
return function (rendererProps) {
return renderer(_objectSpread({}, rendererProps, {
aggregation: aggregation
}));
};
}
return renderer;
}, [columnCommand, cellEditorInCell, renderEditor, renderCommand, renderer, field, aggregation]);
var prefixStyle = useMemo(function () {
if (!aggregation) {
if (height !== undefined && rows === 0) {
return _objectSpread({
height: pxToRem(height),
lineHeight: 1
}, style);
}
if (rowHeight !== 'auto') {
var isCheckBox = fieldType === FieldType["boolean"] || key === SELECTION_KEY;
var borderPadding = isCheckBox ? 4 : 2;
var heightPx = rows > 0 ? (rowHeight + 2) * rows + 1 : rowHeight;
var lineHeightPx = hasEditor || isCheckBox ? rowHeight - borderPadding : rowHeight;
return _objectSpread({
height: pxToRem(heightPx),
lineHeight: rows > 0 ? 'inherit' : pxToRem(lineHeightPx)
}, style);
}
}
return style;
}, [fieldType, key, rows, rowHeight, height, style, aggregation, hasEditor]);
var textAlign = useMemo(function () {
return align || (columnCommand ? ColumnAlign.center : getConfig('tableColumnAlign')(column, field));
}, [columnCommand, align, column, field]);
var colSpanStyle = useMemo(function () {
return colSpan && colSpan > 1 && (textAlign === ColumnAlign.right || textAlign === ColumnAlign.center) ? {
width: "calc(100% - ".concat(pxToRem(30), ")")
} : {};
}, [colSpan, textAlign]);
var innerStyle = useMemo(function () {
if (inAggregation) {
return _objectSpread({}, prefixStyle, {}, colSpanStyle);
}
return _objectSpread({
textAlign: textAlign
}, prefixStyle, {}, colSpanStyle);
}, [inAggregation, textAlign, prefixStyle, colSpanStyle]);
var value = name ? pristine ? record.getPristineValue(name) : record.get(name) : undefined;
var renderValidationResult = useCallback(function (validationResult) {
if (validationResult && validationResult.validationMessage) {
return utilRenderValidationMessage(validationResult.validationMessage, true);
}
}, []);
var isValidationMessageHidden = useCallback(function (message) {
return !message || pristine;
}, [pristine]);
var editorBorder = !inlineEdit && hasEditor;
var getRenderedValue = function getRenderedValue() {
var processValue = function processValue(v) {
if (!isNil(v)) {
var _text = isPlainObject(v) ? v : utilProcessValue(v, getDateFormatByField(field));
return processFieldValue(_text, field, {
getProp: function getProp(propName) {
return field && field.get(propName);
},
lang: dataSet && dataSet.lang || localeContext.locale.lang
}, true);
}
return '';
};
var processRenderer = function processRenderer(v, repeat) {
var processedValue;
if (field && (field.lookup || field.get('options') || field.get('lovCode'))) {
processedValue = field.getText(v);
} // 值集中不存在 再去取直接返回的值
var text = isNil(processedValue) ? processValue(v) : processedValue;
return (cellRenderer || defaultOutputRenderer)({
value: v,
text: text,
record: record,
dataSet: dataSet,
name: name,
repeat: repeat
});
};
if (field) {
if (!cellEditorInCell) {
var multiple = field.get('multiple');
var range = field.get('range');
if (multiple) {
var _renderMultipleValues = renderMultipleValues(value, {
disabled: disabled,
readOnly: true,
range: range,
prefixCls: prefixCls,
processRenderer: processRenderer,
renderValidationResult: renderValidationResult,
isValidationMessageHidden: isValidationMessageHidden,
showValidationMessage: showValidationMessage,
validator: field.validator
}),
tags = _renderMultipleValues.tags,
multipleValidateMessageLength = _renderMultipleValues.multipleValidateMessageLength;
multipleValidateMessageLengthRef.current = multipleValidateMessageLength;
return tags;
}
if (range) {
return renderRangeValue(toRangeValue(value, range), {
processRenderer: processRenderer
});
}
}
if (field.get('multiLine')) {
var _renderMultiLine = renderMultiLine({
name: name,
field: field,
record: record,
dataSet: dataSet,
prefixCls: innerPrefixCls,
renderer: cellRenderer,
renderValidationResult: renderValidationResult,
isValidationMessageHidden: isValidationMessageHidden,
processValue: processValue,
tooltip: tooltip,
labelTooltip: getTooltip('label')
}),
lines = _renderMultiLine.lines,
_multipleValidateMessageLength = _renderMultiLine.multipleValidateMessageLength;
multipleValidateMessageLengthRef.current = _multipleValidateMessageLength;
return lines;
}
}
var textNode = processRenderer(value);
return textNode === '' ? getConfig('tableDefaultRenderer') : textNode;
};
var result = getRenderedValue();
var text = isEmpty(result) || isArrayLike(result) && !result.length ? editorBorder ? undefined : getConfig('renderEmpty')('Output') : result;
var showTooltip = useCallback(function (e) {
if (field && !(multipleValidateMessageLengthRef.current > 0 || !field.get('validator') && field.get('multiple') && toMultipleValue(value, field.get('range')).length)) {
var validator = field.validator;
var message = validator && renderValidationResult(validator.currentValidationResult);
if (!isValidationMessageHidden(message)) {
showValidationMessage(e, message);
return true;
}
}
var element = e.target;
if (element && !multiLine && (tooltip === TextTooltip.always || tooltip === TextTooltip.overflow && isOverflow(element))) {
if (text) {
show(element, {
title: text,
placement: 'right',
theme: getTooltipTheme('table-cell')
});
return true;
}
}
return false;
}, [renderValidationResult, isValidationMessageHidden, field, tooltip, multiLine, text]);
var handleMouseEnter = useCallback(function (e) {
if (!tableStore.columnResizing && showTooltip(e)) {
tooltipShownRef.current = true;
}
}, [tooltipShownRef, tableStore, showTooltip]);
var handleMouseLeave = useCallback(function () {
if (!tableStore.columnResizing && tooltipShownRef.current) {
hide();
tooltipShownRef.current = false;
}
}, [tooltipShownRef, tableStore]);
useEffect(function () {
if (name && inlineEdit && record === currentEditRecord) {
var currentEditor = tableStore.editors.get(name);
if (currentEditor) {
currentEditor.alignEditor();
}
return function () {
if (currentEditor) {
currentEditor.hideEditor();
}
};
}
}, []);
useEffect(function () {
return function () {
if (tooltipShownRef.current) {
hide();
tooltipShownRef.current = false;
}
};
}, [tooltipShownRef]);
var innerProps = {
tabIndex: hasEditor && canFocus ? 0 : -1,
onFocus: handleFocus,
children: text
};
var empty = field ? isFieldValueEmpty(value, field.get('range'), field.get('multiple'), field.type === FieldType.object ? field.get('valueField') : undefined, field.type === FieldType.object ? field.get('textField') : undefined) : false;
var innerClassName = [innerPrefixCls];
if (columnEditorBorder) {
innerClassName.push("".concat(prefixCls, "-inner-bordered"));
}
if (editorBorder) {
innerClassName.push("".concat(prefixCls, "-inner-editable"));
}
var highlight;
var inValid;
if (field) {
if (!pristine && field.dirty) {
innerClassName.push("".concat(prefixCls, "-inner-dirty"));
}
if (!inlineEdit && !cellEditorInCell) {
inValid = !field.valid;
if (inValid) {
innerClassName.push("".concat(prefixCls, "-inner-invalid"));
}
}
if (editorBorder) {
if (field.required && (empty || !getConfig('showRequiredColorsOnlyEmpty'))) {
innerClassName.push("".concat(prefixCls, "-inner-required"));
}
highlight = field.get('highlight');
if (highlight) {
innerClassName.push("".concat(prefixCls, "-inner-highlight"));
}
}
}
if (fieldDisabled) {
innerClassName.push("".concat(prefixCls, "-inner-disabled"));
}
if (multiLine) {
innerClassName.push("".concat(prefixCls, "-inner-multiLine"));
}
if (!isStickySupport() && !hasEditor) {
innerProps.onKeyDown = handleEditorKeyDown;
}
if (inValid || tooltip) {
innerProps.onMouseEnter = handleMouseEnter;
innerProps.onMouseLeave = handleMouseLeave;
}
if (rowHeight === 'auto') {
innerClassName.push("".concat(prefixCls, "-inner-auto-height"));
} else {
innerClassName.push("".concat(prefixCls, "-inner-row-height-fixed"));
}
if (height !== undefined && rows === 0) {
innerClassName.push("".concat(prefixCls, "-inner-fixed-height"));
}
var indentText = children && React.createElement("span", {
style: {
paddingLeft: pxToRem(indentSize * record.level)
}
});
var prefix = (indentText || children || checkBox) && React.createElement("span", {
key: "prefix",
className: "".concat(prefixCls, "-prefix"),
style: prefixStyle
}, indentText, children, checkBox);
var output = React.createElement("span", _extends({
key: "output"
}, innerProps, {
style: innerStyle,
className: innerClassName.join(' ')
}));
return React.createElement(React.Fragment, null, prefix, highlight ? (column.highlightRenderer || tableStore.cellHighlightRenderer)(transformHighlightProps(highlight, {
dataSet: dataSet,
record: record,
name: name
}), output) : output);
});
TableCellInner.displayName = 'TableCellInner';
export default TableCellInner;
//# sourceMappingURL=TableCellInner.js.map