Commit 2019b548 by zhaochengxiang

加工步骤

parent 163e170d
......@@ -3,4 +3,5 @@ import React from 'react';
export const EditModelContext = React.createContext({
attrIsEditingFunction: null,
indexIsEditingFunction: null,
processIsEditingFunction: null,
});
\ No newline at end of file
......@@ -13,6 +13,7 @@ import { Action } from '../../../../util/constant';
import { dispatch } from '../../../../model';
import './ImportAction.less'
import ImportActionProcess from './ImportActionProcess';
const ImportAction = React.forwardRef((props, ref) => {
const { action, hints, onChange, form, modelerId, terms, ddl, roughModelerData, versionId, permitCheckOut, catalogId, logicId, metadataId } = props;
......@@ -139,6 +140,7 @@ const ImportAction = React.forwardRef((props, ref) => {
'model-import-action-technical',
'model-import-action-table',
'model-import-action-index',
'model-import-action-process',
'model-import-action-manage',
// 'model-import-action-relation',
'model-import-action-comment',
......@@ -539,6 +541,19 @@ const ImportAction = React.forwardRef((props, ref) => {
}
}
const onProcessChange = (data, validate=false) => {
const newModelerData = {...modelerDataRef.current, processingList: data};
setModelerData(newModelerData);
modelerDataRef.current = newModelerData;
onChange && onChange(newModelerData);
if (validate) {
validateDataModel(newModelerData);
}
}
const getConsistentKeys = (newModelerData) => {
//分布键
......@@ -624,6 +639,7 @@ const ImportAction = React.forwardRef((props, ref) => {
<Tabs.TabPane tab='技术信息' key="model-import-action-technical" />
<Tabs.TabPane tab='数据表结构' key="model-import-action-table" />
<Tabs.TabPane tab='数据表索引' key="model-import-action-index" />
<Tabs.TabPane tab='加工步骤' key="model-import-action-process" />
<Tabs.TabPane tab='管理信息' key="model-import-action-manage" />
{/* <Tabs.TabPane tab='关联对象' key="model-import-action-relation" /> */}
{
......@@ -666,6 +682,14 @@ const ImportAction = React.forwardRef((props, ref) => {
editable={action!=='detail'&&action!=='flow'&&action!=='detail-version'&&action!=='edit-inherited'}
terms={terms}
/>
<ImportActionProcess
modelerData={modelerData||{}}
constraint={constraint}
template={template}
onChange={onProcessChange}
editable={action!=='detail'&&action!=='flow'&&action!=='detail-version'&&action!=='edit-inherited'}
terms={terms}
/>
<ImportActionManage
form={form}
modelerData={modelerData||{}}
......
......@@ -196,7 +196,7 @@ const AttributesInput = ({ value = {}, attributes, onChange }) => {
)
}
const EditableCell = ({
export const EditableCell = ({
editing,
dataIndex,
colTitle,
......@@ -285,7 +285,7 @@ const EditableCell = ({
);
};
const DragableBodyRow = ({ index, moveRow, className, style, ...restProps }) => {
export const DragableBodyRow = ({ index, moveRow, className, style, ...restProps }) => {
const ref = useRef();
const [{ isOver, dropClassName }, drop] = useDrop(
......
import React, { useState, useCallback, useRef, useEffect, useContext, useMemo } from 'react';
import { Input, Form, Typography, Button, Select, Row, Col, Popover, Checkbox, Tooltip, Table, Space } from 'antd';
import { DeleteOutlined, CloseOutlined, CheckOutlined, PlusOutlined, QuestionCircleOutlined, DownOutlined, UpOutlined } from '@ant-design/icons';
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import update from 'immutability-helper';
import { useClickAway } from 'ahooks';
import { useContextMenu, Menu as RcMenu, Item as RcItem } from "react-contexify";
import DebounceInput from './DebounceInput';
import { addEventListenerForSidebar, removeEventListenerForSidebar } from './Help';
import { showMessage, highlightSearchContentByTerms, inputWidth } from '../../../../util';
import { EditModelContext } from './ContextManage';
import { ValidateTip } from './ImportActionHeader';
import { DragableBodyRow, EditableCell } from './ImportActionIndex';
const { Option } = Select;
const type = 'DragableProcessBodyRow';
const MENU_ID = 'model-process-menu';
const InputDebounce = DebounceInput(300)(Input);
const ImportActionProcess = (props) => {
const { modelerData, onChange, editable, terms, constraint, template } = props;
const [data, setData] = useState([]);
const [ filterData, setFilterData ] = useState([]);
const [form] = Form.useForm();
const [editingKey, setEditingKey] = useState(null);
const [ keywordCondition, setKeywordCondition ] = useState({ keyword: '', needFilter: true });
const { keyword, needFilter } = keywordCondition;
const [insertIndex, setInsertIndex] = useState(0);
const [ currentItem, setCurrentItem ] = useState(null);
const [isCollapse, setCollapse] = useState(true);
const { processIsEditingFunction } = useContext(EditModelContext);
const dataRef = useRef();
const tableRef = useRef(null);
const termsRef = useRef(null);
const { show } = useContextMenu({
id: MENU_ID,
});
useClickAway(() => {
save();
}, tableRef);
useEffect(() => {
processIsEditingFunction && processIsEditingFunction(editingKey);
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [ editingKey ])
//规则改变的时候 数据表为可编辑状态
useEffect(() => {
setEditingKey(null);
}, [constraint, template, modelerData])
useEffect(() => {
termsRef.current = terms;
setData(modelerData.processingList||[]);
dataRef.current = (modelerData.processingList||[]);
setFilterData(
(modelerData.processingList||[]).filter(item =>
!keyword || (item.sequenceNumber||'').indexOf(keyword)!==-1 || (item.name||'').indexOf(keyword)!==-1 || (item.remark||'').indexOf(keyword)!==-1
));
}, [modelerData, terms])
useEffect(() => {
if (needFilter) {
setFilterData(
(modelerData.processingList||[]).filter(item =>
!keyword || (item.sequenceNumber||'').indexOf(keyword)!==-1 || (item.name||'').indexOf(keyword)!==-1 || (item.remark||'').indexOf(keyword)!==-1
));
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [keywordCondition])
const menuData = useMemo(() => {
return [
{ title: '在上方插入行', key: 'up' },
{ title: '在下方插入行', key: 'down' },
{ title: '删除', key: 'delete' },
]
}, [])
const isEditing = (record) => record.sequenceNumber === editingKey;
const onAddClick = (event) => {
event.stopPropagation();
save().then(result => {
if (result) {
setKeywordCondition({ keyword: '', needFilter: false });
const newData = [...dataRef.current??[], {sequenceNumber: ''}];
setFilterData(newData);
setInsertIndex(newData.length-1);
edit(newData[newData.length-1], false);
}
})
}
const onInsertToFrontClick = (record) => {
save().then(result => {
if (result) {
setKeywordCondition({ keyword: '', needFilter: false });
let newData = [...dataRef.current??[]];
const index = newData.findIndex((item) => record.sequenceNumber === item.sequenceNumber);
if (index === -1) {
if (insertIndex === 0) {
newData = [{sequenceNumber: ''}, ...newData];
edit(newData[0], false);
} else {
newData.splice(insertIndex, 0, {sequenceNumber: ''});
edit(newData[insertIndex], false);
}
} else if (index === 0) {
newData = [{sequenceNumber: ''}, ...newData];
setInsertIndex(0);
edit(newData[0], false);
} else {
newData.splice(index, 0, {sequenceNumber: ''});
setInsertIndex(index);
edit(newData[index], false);
}
setFilterData(newData);
}
})
}
const onInsertToBackClick = (record) => {
save().then(result => {
if (result) {
setKeywordCondition({ keyword: '', needFilter: false });
const newData = [...dataRef.current];
const index = newData.findIndex((item) => record.sequenceNumber === item.sequenceNumber);
if (index === -1) {
newData.splice(insertIndex+1, 0, {sequenceNumber: ''});
setFilterData(newData);
setInsertIndex(insertIndex+1);
edit(newData[insertIndex+1], false);
} else {
newData.splice(index+1, 0, {sequenceNumber: ''});
setFilterData(newData);
setInsertIndex(index+1);
edit(newData[index+1], false);
}
}
})
}
const editLogic = (record) => {
form.resetFields();
form.setFieldsValue(record);
setEditingKey(record?.sequenceNumber);
}
const edit = (record, needSave = true) => {
if (needSave) {
save().then(result => {
if (result) {
editLogic(record);
}
})
} else {
editLogic(record);
}
};
const removeLogic = (record) => {
const newData = [...dataRef.current];
const index = newData.findIndex((item) => record.sequenceNumber === item.sequenceNumber);
if (index !== -1) {
newData.splice(index, 1);
}
onChange && onChange(newData);
}
const onRemoveClick = (record) => {
if (record.name === '') {
const newData = [...dataRef.current];
onChange && onChange(newData);
} else {
if (record.name !== editingKey) {
save().then(result => {
if (result) {
removeLogic(record);
}
})
} else {
removeLogic(record);
}
}
save().then(result => {
if (result) {
const newData = [...dataRef.current];
const index = newData.findIndex((item) => record.sequenceNumber === item.sequenceNumber);
if (index !== -1) {
newData.splice(index, 1);
}
onChange && onChange(newData);
}
})
}
const save = async() => {
try {
if (editingKey!==null) {
const row = await form.validateFields();
// console.log('row', row);
const newData = [...data];
const index = newData.findIndex((item) => editingKey === item.sequenceNumber);
let _index;
if (index === -1) {
_index = (data||[]).findIndex(item => item.sequenceNumber === row.sequenceNumber);
} else {
const newDataExcludeSelf = [...data];
newDataExcludeSelf.splice(index, 1);
_index = (newDataExcludeSelf||[]).findIndex(item => item.sequenceNumber === row.sequenceNumber);
}
if (_index !== -1) {
form.setFields([{ name: 'sequenceNumber', errors: ['加工步骤不能重复'] }]);
return;
}
if (index === -1) {
newData.splice(insertIndex, 0, row);
} else {
newData.splice(index, 1, row);
}
dataRef.current = newData;
onChange && onChange(newData, true);
setEditingKey(null);
}
return true;
} catch (errInfo) {
console.log('Validate Failed:', errInfo);
return false;
}
};
const onValuesChange = (changedValues, allValues) => {
// console.log('changed values', changedValues);
// console.log('all values', allValues);
};
const columns = [
{
title: '加载步骤',
dataIndex: 'sequenceNumber',
editable: true,
ellipsis: true,
require: true,
render: (_, record, __) => {
return (
<Tooltip title={record.sequenceNumber}>
<span >{highlightSearchContentByTerms(record.sequenceNumber, termsRef.current)}</span>
</Tooltip>
)
}
},
{
title: '加载表名',
dataIndex: 'name',
editable: true,
ellipsis: true,
require: true,
render: (_, record, __) => {
return (
<Tooltip title={record.name}>
<span >{highlightSearchContentByTerms(record.name, termsRef.current)}</span>
</Tooltip>
)
}
},
{
title: '步骤说明',
dataIndex: 'remark',
editable: true,
ellipsis: true,
require: true,
render: (_, record, __) => {
return (
<Tooltip title={record.remark}>
<span >{highlightSearchContentByTerms(record.remark, termsRef.current)}</span>
</Tooltip>
)
}
},
];
const mergedColumns = () => {
if (editable) {
return columns.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record) => ({
record,
dataIndex: col.dataIndex,
inputType: 'text',
colTitle: col.title,
editing: isEditing(record),
}),
};
});
}
return columns;
}
const moveRow = useCallback(
(dragIndex, hoverIndex) => {
const dragRow = dataRef.current[dragIndex];
const newData = update(dataRef.current, {
$splice: [
[dragIndex, 1],
[hoverIndex, 0, dragRow],
],
})
onChange && onChange(newData);
},
//eslint-disable-next-line react-hooks/exhaustive-deps
[dataRef.current, onChange],
);
const onSearchInputChange = (value) => {
setEditingKey(null);
setKeywordCondition({ keyword: value||'', needFilter: true });
}
const displayMenu = (e) => {
show(e);
}
const handleItemClick = ({ event, props, data, triggerEvent }) => {
const key = event.currentTarget.id;
if (key === 'up') {
onInsertToFrontClick(currentItem);
} else if (key === 'down') {
onInsertToBackClick(currentItem);
} else if (key === 'delete') {
onRemoveClick(currentItem);
}
}
return (
<div className='model-import-action-process' id='model-import-action-process'>
<div className='d-flex mb-3' style={{ justifyContent: 'space-between' }}>
<Space>
<h3 style={{ marginBottom: 0 }}>加工步骤</h3>
{
editable && <Popover content='点击行进行编辑,表格可以通过拖拽来排序'>
<QuestionCircleOutlined className='pointer' />
</Popover>
}
{
isCollapse ? <Button type='primary' size='small' onClick={() => {
setCollapse(!isCollapse)
}}>展开<DownOutlined /></Button> : <Button type='primary' size='small' onClick={() => {
setCollapse(!isCollapse)
}}>收起<UpOutlined /></Button>
}
</Space>
<Space>
{
editable && <Tooltip>
<Button onClick={onAddClick} >新建</Button>
</Tooltip>
}
<div className='d-flex' style={{ alignItems: 'center' }}>
<InputDebounce
placeholder="请输入关键字"
allowClear
value={keyword}
onChange={onSearchInputChange}
style={{ width: inputWidth }}
/>
</div>
</Space>
</div>
{
!isCollapse && <div className='mb-3' id="containerId" ref={tableRef}>
<DndProvider backend={HTML5Backend} >
<Form form={form} component={false} onValuesChange={onValuesChange}>
<Table
components={{
body: {
cell: EditableCell,
//编辑或者搜索状态下不允许拖动
row: (editable&&editingKey===null&&!keyword)?DragableBodyRow:null,
},
}}
onRow={(record, index) => {
let rowParams = {
index,
};
if (editable) {
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||[]}
columns={mergedColumns()}
size='small'
rowKey='name'
rowClassName="editable-row"
pagination={false}
sticky
/>
</Form>
</DndProvider>
</div>
}
<RcMenu id={MENU_ID} >
{
(menuData??[]).map(item => (
<RcItem key={item.key} id={item.key} onClick={handleItemClick}>
{item.title}
</RcItem>
))
}
</RcMenu>
</div>
);
}
export default ImportActionProcess;
\ No newline at end of file
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