Commit ff47a1cb authored by zhangwenshuai's avatar zhangwenshuai

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

parent 1acd88f6
...@@ -10,27 +10,25 @@ ...@@ -10,27 +10,25 @@
height: 100%; height: 100%;
font-size: @textFontGen; font-size: @textFontGen;
padding: 0 @paddingLg; padding: 0 @paddingLg;
&.hover { //&.hover {
background: @tableHoverBgColor; // background: @tableHoverBgColor;
.checkbox { // .checkbox {
display: block; // display: block;
&.hasNum { // &.hasNum {
display: block; // display: block;
} // }
} // }
.num { // .num {
display: block; // display: block;
&.hasCheckbox { // &.hasCheckbox {
display: none; // display: none;
} // }
} // }
.expand { // .expand {
visibility: visible; // visibility: visible;
} // }
} //}
&.selected {
box-shadow: inset 0 0 0 1px @primaryColor;
}
.num { .num {
min-width: 30px; min-width: 30px;
max-width: 100px; max-width: 100px;
...@@ -38,7 +36,7 @@ ...@@ -38,7 +36,7 @@
.icon { .icon {
width: 22px; width: 22px;
} }
&.checked{ &.checked {
display: none; display: none;
} }
} }
...@@ -49,7 +47,7 @@ ...@@ -49,7 +47,7 @@
&.hasNum { &.hasNum {
display: none; display: none;
} }
&.checked{ &.checked {
display: block; display: block;
} }
} }
...@@ -94,3 +92,26 @@ ...@@ -94,3 +92,26 @@
background: #333333; 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 { Checkbox, message, Popover } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import _ from 'lodash'; import _ from 'lodash';
...@@ -33,10 +33,6 @@ const Cell = (props: CellProps) => { ...@@ -33,10 +33,6 @@ const Cell = (props: CellProps) => {
rowSelection, rowSelection,
columns, columns,
contentMenu, contentMenu,
selectedCell,
cellKey,
changeSelectedCell,
position = 'center',
} = props; } = props;
const { const {
columnType, columnType,
...@@ -47,6 +43,7 @@ const Cell = (props: CellProps) => { ...@@ -47,6 +43,7 @@ const Cell = (props: CellProps) => {
cellRenderProps, cellRenderProps,
readOnlyFlag, readOnlyFlag,
} = columnConfig; } = columnConfig;
const cellUnit = useRef(null);
const [status, setStatus] = useState('detail'); const [status, setStatus] = useState('detail');
useEffect(() => { useEffect(() => {
...@@ -119,6 +116,7 @@ const Cell = (props: CellProps) => { ...@@ -119,6 +116,7 @@ const Cell = (props: CellProps) => {
}; };
const selfRenderDetailCell = () => { const selfRenderDetailCell = () => {
// 数据为空
let empty = let empty =
!cellData || cellData.length === 0 || (cellData.length === 1 && !cellData[0].text && !cellData[0].value); !cellData || cellData.length === 0 || (cellData.length === 1 && !cellData[0].text && !cellData[0].value);
let detailConfig; let detailConfig;
...@@ -138,7 +136,7 @@ const Cell = (props: CellProps) => { ...@@ -138,7 +136,7 @@ const Cell = (props: CellProps) => {
const style: any = {}; const style: any = {};
const { current = 1, pageSize = 20 } = paginationConfig || {}; const { current = 1, pageSize = 20 } = paginationConfig || {};
// 构造序号
const getIndex = () => { const getIndex = () => {
// if (current === 1) { // if (current === 1) {
// let src = ''; // let src = '';
...@@ -159,6 +157,7 @@ const Cell = (props: CellProps) => { ...@@ -159,6 +157,7 @@ const Cell = (props: CellProps) => {
// } // }
return (current - 1) * pageSize + rowIndex + 1; return (current - 1) * pageSize + rowIndex + 1;
}; };
// 获取当前行在所选列表中的index
const getCheckedIndex = () => { const getCheckedIndex = () => {
if (!rowSelection) { if (!rowSelection) {
return -1; return -1;
...@@ -171,6 +170,7 @@ const Cell = (props: CellProps) => { ...@@ -171,6 +170,7 @@ const Cell = (props: CellProps) => {
}); });
return index; return index;
}; };
// 构造行复选框
const getCheckbox = () => { const getCheckbox = () => {
const { selectedRows, onChange } = rowSelection; const { selectedRows, onChange } = rowSelection;
const index = getCheckedIndex(); const index = getCheckedIndex();
...@@ -190,25 +190,43 @@ const Cell = (props: CellProps) => { ...@@ -190,25 +190,43 @@ const Cell = (props: CellProps) => {
}; };
const { dynamicCellConfigDTO } = columnData; const { dynamicCellConfigDTO } = columnData;
const detail = ( const detail = (
<div <div
onMouseEnter={onMouseEnter} className={s.detailCell}
onMouseLeave={onMouseLeave}
className={
selectedCell === `${position}_${cellKey}`
? classNames(`row_${rowIndex}`, `col_${columnIndex}`, s.detailCell, s.selected)
: classNames(`row_${rowIndex}`, `col_${columnIndex}`, s.detailCell)
}
onClick={() => { onClick={() => {
// 不可编辑状态 // 不可编辑状态
if (!cellEditable || readOnlyFlag || (dynamicCellConfigDTO && dynamicCellConfigDTO.readonlyFlag)) { if (!cellEditable || readOnlyFlag || (dynamicCellConfigDTO && dynamicCellConfigDTO.readonlyFlag)) {
return false; 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'); setStatus('edit');
if (dom) {
// 给当前dom添加编辑状态
dom.setAttribute('data-editingCell', '1');
}
} else { } 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} style={style}
...@@ -324,7 +342,16 @@ const Cell = (props: CellProps) => { ...@@ -324,7 +342,16 @@ const Cell = (props: CellProps) => {
}; };
return ( 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 === 'detail' && selfRenderDetailCell()}
{status === 'edit' && selfRenderEditCell()} {status === 'edit' && selfRenderEditCell()}
</div> </div>
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
position: absolute; position: absolute;
right: 0; right: 0;
z-index: 1; z-index: 1;
overflow: hidden;
} }
:global(.ReactVirtualized__Grid__innerScrollContainer) { :global(.ReactVirtualized__Grid__innerScrollContainer) {
overflow: unset !important; overflow: unset !important;
......
...@@ -677,6 +677,7 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -677,6 +677,7 @@ export default class AirTable extends Component<TableProps, TableState> {
position: 'absolute', position: 'absolute',
right: 0, right: 0,
top: headerHeight, top: headerHeight,
marginRight: -scrollbarWidth,
}} }}
> >
<Grid <Grid
...@@ -694,8 +695,12 @@ export default class AirTable extends Component<TableProps, TableState> { ...@@ -694,8 +695,12 @@ export default class AirTable extends Component<TableProps, TableState> {
columns: showColumns, columns: showColumns,
showColumns: rightColumns, showColumns: rightColumns,
})} })}
onScroll={(...arg: Array<Object>) => {
onScroll({ scrollTop: arg[0].scrollTop });
this.onScroll(arg[0]);
}}
columnCount={rightCount} columnCount={rightCount}
width={rightWidth} width={rightWidth + scrollbarWidth}
rowHeight={rowHeight} rowHeight={rowHeight}
rowCount={rowCount} rowCount={rowCount}
height={totalHeight - scrollbarWidth} height={totalHeight - scrollbarWidth}
......
...@@ -32,7 +32,31 @@ export const Tags = (props: any) => { ...@@ -32,7 +32,31 @@ export const Tags = (props: any) => {
itemStyle.marginBottom = '5px'; itemStyle.marginBottom = '5px';
} }
return ( return (
<div className={s.container}> <div className={s.container}>
{dotVisible && mode === 'multiple' && (
<Popover
placement="left"
overlayClassName={s.popContainer}
content={
<div
className={s.popContent}
>
{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.outContainer} ref={outer} style={outStyle}>
<div className={s.innerContainer} ref={inner} style={innerStyle}> <div className={s.innerContainer} ref={inner} style={innerStyle}>
{value.map((item, index) => { {value.map((item, index) => {
...@@ -44,7 +68,7 @@ export const Tags = (props: any) => { ...@@ -44,7 +68,7 @@ export const Tags = (props: any) => {
return ( return (
<span <span
key={index} key={index}
className={mode === 'multiple' ? classNames(s.item, s.multi) : s.item} className={classNames(s.item, mode === 'multiple' && s.multi)}
style={{ ...itemStyle, background: `#${color}` }} style={{ ...itemStyle, background: `#${color}` }}
> >
<div className={s.itemBgTxt}>{item.text}</div> <div className={s.itemBgTxt}>{item.text}</div>
...@@ -53,21 +77,11 @@ export const Tags = (props: any) => { ...@@ -53,21 +77,11 @@ export const Tags = (props: any) => {
})} })}
</div> </div>
</div> </div>
{dotVisible && mode === 'multiple' && ( </Popover>
<Popover )}
trigger="click" {!dotVisible && (
onClick={(e) => { <div className={s.outContainer} ref={outer} style={outStyle}>
e.stopPropagation(); <div className={s.innerContainer} ref={inner} style={innerStyle}>
}}
placement="left"
overlayClassName={s.popContainer}
content={
<div
className={s.popContent}
onClick={(e) => {
e.stopPropagation();
}}
>
{value.map((item, index) => { {value.map((item, index) => {
let color = ''; let color = '';
if (options && Array.isArray(options) && options.length > 0) { if (options && Array.isArray(options) && options.length > 0) {
...@@ -75,99 +89,19 @@ export const Tags = (props: any) => { ...@@ -75,99 +89,19 @@ export const Tags = (props: any) => {
color = obj.color || 'e9eef9'; color = obj.color || 'e9eef9';
} }
return ( return (
<span className={s.popItem} key={index} style={{ background: `#${color}` }}> <span
<div className={s.popItemBgTxt}>{item.text}</div> key={index}
className={classNames(s.item, mode === 'multiple' && s.multi)}
style={{ ...itemStyle, background: `#${color}` }}
>
<div className={s.itemBgTxt}>{item.text}</div>
</span> </span>
); );
})} })}
</div> </div>
}
>
<div className={s.moreBtn}>
<IconFont type="iconzhankai1" />
</div> </div>
</Popover>
)} )}
</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; export default Tags;
...@@ -11,13 +11,14 @@ interface State { ...@@ -11,13 +11,14 @@ interface State {
} }
export default function CellContainer<P extends Props>(Comp) { export default function CellContainer<P extends Props>(Comp) {
return class extends React.Component<P & Props, State> { return class extends React.Component<P & Props, State> {
container: any;
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
value: props.value, // 组件的值 value: props.value, // 组件的值
option: undefined, // 选择项 option: undefined, // 选择项
}; };
console.log('props.value', props.value); this.container = React.createRef();
} }
componentDidMount(): void { componentDidMount(): void {
document.addEventListener('click', this.onBlur, false); document.addEventListener('click', this.onBlur, false);
...@@ -26,30 +27,49 @@ export default function CellContainer<P extends Props>(Comp) { ...@@ -26,30 +27,49 @@ export default function CellContainer<P extends Props>(Comp) {
document.removeEventListener('click', this.onBlur, false); document.removeEventListener('click', this.onBlur, false);
} }
changeValue = (value: any, option: any) => { changeValue = (value: any, option: any) => {
console.log('value', value);
this.setState({ value, option }); 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 { onEmitChange } = this.props;
const { value, option } = this.state; const { value, option } = this.state;
console.log('state.value', value);
if (typeof onEmitChange === 'function') { if (typeof onEmitChange === 'function') {
onEmitChange(value, option); 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() { render() {
const selfProps = antiAssign(this.props, ['onEmitChange', 'onChange', 'value']); const selfProps = antiAssign(this.props, ['onEmitChange', 'onChange', 'value']);
const { value } = this.state; const { value } = this.state;
// cellContainer默认将组件中的全局弹框挂载到当前cell上
return ( return (
<div className={s.container} onClick={this.onClick}> <div className={s.container} ref={this.container}>
<Comp <Comp
{...selfProps} {...selfProps}
value={value} value={value}
onChange={this.changeValue} onChange={this.changeValue}
getPopupContainer={() => {
return this.container.current;
}}
getCalendarContainer={() => {
return this.container.current;
}}
/> />
</div> </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