Commit fe1235c7 by zhaochengxiang

字段编辑优化

parent 90483a08
...@@ -358,10 +358,10 @@ const ImportAction = (props) => { ...@@ -358,10 +358,10 @@ const ImportAction = (props) => {
const getAllNewKeysAfterTableChange = (newModelerData) => { const getAllNewKeysAfterTableChange = (newModelerData) => {
//分布键 //分布键
let newDistribution = [...(newModelerData.easyDataModelerDistributionKey||[])]; let newDistribution = [];
(newDistribution||[]).forEach((item, index) => { (newModelerData.easyDataModelerDistributionKey||[]).forEach((item, index) => {
const _index = (newModelerData.easyDataModelerDataModelAttributes||[]).findIndex(_item => item.name === _item.name); const _index = (newModelerData.easyDataModelerDataModelAttributes||[]).findIndex(_item => item.iid === _item.iid);
if (_index !== -1) { if (_index !== -1) {
newDistribution.push({...newModelerData.easyDataModelerDataModelAttributes[_index]}); newDistribution.push({...newModelerData.easyDataModelerDataModelAttributes[_index]});
...@@ -373,10 +373,10 @@ const ImportAction = (props) => { ...@@ -373,10 +373,10 @@ const ImportAction = (props) => {
} }
//主键 //主键
let newPrimary = [...(newModelerData.easyDataModelerPrimaryKey||[])]; let newPrimary = [];
(newPrimary||[]).forEach((item, index) => { (newModelerData.easyDataModelerPrimaryKey||[]).forEach((item, index) => {
const _index = (newModelerData.easyDataModelerDataModelAttributes||[]).findIndex(_item => item.name === _item.name); const _index = (newModelerData.easyDataModelerDataModelAttributes||[]).findIndex(_item => item.iid === _item.iid);
if (_index !== -1) { if (_index !== -1) {
newPrimary.push({...newModelerData.easyDataModelerDataModelAttributes[_index]}); newPrimary.push({...newModelerData.easyDataModelerDataModelAttributes[_index]});
...@@ -393,7 +393,7 @@ const ImportAction = (props) => { ...@@ -393,7 +393,7 @@ const ImportAction = (props) => {
const newKeys = []; const newKeys = [];
(newPartition.keys||[]).forEach((item, index) => { (newPartition.keys||[]).forEach((item, index) => {
const _index = (newModelerData.easyDataModelerDataModelAttributes||[]).findIndex(_item => item.name === _item.name); const _index = (newModelerData.easyDataModelerDataModelAttributes||[]).findIndex(_item => item.iid === _item.iid);
if (_index !== -1) { if (_index !== -1) {
newKeys.push({...newModelerData.easyDataModelerDataModelAttributes[_index]}); newKeys.push({...newModelerData.easyDataModelerDataModelAttributes[_index]});
...@@ -406,6 +406,21 @@ const ImportAction = (props) => { ...@@ -406,6 +406,21 @@ const ImportAction = (props) => {
newPartition = null; newPartition = null;
} }
//类主键
let newSemiPrimary = [];
(newModelerData.semiPrimaryKey||[]).forEach((item, index) => {
const _index = (newModelerData.easyDataModelerDataModelAttributes||[]).findIndex(_item => item.iid === _item.iid);
if (_index !== -1) {
newSemiPrimary.push({...newModelerData.easyDataModelerDataModelAttributes[_index]});
}
})
if ((newSemiPrimary||[]).length === 0) {
newSemiPrimary = null;
}
//索引 //索引
let newEasyDataModelerIndices = [...(newModelerData.easyDataModelerIndices||[])]; let newEasyDataModelerIndices = [...(newModelerData.easyDataModelerIndices||[])];
(newModelerData.easyDataModelerIndices||[]).forEach((easyDataModelerIndex, index) => { (newModelerData.easyDataModelerIndices||[]).forEach((easyDataModelerIndex, index) => {
...@@ -427,7 +442,7 @@ const ImportAction = (props) => { ...@@ -427,7 +442,7 @@ const ImportAction = (props) => {
newEasyDataModelerIndices = newEasyDataModelerIndices.filter(item => (item.indexedEasyDataModelAttributes||[]).length > 0); newEasyDataModelerIndices = newEasyDataModelerIndices.filter(item => (item.indexedEasyDataModelAttributes||[]).length > 0);
return { partition: newPartition, easyDataModelerDistributionKey: newDistribution, easyDataModelerPrimaryKey: newPrimary, easyDataModelerIndices: newEasyDataModelerIndices }; return { partition: newPartition, easyDataModelerDistributionKey: newDistribution, easyDataModelerPrimaryKey: newPrimary, easyDataModelerIndices: newEasyDataModelerIndices, semiPrimaryKey: newSemiPrimary};
} }
return ( return (
......
...@@ -82,7 +82,7 @@ const TemplateSelect = ({ value = {}, templates = [], onChange, ...restProps }) ...@@ -82,7 +82,7 @@ const TemplateSelect = ({ value = {}, templates = [], onChange, ...restProps })
const AttributesSelect = ({ value = [], modelerData, onChange, ...restProps }) => { const AttributesSelect = ({ value = [], modelerData, onChange, ...restProps }) => {
const onAttributeChange = (value) => { const onAttributeChange = (value) => {
const currentAttributes = (modelerData?.easyDataModelerDataModelAttributes||[]).filter(attribute => (value||[]).indexOf(attribute.name)!==-1); const currentAttributes = (modelerData?.easyDataModelerDataModelAttributes||[]).filter(attribute => (value||[]).indexOf(attribute.iid)!==-1);
triggerChange(currentAttributes); triggerChange(currentAttributes);
} }
...@@ -94,15 +94,15 @@ const AttributesSelect = ({ value = [], modelerData, onChange, ...restProps }) = ...@@ -94,15 +94,15 @@ const AttributesSelect = ({ value = [], modelerData, onChange, ...restProps }) =
//value有可能为空 //value有可能为空
value = value ? value: []; value = value ? value: [];
let attributeNames = []; let attributeIds = [];
value.forEach(attribute => { value.forEach(attribute => {
attributeNames.push(attribute.name); attributeIds.push(attribute.iid);
}) })
return ( return (
<Select <Select
onChange={(value) => { onAttributeChange && onAttributeChange(value) }} onChange={(value) => { onAttributeChange && onAttributeChange(value) }}
value={attributeNames} value={attributeIds}
placeholder='请选择字段名称' placeholder='请选择字段名称'
style={{ width: 300 }} style={{ width: 300 }}
mode='multiple' mode='multiple'
...@@ -111,7 +111,7 @@ const AttributesSelect = ({ value = [], modelerData, onChange, ...restProps }) = ...@@ -111,7 +111,7 @@ const AttributesSelect = ({ value = [], modelerData, onChange, ...restProps }) =
{ {
(modelerData?.easyDataModelerDataModelAttributes||[]).map((attribute, index) => { (modelerData?.easyDataModelerDataModelAttributes||[]).map((attribute, index) => {
return ( return (
<Option key={index} value={attribute.name||''}>{attribute.name||''}</Option> <Option key={index} value={attribute.iid||''}>{attribute.name||''}</Option>
); );
}) })
} }
...@@ -134,7 +134,7 @@ const PartitionSelect = ({ value = {}, modelerData, partitionTypes = [], onChang ...@@ -134,7 +134,7 @@ const PartitionSelect = ({ value = {}, modelerData, partitionTypes = [], onChang
} }
const onAttributeChange = (value) => { const onAttributeChange = (value) => {
const currentAttributes = (modelerData?.easyDataModelerDataModelAttributes||[]).filter(attribute => (value||[]).indexOf(attribute.name)!==-1); const currentAttributes = (modelerData?.easyDataModelerDataModelAttributes||[]).filter(attribute => (value||[]).indexOf(attribute.iid)!==-1);
triggerChange({ keys: currentAttributes }); triggerChange({ keys: currentAttributes });
} }
...@@ -149,9 +149,9 @@ const PartitionSelect = ({ value = {}, modelerData, partitionTypes = [], onChang ...@@ -149,9 +149,9 @@ const PartitionSelect = ({ value = {}, modelerData, partitionTypes = [], onChang
//value有可能为空 //value有可能为空
value = value ? value: {}; value = value ? value: {};
let attributeNames = []; let attributeIds = [];
(value?.keys||[]).forEach(attribute => { (value?.keys||[]).forEach(attribute => {
attributeNames.push(attribute.name); attributeIds.push(attribute.iid);
}) })
return ( return (
...@@ -173,7 +173,7 @@ const PartitionSelect = ({ value = {}, modelerData, partitionTypes = [], onChang ...@@ -173,7 +173,7 @@ const PartitionSelect = ({ value = {}, modelerData, partitionTypes = [], onChang
</Select> </Select>
<Select <Select
onChange={(value) => { onAttributeChange && onAttributeChange(value) }} onChange={(value) => { onAttributeChange && onAttributeChange(value) }}
value={attributeNames} value={attributeIds}
placeholder='请选择字段名称' placeholder='请选择字段名称'
style={{ width: 200, marginLeft: 5 }} style={{ width: 200, marginLeft: 5 }}
mode='multiple' mode='multiple'
...@@ -182,7 +182,7 @@ const PartitionSelect = ({ value = {}, modelerData, partitionTypes = [], onChang ...@@ -182,7 +182,7 @@ const PartitionSelect = ({ value = {}, modelerData, partitionTypes = [], onChang
{ {
(modelerData?.easyDataModelerDataModelAttributes||[]).map((attribute, index) => { (modelerData?.easyDataModelerDataModelAttributes||[]).map((attribute, index) => {
return ( return (
<Option key={index} value={attribute.name||''}>{attribute.name||''}</Option> <Option key={index} value={attribute.iid||''}>{attribute.name||''}</Option>
); );
}) })
} }
...@@ -399,7 +399,7 @@ const ImportActionHeader = (props) => { ...@@ -399,7 +399,7 @@ const ImportActionHeader = (props) => {
setOnlyShowRequireChange(e.target.checked); setOnlyShowRequireChange(e.target.checked);
} }
let distributionDescription = '', primaryDescription = '', partitionsDescription = ''; let distributionDescription = '', primaryDescription = '', partitionsDescription = '', semiPrimaryDescription = '';
if (!editable && modelerData) { if (!editable && modelerData) {
//分布 //分布
...@@ -438,6 +438,17 @@ const ImportActionHeader = (props) => { ...@@ -438,6 +438,17 @@ const ImportActionHeader = (props) => {
if (modelerData?.partition?.partitionType?.name) { if (modelerData?.partition?.partitionType?.name) {
partitionsDescription += '/' + modelerData?.partition?.partitionType?.name||''; partitionsDescription += '/' + modelerData?.partition?.partitionType?.name||'';
} }
//类主键
if (modelerData?.semiPrimaryKey) {
(modelerData?.semiPrimaryKey||[]).forEach((item, index) => {
if (index > 0) {
semiPrimaryDescription += ',';
}
semiPrimaryDescription += item.name||'';
})
}
} }
return ( return (
...@@ -583,10 +594,10 @@ const ImportActionHeader = (props) => { ...@@ -583,10 +594,10 @@ const ImportActionHeader = (props) => {
<Col span={8}> <Col span={8}>
<Form.Item <Form.Item
label="类主键" label="类主键"
name="semiPrimaryKeysDescription" name="semiPrimaryKey"
labelAlign="left" labelAlign="left"
> >
<Input style={{ width: 300 }} /> <AttributesSelect modelerData={modelerData} />
</Form.Item> </Form.Item>
</Col> </Col>
</Row> </Row>
...@@ -650,7 +661,7 @@ const ImportActionHeader = (props) => { ...@@ -650,7 +661,7 @@ const ImportActionHeader = (props) => {
<Descriptions.Item label="分布键">{highlightSearchContentByTerms(distributionDescription||'', terms)}</Descriptions.Item> <Descriptions.Item label="分布键">{highlightSearchContentByTerms(distributionDescription||'', terms)}</Descriptions.Item>
<Descriptions.Item label="分区键">{highlightSearchContentByTerms(partitionsDescription||'', terms)}</Descriptions.Item> <Descriptions.Item label="分区键">{highlightSearchContentByTerms(partitionsDescription||'', terms)}</Descriptions.Item>
<Descriptions.Item label="主键">{highlightSearchContentByTerms(primaryDescription||'', terms)}</Descriptions.Item> <Descriptions.Item label="主键">{highlightSearchContentByTerms(primaryDescription||'', terms)}</Descriptions.Item>
<Descriptions.Item label="类主键">{highlightSearchContentByTerms(modelerData.semiPrimaryKeysDescription||'', terms)}</Descriptions.Item> <Descriptions.Item label="类主键">{highlightSearchContentByTerms(semiPrimaryDescription||'', terms)}</Descriptions.Item>
<Descriptions.Item label="加载方式">{highlightSearchContentByTerms(modelerData.dataLoadingStrategy||'', terms)}</Descriptions.Item> <Descriptions.Item label="加载方式">{highlightSearchContentByTerms(modelerData.dataLoadingStrategy||'', terms)}</Descriptions.Item>
<Descriptions.Item label="更新时间">{highlightSearchContentByTerms(modelerData.dataUpdatingTiming||'', terms)}</Descriptions.Item> <Descriptions.Item label="更新时间">{highlightSearchContentByTerms(modelerData.dataUpdatingTiming||'', terms)}</Descriptions.Item>
<Descriptions.Item label="维护历史">{highlightSearchContentByTerms(modelerData.maintenanceRecords||'', terms)}</Descriptions.Item> <Descriptions.Item label="维护历史">{highlightSearchContentByTerms(modelerData.maintenanceRecords||'', terms)}</Descriptions.Item>
......
...@@ -4,6 +4,8 @@ import { DeleteOutlined, CloseOutlined, CheckOutlined, PlusOutlined, MinusOutlin ...@@ -4,6 +4,8 @@ import { DeleteOutlined, CloseOutlined, CheckOutlined, PlusOutlined, MinusOutlin
import { DndProvider, useDrag, useDrop } from 'react-dnd'; import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend'; import { HTML5Backend } from 'react-dnd-html5-backend';
import update from 'immutability-helper'; import update from 'immutability-helper';
import { useClickAway } from 'ahooks';
import { useContextMenu, Menu as RcMenu, Item as RcItem } from "react-contexify";
import { addEventListenerForSidebar, removeEventListenerForSidebar } from './Help'; import { addEventListenerForSidebar, removeEventListenerForSidebar } from './Help';
import { showMessage, highlightSearchContentByTerms, inputWidth } from '../../../../util'; import { showMessage, highlightSearchContentByTerms, inputWidth } from '../../../../util';
...@@ -11,6 +13,7 @@ import { showMessage, highlightSearchContentByTerms, inputWidth } from '../../.. ...@@ -11,6 +13,7 @@ import { showMessage, highlightSearchContentByTerms, inputWidth } from '../../..
const { Option } = Select; const { Option } = Select;
const type = 'DragableIndexBodyRow'; const type = 'DragableIndexBodyRow';
const MENU_ID = 'model-index-menu';
const AttributesInputItem = ({ indexedAttribute = null, indexedAttributeOrder = null, attributes, onAttributeChange, onOrderChange, onDelete , className }) => { const AttributesInputItem = ({ indexedAttribute = null, indexedAttributeOrder = null, attributes, onAttributeChange, onOrderChange, onDelete , className }) => {
...@@ -20,6 +23,7 @@ const AttributesInputItem = ({ indexedAttribute = null, indexedAttributeOrder = ...@@ -20,6 +23,7 @@ const AttributesInputItem = ({ indexedAttribute = null, indexedAttributeOrder =
<span>字段名称:</span> <span>字段名称:</span>
</Col> </Col>
<Col span={6}> <Col span={6}>
<span onClick={e => e.stopPropagation()}>
<Select <Select
onChange={(value) => { onAttributeChange && onAttributeChange(value) }} onChange={(value) => { onAttributeChange && onAttributeChange(value) }}
value={indexedAttribute ? (indexedAttribute.name||'') : ''} value={indexedAttribute ? (indexedAttribute.name||'') : ''}
...@@ -33,12 +37,14 @@ const AttributesInputItem = ({ indexedAttribute = null, indexedAttributeOrder = ...@@ -33,12 +37,14 @@ const AttributesInputItem = ({ indexedAttribute = null, indexedAttributeOrder =
}) })
} }
</Select> </Select>
</span>
</Col> </Col>
<Col span={1}></Col> <Col span={1}></Col>
<Col span={2}> <Col span={2}>
<span>排序:</span> <span>排序:</span>
</Col> </Col>
<Col span={6}> <Col span={6}>
<span onClick={e => e.stopPropagation()}>
<Select <Select
onChange={(value) => { onOrderChange && onOrderChange(value) }} onChange={(value) => { onOrderChange && onOrderChange(value) }}
value={indexedAttributeOrder||''} value={indexedAttributeOrder||''}
...@@ -47,6 +53,7 @@ const AttributesInputItem = ({ indexedAttribute = null, indexedAttributeOrder = ...@@ -47,6 +53,7 @@ const AttributesInputItem = ({ indexedAttribute = null, indexedAttributeOrder =
<Option value='DESC'>DESC</Option> <Option value='DESC'>DESC</Option>
<Option value='ASC'>ASC</Option> <Option value='ASC'>ASC</Option>
</Select> </Select>
</span>
</Col> </Col>
<Col span={1}></Col> <Col span={1}></Col>
<Col span={1}> <Col span={1}>
...@@ -121,7 +128,7 @@ const AttributesInput = ({ value = {}, attributes, onChange }) => { ...@@ -121,7 +128,7 @@ const AttributesInput = ({ value = {}, attributes, onChange }) => {
}; };
return ( return (
<> <React.Fragment>
{ {
(indexedEasyDataModelAttributes||[]).map((indexedAttribute, index) => { (indexedEasyDataModelAttributes||[]).map((indexedAttribute, index) => {
return ( return (
...@@ -133,13 +140,16 @@ const AttributesInput = ({ value = {}, attributes, onChange }) => { ...@@ -133,13 +140,16 @@ const AttributesInput = ({ value = {}, attributes, onChange }) => {
attributes={attributes} attributes={attributes}
onAttributeChange={(value) => { onAttributeChange(value, index) } } onAttributeChange={(value) => { onAttributeChange(value, index) } }
onOrderChange={(value) => { onOrderChange(value, index) }} onOrderChange={(value) => { onOrderChange(value, index) }}
onDelete={() => { onItemDelete(index) }} onDelete={(event) => {
event.stopPropagation();
onItemDelete(index)
}}
/> />
); );
}) })
} }
<Button onClick={addAttribute}>新增字段</Button> <Button onClick={addAttribute}>新增字段</Button>
</> </React.Fragment>
) )
} }
...@@ -276,10 +286,21 @@ const ImportActionIndex = (props) => { ...@@ -276,10 +286,21 @@ const ImportActionIndex = (props) => {
const [ filterData, setFilterData ] = useState([]); const [ filterData, setFilterData ] = useState([]);
const [ insertIndex, setInsertIndex ] = useState(0); const [ insertIndex, setInsertIndex ] = useState(0);
const [ currentItem, setCurrentItem ] = useState(null);
const dataRef = useRef(); const dataRef = useRef();
dataRef.current = data; dataRef.current = data;
const tableRef = useRef(null);
const { show } = useContextMenu({
id: MENU_ID,
});
useClickAway(() => {
save();
}, tableRef);
//规则改变的时候 数据表为可编辑状态 //规则改变的时候 数据表为可编辑状态
useEffect(() => { useEffect(() => {
setEditingKey(null); setEditingKey(null);
...@@ -308,29 +329,79 @@ const ImportActionIndex = (props) => { ...@@ -308,29 +329,79 @@ const ImportActionIndex = (props) => {
const isEditing = (record) => record.name === editingKey; const isEditing = (record) => record.name === editingKey;
const onAddClick = () => { const onAddClick = (event) => {
event.stopPropagation();
save().then(result => {
if (result) {
const newData = [...dataRef.current, {name: ''}];
setFilterData(newData);
setInsertIndex(newData.length-1);
edit(newData[newData.length-1], false);
}
})
}
const insertToFront = (record) => {
save().then(result => {
const newFilterData = [...filterData, {name: ''}]; if (result) {
let newData = [...dataRef.current];
setFilterData(newFilterData); const index = newData.findIndex((item) => record.name === item.name);
setInsertIndex(newFilterData.length-1); if (index === -1) {
edit(newFilterData[newFilterData.length-1]);
if (insertIndex === 0) {
newData = [{name: ''}, ...newData];
edit(newData[0], false);
} else {
newData.splice(insertIndex, 0, {name: ''});
edit(newData[insertIndex], false);
} }
const insert = (record) => { } else if (index === 0) {
const newData = [...data]; newData = [{name: ''}, ...newData];
setInsertIndex(0);
edit(newData[0], false);
} else {
newData.splice(index, 0, {name: ''});
setInsertIndex(index);
edit(newData[index], false);
}
setFilterData(newData);
}
})
}
const insertToBack = (record) => {
save().then(result => {
if (result) {
const newData = [...dataRef.current];
const index = newData.findIndex((item) => record.name === item.name); const index = newData.findIndex((item) => record.name === item.name);
newData.splice(index+1, 0, {name: ''}); if (index === -1) {
newData.splice(insertIndex+1, 0, {name: ''});
setFilterData(newData);
setInsertIndex(insertIndex+1);
edit(newData[insertIndex+1], false);
} else {
newData.splice(index+1, 0, {name: ''});
setFilterData(newData); setFilterData(newData);
setInsertIndex(index+1); setInsertIndex(index+1);
edit(newData[index+1]); edit(newData[index+1], false);
}
}
})
} }
const edit = (record) => { const editLogic = (record) => {
form.setFieldsValue({ form.setFieldsValue({
name: '', name: '',
attributesWithOrders: { attributesWithOrders: {
...@@ -340,33 +411,39 @@ const ImportActionIndex = (props) => { ...@@ -340,33 +411,39 @@ const ImportActionIndex = (props) => {
unique: false, unique: false,
...record, ...record,
}); });
setEditingKey(record.name);
setEditingKey(record?.name);
}
const edit = (record, needSave = true) => {
if (needSave) {
save().then(result => {
if (result) {
editLogic(record);
}
})
} else {
editLogic(record);
}
}; };
const remove = (record) => { const remove = (record) => {
const newData = [...data]; const newData = [...data];
const index = newData.findIndex((item) => record.name === item.name); const index = newData.findIndex((item) => record.name === item.name);
if (index !== -1) {
newData.splice(index, 1); newData.splice(index, 1);
onChange && onChange(newData);
} }
const cancel = () => { onChange && onChange(newData);
const newFilterData = [...filterData];
const index = newFilterData.findIndex((item) => editingKey === item.name);
const item = newFilterData[index];
if (!item.name || item.name==='') {
newFilterData.splice(index, 1);
setFilterData(newFilterData);
}
setEditingKey(null); setEditingKey(null);
}; }
const save = async() => { const save = async() => {
try { try {
if (editingKey!==null) {
const row = await form.validateFields(); const row = await form.validateFields();
// console.log('row', row); // console.log('row', row);
...@@ -420,12 +497,18 @@ const ImportActionIndex = (props) => { ...@@ -420,12 +497,18 @@ const ImportActionIndex = (props) => {
}}); }});
} }
dataRef.current = newData;
onChange && onChange(newData, true); onChange && onChange(newData, true);
setEditingKey(null); setEditingKey(null);
}
return true;
} catch (errInfo) { } catch (errInfo) {
console.log('Validate Failed:', errInfo); console.log('Validate Failed:', errInfo);
return false;
} }
}; };
...@@ -515,35 +598,16 @@ const ImportActionIndex = (props) => { ...@@ -515,35 +598,16 @@ const ImportActionIndex = (props) => {
render: (_, record) => { render: (_, record) => {
if (!editable) return null; if (!editable) return null;
return isEditing(record) ? ( return (
<> <React.Fragment>
<Typography.Link className='mr-3' disabled={editingKey===null} onClick={(event) => {
event.preventDefault();
event.stopPropagation();
save();
}}>
保存
</Typography.Link>
<Typography.Link disabled={editingKey===null} onClick={(event) => {
event.preventDefault();
event.stopPropagation();
cancel();
}}>
取消
</Typography.Link>
</>
) : (
<>
<Button <Button
className='mr-3' className='mr-3'
size='small' size='small'
type='text' type='text'
icon={<PlusOutlined />} icon={<PlusOutlined />}
disabled={editingKey !== null}
onClick={(event) => { onClick={(event) => {
event.preventDefault();
event.stopPropagation(); event.stopPropagation();
insert(record); insertToFront(record);
}} }}
/> />
...@@ -552,15 +616,13 @@ const ImportActionIndex = (props) => { ...@@ -552,15 +616,13 @@ const ImportActionIndex = (props) => {
size='small' size='small'
type='text' type='text'
icon={<MinusOutlined />} icon={<MinusOutlined />}
disabled={editingKey !== null}
onClick={(event) => { onClick={(event) => {
event.preventDefault();
event.stopPropagation(); event.stopPropagation();
remove(record); remove(record);
}} }}
/> />
</> </React.Fragment>
); )
}, },
}, },
] ]
...@@ -682,14 +744,18 @@ const ImportActionIndex = (props) => { ...@@ -682,14 +744,18 @@ const ImportActionIndex = (props) => {
setKeyword(e.target.value||''); setKeyword(e.target.value||'');
} }
const onClickRowTriggerEdit = (record) => { const displayMenu = (e) => {
edit(record); show(e);
} }
let disableAdd = false, addTip = ''; const handleItemClick = ({ event, props, data, triggerEvent }) => {
if (editingKey!==null || keyword!=='') { const key = event.currentTarget.id;
disableAdd = true;
addTip = '正在搜索或者编辑中,不允许新建'; if (key === 'up') {
insertToFront(currentItem);
} else if (key === 'down') {
insertToBack(currentItem);
}
} }
return ( return (
...@@ -705,8 +771,8 @@ const ImportActionIndex = (props) => { ...@@ -705,8 +771,8 @@ const ImportActionIndex = (props) => {
</Space> </Space>
<Space> <Space>
{ {
editable && <Tooltip title={addTip}> editable && <Tooltip>
<Button onClick={onAddClick} disabled={disableAdd} >新建</Button> <Button onClick={onAddClick} >新建</Button>
</Tooltip> </Tooltip>
} }
<div className='d-flex' style={{ alignItems: 'center' }}> <div className='d-flex' style={{ alignItems: 'center' }}>
...@@ -720,7 +786,7 @@ const ImportActionIndex = (props) => { ...@@ -720,7 +786,7 @@ const ImportActionIndex = (props) => {
</div> </div>
</Space> </Space>
</div> </div>
<div className='mb-3' id="containerId"> <div className='mb-3' id="containerId" ref={tableRef}>
<DndProvider backend={HTML5Backend} > <DndProvider backend={HTML5Backend} >
<Form form={form} component={false} onValuesChange={onValuesChange}> <Form form={form} component={false} onValuesChange={onValuesChange}>
<Table <Table
...@@ -732,15 +798,31 @@ const ImportActionIndex = (props) => { ...@@ -732,15 +798,31 @@ const ImportActionIndex = (props) => {
}, },
}} }}
onRow={(record, index) => { onRow={(record, index) => {
if (!editable || editingKey!==null || keyword.length>0) return null; let rowParams = {
return {
index, index,
onClick: (event) => { };
onClickRowTriggerEdit(record);
}, if (editable) {
moveRow rowParams = {...rowParams, onContextMenu: event => {
setCurrentItem(record);
displayMenu(event);
} }
};
if (!isEditing(record)) {
rowParams = {...rowParams, onClick: (event) => {
event.stopPropagation();
edit(record);
}
}
if (keyword.length===0) {
rowParams = {...rowParams, moveRow};
}
}
}
return rowParams;
}} }}
dataSource={filterData||[]} dataSource={filterData||[]}
columns={mergedColumns()} columns={mergedColumns()}
...@@ -752,6 +834,15 @@ const ImportActionIndex = (props) => { ...@@ -752,6 +834,15 @@ const ImportActionIndex = (props) => {
/> />
</Form> </Form>
</DndProvider> </DndProvider>
<RcMenu id={MENU_ID} >
<RcItem id="up" onClick={handleItemClick}>
向上插入
</RcItem>
<RcItem id="down" onClick={handleItemClick}>
向下插入
</RcItem>
</RcMenu>
</div> </div>
</div> </div>
); );
......
...@@ -5,6 +5,7 @@ import { DndProvider, useDrag, useDrop } from 'react-dnd'; ...@@ -5,6 +5,7 @@ import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend'; import { HTML5Backend } from 'react-dnd-html5-backend';
import update from 'immutability-helper'; import update from 'immutability-helper';
import { useClickAway } from 'ahooks'; import { useClickAway } from 'ahooks';
import { useContextMenu, Menu as RcMenu, Item as RcItem } from "react-contexify";
import { generateUUID, highlightSearchContentByTerms, showMessage, inputWidth, paginate } from '../../../../util'; import { generateUUID, highlightSearchContentByTerms, showMessage, inputWidth, paginate } from '../../../../util';
import { dispatch, dispatchLatest } from '../../../../model'; import { dispatch, dispatchLatest } from '../../../../model';
...@@ -18,6 +19,7 @@ const { Option } = Select; ...@@ -18,6 +19,7 @@ const { Option } = Select;
const type = 'DragableTableBodyRow'; const type = 'DragableTableBodyRow';
const perSuggestCount = 5; const perSuggestCount = 5;
const supportMaxAttributeCountPerPage = 100; const supportMaxAttributeCountPerPage = 100;
const MENU_ID = 'model-attribute-menu';
const DatatypeInput = ({ value = {}, datatypes, onChange }) => { const DatatypeInput = ({ value = {}, datatypes, onChange }) => {
...@@ -251,12 +253,17 @@ const ImportActionTable = (props) => { ...@@ -251,12 +253,17 @@ const ImportActionTable = (props) => {
const [ filterPageData, setFilterPageData ] = useState([]); const [ filterPageData, setFilterPageData ] = useState([]);
const { pageNum, pageSize, filterData } = filterPageCondition; const { pageNum, pageSize, filterData } = filterPageCondition;
const [ insertIndex, setInsertIndex ] = useState(0); const [ insertIndex, setInsertIndex ] = useState(0);
const [ currentItem, setCurrentItem ] = useState(null);
const moveRowRef = useRef({ data, onChange, pageNum, pageSize }); const moveRowRef = useRef({ data, onChange, pageNum, pageSize });
const tableRef = useRef(null) const tableRef = useRef(null);
const { show } = useContextMenu({
id: MENU_ID,
});
useClickAway(() => { useClickAway(() => {
editItemPrevSave(); save();
}, tableRef); }, tableRef);
//规则改变的时候 数据表为可编辑状态 //规则改变的时候 数据表为可编辑状态
...@@ -292,8 +299,6 @@ const ImportActionTable = (props) => { ...@@ -292,8 +299,6 @@ const ImportActionTable = (props) => {
}, [keyword]) }, [keyword])
useEffect(() => { useEffect(() => {
moveRowRef.current.pageNum = pageNum; moveRowRef.current.pageNum = pageNum;
moveRowRef.current.pageSize = pageSize; moveRowRef.current.pageSize = pageSize;
...@@ -315,30 +320,61 @@ const ImportActionTable = (props) => { ...@@ -315,30 +320,61 @@ const ImportActionTable = (props) => {
const isEditing = (record) => record?.iid === editingKey; const isEditing = (record) => record?.iid === editingKey;
const onAddClick = () => { const onAddClick = (event) => {
event.stopPropagation();
save().then(result => {
if (result) {
const iid = generateUUID(); const iid = generateUUID();
const newFilterData = [...filterData, {iid}]; const newData = [...moveRowRef.current.data, {iid}];
if (newFilterData.length > supportMaxAttributeCountPerPage) { if (newData.length > supportMaxAttributeCountPerPage) {
const totalNum = parseInt(newFilterData.length/supportMaxAttributeCountPerPage) + ((newFilterData.length%supportMaxAttributeCountPerPage===0)?0:1); const totalNum = parseInt(newData.length/supportMaxAttributeCountPerPage) + ((newData.length%supportMaxAttributeCountPerPage===0)?0:1);
setFilterPageCondition({...filterPageCondition, ...{ filterData: newFilterData, pageNum: totalNum }}); setFilterPageCondition({...filterPageCondition, ...{ filterData: newData, pageNum: totalNum }});
} else { } else {
setFilterPageCondition({...filterPageCondition, ...{ filterData: newFilterData}}); setFilterPageCondition({...filterPageCondition, ...{ filterData: newData}});
} }
setInsertIndex(newFilterData.length-1); setInsertIndex(newData.length-1);
edit(newFilterData[newFilterData.length-1]); edit(newData[newData.length-1], false);
setTimeout(() => { setTimeout(() => {
document.getElementById(`field-${iid}`)?.scrollIntoView(); document.getElementById(`field-${iid}`)?.scrollIntoView();
}, 200) }, 200)
} }
})
}
const insert = (record) => { const insertToFront = (record) => {
const newData = [...data]; save().then(result => {
if (result) {
let newData = [...moveRowRef.current.data];
const index = newData.findIndex((item) => record.iid === item.iid);
const iid = generateUUID();
if (index === 0) {
newData = [{iid}, ...newData];
setInsertIndex(0);
edit(newData[0], false);
} else {
newData.splice(index, 0, {iid});
setInsertIndex(index);
edit(newData[index], false);
}
setFilterPageCondition({...filterPageCondition, ...{ filterData: newData}});
}
})
}
const insertToBack = (record) => {
save().then(result => {
if (result) {
const newData = [...moveRowRef.current.data];
const index = newData.findIndex((item) => record.iid === item.iid); const index = newData.findIndex((item) => record.iid === item.iid);
const iid = generateUUID(); const iid = generateUUID();
...@@ -346,10 +382,12 @@ const ImportActionTable = (props) => { ...@@ -346,10 +382,12 @@ const ImportActionTable = (props) => {
setFilterPageCondition({...filterPageCondition, ...{ filterData: newData}}); setFilterPageCondition({...filterPageCondition, ...{ filterData: newData}});
setInsertIndex(index+1); setInsertIndex(index+1);
edit(newData[index+1]); edit(newData[index+1], false);
}
})
} }
const edit = (record) => { const editLogic = (record) => {
form.setFieldsValue({ form.setFieldsValue({
name: '', name: '',
cnName: '', cnName: '',
...@@ -366,41 +404,46 @@ const ImportActionTable = (props) => { ...@@ -366,41 +404,46 @@ const ImportActionTable = (props) => {
...record, ...record,
}); });
setEditingKey(record.iid); console.log('record', record);
setAutoTranslate((record.name||'')==='');
if ((record.cnName||'')!=='') { setEditingKey(record?.iid);
onValuesChange({ cnName: record.cnName }, record, 1, record.iid); setAutoTranslate((record?.name||'')==='');
} else if ((record.name||'')!=='') {
onValuesChange({ name: record.name }, record, 1, record.iid); if ((record?.cnName||'')!=='') {
onValuesChange({ cnName: record?.cnName }, record, 1, record?.iid);
} else if ((record?.name||'')!=='') {
onValuesChange({ name: record?.name }, record, 1, record?.iid);
}
}
const edit = (record, needSave = true) => {
if (needSave) {
save().then((result) => {
editLogic(record);
});
} else {
editLogic(record);
} }
}; };
const remove = (record) => { const remove = (record) => {
const newData = [...data]; const newData = [...data];
const index = newData.findIndex((item) => record.iid === item.iid); const index = newData.findIndex((item) => record.iid === item.iid);
if (index !== -1) {
newData.splice(index, 1); newData.splice(index, 1);
onChange && onChange(newData);
} }
const cancel = () => { onChange && onChange(newData);
const newFilterData = [...filterData];
const _index = (data||[]).findIndex((item) => editingKey === item.iid);
const index = newFilterData.findIndex((item) => editingKey === item.iid);
const item = newFilterData[index];
if (_index===-1 && (!item.name || item.name==='')) {
newFilterData.splice(index, 1);
setFilterPageCondition({...filterPageCondition, filterData: newFilterData })
}
if (editingKey === record.iid) {
setEditingKey(''); setEditingKey('');
setSuggests([]); setSuggests([]);
setEnglishSuggests([]); setEnglishSuggests([]);
}; }
}
const editItemPrevSave = async(editNewItem = null) => { const save = async() => {
try { try {
...@@ -447,6 +490,8 @@ const ImportActionTable = (props) => { ...@@ -447,6 +490,8 @@ const ImportActionTable = (props) => {
newData.splice(index, 1, { ...item, ...row, modelingTemplateTag: null }); newData.splice(index, 1, { ...item, ...row, modelingTemplateTag: null });
} }
moveRowRef.current.data = newData;
onChange && onChange(newData, true); onChange && onChange(newData, true);
setEditingKey(''); setEditingKey('');
...@@ -454,12 +499,11 @@ const ImportActionTable = (props) => { ...@@ -454,12 +499,11 @@ const ImportActionTable = (props) => {
setEnglishSuggests([]); setEnglishSuggests([]);
} }
if (editNewItem) { return true;
edit(editNewItem);
}
} catch (errInfo) { } catch (errInfo) {
console.log('Validate Failed:', errInfo); console.log('Validate Failed:', errInfo);
return false;
} }
}; };
...@@ -824,7 +868,6 @@ const ImportActionTable = (props) => { ...@@ -824,7 +868,6 @@ const ImportActionTable = (props) => {
!isEditing(record) && <React.Fragment> !isEditing(record) && <React.Fragment>
{ {
record?.isPossibleNewRecommendedDefinition?.possible && <Typography.Link className='mr-3' onClick={(event) => { record?.isPossibleNewRecommendedDefinition?.possible && <Typography.Link className='mr-3' onClick={(event) => {
event.preventDefault();
event.stopPropagation(); event.stopPropagation();
value?.setGlobalState && value?.setGlobalState({ value?.setGlobalState && value?.setGlobalState({
message: 'data-govern-show-standard-create', message: 'data-govern-show-standard-create',
...@@ -839,7 +882,6 @@ const ImportActionTable = (props) => { ...@@ -839,7 +882,6 @@ const ImportActionTable = (props) => {
} }
{ {
record?.isPossibleNewTerm?.possible && <Typography.Link className='mr-3' onClick={(event) => { record?.isPossibleNewTerm?.possible && <Typography.Link className='mr-3' onClick={(event) => {
event.preventDefault();
event.stopPropagation(); event.stopPropagation();
value?.setGlobalState && value?.setGlobalState({ value?.setGlobalState && value?.setGlobalState({
message: 'data-govern-show-standard-create', message: 'data-govern-show-standard-create',
...@@ -863,11 +905,9 @@ const ImportActionTable = (props) => { ...@@ -863,11 +905,9 @@ const ImportActionTable = (props) => {
size='small' size='small'
type='text' type='text'
icon={<PlusOutlined />} icon={<PlusOutlined />}
disabled={editingKey !== ''}
onClick={(event) => { onClick={(event) => {
event.preventDefault();
event.stopPropagation(); event.stopPropagation();
insert(record); insertToFront(record);
}} }}
/> />
...@@ -876,9 +916,7 @@ const ImportActionTable = (props) => { ...@@ -876,9 +916,7 @@ const ImportActionTable = (props) => {
size='small' size='small'
type='text' type='text'
icon={<MinusOutlined />} icon={<MinusOutlined />}
disabled={editingKey !== ''}
onClick={(event) => { onClick={(event) => {
event.preventDefault();
event.stopPropagation(); event.stopPropagation();
remove(record); remove(record);
}} }}
...@@ -1055,14 +1093,18 @@ const ImportActionTable = (props) => { ...@@ -1055,14 +1093,18 @@ const ImportActionTable = (props) => {
onValuesChange(currentChangedValues, form.getFieldsValue(), suggestOffset); onValuesChange(currentChangedValues, form.getFieldsValue(), suggestOffset);
} }
const onClickRowTriggerEdit = (record) => { const displayMenu = (e) => {
edit(record); show(e);
} }
let disableAdd = false, addTip = ''; const handleItemClick = ({ event, props, data, triggerEvent }) => {
if (editingKey!=='' || keyword!=='') { const key = event.currentTarget.id;
disableAdd = true;
addTip = '正在搜索或者编辑中,不允许新建'; if (key === 'up') {
insertToFront(currentItem);
} else if (key === 'down') {
insertToBack(currentItem);
}
} }
return ( return (
...@@ -1078,8 +1120,8 @@ const ImportActionTable = (props) => { ...@@ -1078,8 +1120,8 @@ const ImportActionTable = (props) => {
</Space> </Space>
<Space> <Space>
{ {
editable && <Tooltip title={addTip}> editable && <Tooltip>
<Button onClick={onAddClick} disabled={disableAdd} >新建</Button> <Button onClick={onAddClick}>新建</Button>
</Tooltip> </Tooltip>
} }
<div className='d-flex' style={{ alignItems: 'center' }}> <div className='d-flex' style={{ alignItems: 'center' }}>
...@@ -1116,20 +1158,33 @@ const ImportActionTable = (props) => { ...@@ -1116,20 +1158,33 @@ const ImportActionTable = (props) => {
return 'editable-row'; return 'editable-row';
}} }}
onRow={(record, index) => { onRow={(record, index) => {
if (!editable || isEditing(record) || keyword.length>0) return {
id: `field-${record.iid}`,
};
return { let rowParams = {
index, index,
id: `field-${record.iid}`, id: `field-${record.iid}`,
onClick: (event) => { }
event.preventDefault();
if (editable) {
rowParams = {...rowParams, onContextMenu: event => {
setCurrentItem(record);
displayMenu(event);
}
};
if (!isEditing(record)) {
rowParams = {...rowParams, onClick: (event) => {
event.stopPropagation(); event.stopPropagation();
editItemPrevSave(record); edit(record);
},
moveRow
} }
}
if (keyword.length===0) {
rowParams = {...rowParams, moveRow};
}
}
}
return rowParams;
}} }}
dataSource={filterPageData||[]} dataSource={filterPageData||[]}
columns={mergedColumns()} columns={mergedColumns()}
...@@ -1214,6 +1269,15 @@ const ImportActionTable = (props) => { ...@@ -1214,6 +1269,15 @@ const ImportActionTable = (props) => {
/> />
} }
<RcMenu id={MENU_ID} >
<RcItem id="up" onClick={handleItemClick}>
向上插入
</RcItem>
<RcItem id="down" onClick={handleItemClick}>
向下插入
</RcItem>
</RcMenu>
</div> </div>
</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