Commit ff47a1cb authored by zhangwenshuai's avatar zhangwenshuai

修改单元格编辑触发逻辑,改为点击时判断是否为当前编辑单元格

parent 1acd88f6
......@@ -10,27 +10,25 @@
height: 100%;
font-size: @textFontGen;
padding: 0 @paddingLg;
&.hover {
background: @tableHoverBgColor;
.checkbox {
display: block;
&.hasNum {
display: block;
}
}
.num {
display: block;
&.hasCheckbox {
display: none;
}
}
.expand {
visibility: visible;
}
}
&.selected {
box-shadow: inset 0 0 0 1px @primaryColor;
}
//&.hover {
// background: @tableHoverBgColor;
// .checkbox {
// display: block;
// &.hasNum {
// display: block;
// }
// }
// .num {
// display: block;
// &.hasCheckbox {
// display: none;
// }
// }
// .expand {
// visibility: visible;
// }
//}
.num {
min-width: 30px;
max-width: 100px;
......@@ -38,7 +36,7 @@
.icon {
width: 22px;
}
&.checked{
&.checked {
display: none;
}
}
......@@ -49,7 +47,7 @@
&.hasNum {
display: none;
}
&.checked{
&.checked {
display: block;
}
}
......@@ -94,3 +92,26 @@
background: #333333;
}
}
&.selected {
box-shadow: inset 0 0 0 1px @primaryColor;
}
&.hover {
background: @tableHoverBgColor;
.detailCell {
.checkbox {
display: block;
&.hasNum {
display: block;
}
}
.num {
display: block;
&.hasCheckbox {
display: none;
}
}
.expand {
visibility: visible;
}
}
}
import React, { useEffect, useMemo, useState } from 'react';
import React, { useEffect, useMemo, useState, useRef } from 'react';
import { Checkbox, message, Popover } from 'antd';
import classNames from 'classnames';
import _ from 'lodash';
......@@ -33,10 +33,6 @@ const Cell = (props: CellProps) => {
rowSelection,
columns,
contentMenu,
selectedCell,
cellKey,
changeSelectedCell,
position = 'center',
} = props;
const {
columnType,
......@@ -47,6 +43,7 @@ const Cell = (props: CellProps) => {
cellRenderProps,
readOnlyFlag,
} = columnConfig;
const cellUnit = useRef(null);
const [status, setStatus] = useState('detail');
useEffect(() => {
......@@ -119,6 +116,7 @@ const Cell = (props: CellProps) => {
};
const selfRenderDetailCell = () => {
// 数据为空
let empty =
!cellData || cellData.length === 0 || (cellData.length === 1 && !cellData[0].text && !cellData[0].value);
let detailConfig;
......@@ -138,7 +136,7 @@ const Cell = (props: CellProps) => {
const style: any = {};
const { current = 1, pageSize = 20 } = paginationConfig || {};
// 构造序号
const getIndex = () => {
// if (current === 1) {
// let src = '';
......@@ -159,6 +157,7 @@ const Cell = (props: CellProps) => {
// }
return (current - 1) * pageSize + rowIndex + 1;
};
// 获取当前行在所选列表中的index
const getCheckedIndex = () => {
if (!rowSelection) {
return -1;
......@@ -171,6 +170,7 @@ const Cell = (props: CellProps) => {
});
return index;
};
// 构造行复选框
const getCheckbox = () => {
const { selectedRows, onChange } = rowSelection;
const index = getCheckedIndex();
......@@ -190,25 +190,43 @@ const Cell = (props: CellProps) => {
};
const { dynamicCellConfigDTO } = columnData;
const detail = (
<div
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
className={
selectedCell === `${position}_${cellKey}`
? classNames(`row_${rowIndex}`, `col_${columnIndex}`, s.detailCell, s.selected)
: classNames(`row_${rowIndex}`, `col_${columnIndex}`, s.detailCell)
}
className={s.detailCell}
onClick={() => {
// 不可编辑状态
if (!cellEditable || readOnlyFlag || (dynamicCellConfigDTO && dynamicCellConfigDTO.readonlyFlag)) {
return false;
}
if (selectedCell === `${position}_${cellKey}`) {
// 获取当前节点的选中状态
const dom = cellUnit.current;
let selected = false;
if (dom && dom.getAttribute('data-selectedCell')) {
selected = dom.getAttribute('data-selectedCell') === '1';
}
if (selected) {
// 当前已选中,则进入编辑状态
setStatus('edit');
if (dom) {
// 给当前dom添加编辑状态
dom.setAttribute('data-editingCell', '1');
}
} else {
changeSelectedCell && changeSelectedCell(`${position}_${cellKey}`);
// 否则进入选中状态
if (dom) {
// 先清除所有dom的选中状态及样式
const doms = document.querySelectorAll('.cellUnit');
if (doms) {
doms.forEach((item) => {
item.setAttribute('data-selectedCell', '0');
item.classList.remove(s.selected);
});
}
// 给当前dom添加选中状态
dom.setAttribute('data-selectedCell', '1');
// 给当前dom添加选中样式
dom.classList.add(s.selected);
}
}
}}
style={style}
......@@ -324,7 +342,16 @@ const Cell = (props: CellProps) => {
};
return (
<div className={cellClassName} style={cellStyle}>
<div
className={classNames('cellUnit', `row_${rowIndex}`, `col_${columnIndex}`, cellClassName)}
style={cellStyle}
id={`cellUnit_${rowIndex}_${columnIndex}`}
data-selectedCell="0"
data-editingCell="0"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
ref={cellUnit}
>
{status === 'detail' && selfRenderDetailCell()}
{status === 'edit' && selfRenderEditCell()}
</div>
......
......@@ -33,6 +33,7 @@
position: absolute;
right: 0;
z-index: 1;
overflow: hidden;
}
:global(.ReactVirtualized__Grid__innerScrollContainer) {
overflow: unset !important;
......
......@@ -615,16 +615,16 @@ export default class AirTable extends Component<TableProps, TableState> {
})}
/>
) : (
columnCount > 0 &&
!loading && (
<Empty
className={styles.defaultEmpty}
description={
noDataPlaceholder || locale.empty
}
/>
)
)}
columnCount > 0 &&
!loading && (
<Empty
className={styles.defaultEmpty}
description={
noDataPlaceholder || locale.empty
}
/>
)
)}
</div>
}
</div>
......@@ -677,6 +677,7 @@ export default class AirTable extends Component<TableProps, TableState> {
position: 'absolute',
right: 0,
top: headerHeight,
marginRight: -scrollbarWidth,
}}
>
<Grid
......@@ -694,8 +695,12 @@ export default class AirTable extends Component<TableProps, TableState> {
columns: showColumns,
showColumns: rightColumns,
})}
onScroll={(...arg: Array<Object>) => {
onScroll({ scrollTop: arg[0].scrollTop });
this.onScroll(arg[0]);
}}
columnCount={rightCount}
width={rightWidth}
width={rightWidth + scrollbarWidth}
rowHeight={rowHeight}
rowCount={rowCount}
height={totalHeight - scrollbarWidth}
......
......@@ -32,41 +32,15 @@ export const Tags = (props: any) => {
itemStyle.marginBottom = '5px';
}
return (
<div className={s.container}>
<div className={s.outContainer} ref={outer} style={outStyle}>
<div className={s.innerContainer} ref={inner} style={innerStyle}>
{value.map((item, index) => {
let color = '';
if (options && Array.isArray(options) && options.length > 0) {
const obj = options.find((ls) => ls.id === item.value) || {};
color = obj.color || 'e9eef9';
}
return (
<span
key={index}
className={mode === 'multiple' ? classNames(s.item, s.multi) : s.item}
style={{ ...itemStyle, background: `#${color}` }}
>
<div className={s.itemBgTxt}>{item.text}</div>
</span>
);
})}
</div>
</div>
{dotVisible && mode === 'multiple' && (
<Popover
trigger="click"
onClick={(e) => {
e.stopPropagation();
}}
placement="left"
overlayClassName={s.popContainer}
content={
<div
className={s.popContent}
onClick={(e) => {
e.stopPropagation();
}}
>
{value.map((item, index) => {
let color = '';
......@@ -83,91 +57,51 @@ export const Tags = (props: any) => {
</div>
}
>
<div className={s.moreBtn}>
<IconFont type="iconzhankai1" />
<div className={s.outContainer} ref={outer} style={outStyle}>
<div className={s.innerContainer} ref={inner} style={innerStyle}>
{value.map((item, index) => {
let color = '';
if (options && Array.isArray(options) && options.length > 0) {
const obj = options.find((ls) => ls.id === item.value) || {};
color = obj.color || 'e9eef9';
}
return (
<span
key={index}
className={classNames(s.item, mode === 'multiple' && s.multi)}
style={{ ...itemStyle, background: `#${color}` }}
>
<div className={s.itemBgTxt}>{item.text}</div>
</span>
);
})}
</div>
</div>
</Popover>
)}
{!dotVisible && (
<div className={s.outContainer} ref={outer} style={outStyle}>
<div className={s.innerContainer} ref={inner} style={innerStyle}>
{value.map((item, index) => {
let color = '';
if (options && Array.isArray(options) && options.length > 0) {
const obj = options.find((ls) => ls.id === item.value) || {};
color = obj.color || 'e9eef9';
}
return (
<span
key={index}
className={classNames(s.item, mode === 'multiple' && s.multi)}
style={{ ...itemStyle, background: `#${color}` }}
>
<div className={s.itemBgTxt}>{item.text}</div>
</span>
);
})}
</div>
</div>
)}
</div>
// <div className={s.container}>
// {dotVisible && mode === 'multiple' && (
// <Popover
// // trigger="click"
// onClick={(e) => {
// debugger
// e.stopPropagation();
// }}
// placement="left"
// overlayClassName={s.popContainer}
// content={
// <div
// className={s.popContent}
// onClick={(e) => {
// debugger
// e.stopPropagation();
// }}
// >
// {value.map((item, index) => {
// let color = '';
// if (options && Array.isArray(options) && options.length > 0) {
// const obj = options.find((ls) => ls.id === item.value) || {};
// color = obj.color || 'e9eef9';
// }
// return (
// <span className={s.popItem} key={index} style={{ background: `#${color}` }}>
// <div className={s.popItemBgTxt}>{item.text}</div>
// </span>
// );
// })}
// </div>
// }
// >
// <div className={s.outContainer} ref={outer} style={outStyle}>
// <div className={s.innerContainer} ref={inner} style={innerStyle}>
// {value.map((item, index) => {
// let color = '';
// if (options && Array.isArray(options) && options.length > 0) {
// const obj = options.find((ls) => ls.id === item.value) || {};
// color = obj.color || 'e9eef9';
// }
// return (
// <span
// key={index}
// className={classNames(s.item, mode === 'multiple' && s.multi)}
// style={{ ...itemStyle, background: `#${color}` }}
// >
// <div className={s.itemBgTxt}>{item.text}</div>
// </span>
// );
// })}
// </div>
// </div>
// </Popover>
// )}
// {!dotVisible && (
// <div className={s.outContainer} ref={outer} style={outStyle}>
// <div className={s.innerContainer} ref={inner} style={innerStyle}>
// {value.map((item, index) => {
// let color = '';
// if (options && Array.isArray(options) && options.length > 0) {
// const obj = options.find((ls) => ls.id === item.value) || {};
// color = obj.color || 'e9eef9';
// }
// return (
// <span
// key={index}
// className={classNames(s.item, mode === 'multiple' && s.multi)}
// style={{ ...itemStyle, background: `#${color}` }}
// >
// <div className={s.itemBgTxt}>{item.text}</div>
// </span>
// );
// })}
// </div>
// </div>
// )}
// </div>
);
};
export default Tags;
......@@ -11,13 +11,14 @@ interface State {
}
export default function CellContainer<P extends Props>(Comp) {
return class extends React.Component<P & Props, State> {
container: any;
constructor(props) {
super(props);
this.state = {
value: props.value, // 组件的值
option: undefined, // 选择项
};
console.log('props.value', props.value);
this.container = React.createRef();
}
componentDidMount(): void {
document.addEventListener('click', this.onBlur, false);
......@@ -26,30 +27,49 @@ export default function CellContainer<P extends Props>(Comp) {
document.removeEventListener('click', this.onBlur, false);
}
changeValue = (value: any, option: any) => {
console.log('value', value);
this.setState({ value, option });
};
onBlur = () => {
onBlur = (e: any) => {
let currTarget = e.target;
while (currTarget != document) {
let editing = currTarget.getAttribute('data-editingCell');
// 当前点击div是正在编辑的cell时,阻止修改回调
if (editing === '1') {
return;
}
currTarget = currTarget.parentNode;
}
const { onEmitChange } = this.props;
const { value, option } = this.state;
console.log('state.value', value);
if (typeof onEmitChange === 'function') {
onEmitChange(value, option);
// 清除所有dom的编辑状态
const doms = document.querySelectorAll('.cellUnit');
if (doms) {
doms.forEach((item) => {
item.setAttribute('data-editingCell', '0');
});
}
}
};
onClick = (e) => {
e.stopPropagation(); //阻止事件冒泡
e.nativeEvent.stopImmediatePropagation();
};
render() {
const selfProps = antiAssign(this.props, ['onEmitChange', 'onChange', 'value']);
const { value } = this.state;
// cellContainer默认将组件中的全局弹框挂载到当前cell上
return (
<div className={s.container} onClick={this.onClick}>
<div className={s.container} ref={this.container}>
<Comp
{...selfProps}
value={value}
onChange={this.changeValue}
getPopupContainer={() => {
return this.container.current;
}}
getCalendarContainer={() => {
return this.container.current;
}}
/>
</div>
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment