Commit ab53a797 by zhaochengxiang

推荐更多

parent 502e002f
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
"react-dnd-html5-backend": "^14.0.0", "react-dnd-html5-backend": "^14.0.0",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
"react-redux": "^7.1.0", "react-redux": "^7.1.0",
"react-resizable": "^3.0.4",
"react-router-dom": "^5.0.1", "react-router-dom": "^5.0.1",
"react-scripts": "4.0.3", "react-scripts": "4.0.3",
"react-virtualized": "^9.22.3", "react-virtualized": "^9.22.3",
......
...@@ -126,3 +126,18 @@ tr.drop-over-downward td { ...@@ -126,3 +126,18 @@ tr.drop-over-downward td {
tr.drop-over-upward td { tr.drop-over-upward td {
border-top: 2px dashed #1890ff; border-top: 2px dashed #1890ff;
} }
.react-resizable {
position: relative;
background-clip: padding-box;
}
.react-resizable-handle {
position: absolute;
width: 10px;
height: 100%;
bottom: 0;
right: -5px;
cursor: col-resize;
z-index: 1;
}
\ No newline at end of file
...@@ -82,6 +82,10 @@ export function* recatalogDataModel(payload) { ...@@ -82,6 +82,10 @@ export function* recatalogDataModel(payload) {
return yield call(datamodelerService.recatalogDataModel, payload); return yield call(datamodelerService.recatalogDataModel, payload);
} }
export function* modelCopy(payload) {
return yield call(datamodelerService.modelCopy, payload);
}
export function* extractExcelContent(payload) { export function* extractExcelContent(payload) {
return yield call(datamodelerService.extractExcelContent, payload); return yield call(datamodelerService.extractExcelContent, payload);
} }
......
...@@ -39,6 +39,10 @@ export function recatalogDataModel(payload) { ...@@ -39,6 +39,10 @@ export function recatalogDataModel(payload) {
return PostJSON("/datamodeler/easyDataModelerCURD/recatalogDataModel", payload); return PostJSON("/datamodeler/easyDataModelerCURD/recatalogDataModel", payload);
} }
export function modelCopy(payload) {
return GetJSON("/datamodeler/easyDataModelerCURD/copy", payload);
}
export function extractExcelContent(payload) { export function extractExcelContent(payload) {
return PostFile("/datamodeler/easyDataModelerDesign/kickStart", payload); return PostFile("/datamodeler/easyDataModelerDesign/kickStart", payload);
} }
......
...@@ -137,18 +137,13 @@ const ImportAction = (props) => { ...@@ -137,18 +137,13 @@ const ImportAction = (props) => {
const getCurrentDataModel = () => { const getCurrentDataModel = () => {
dispatch({ dispatch({
type: 'datamodel.getDataModel', type: (action==='add') ? 'datamodel.modelCopy' : 'datamodel.getDataModel',
payload: { payload: {
id: modelerId||'' id: modelerId||''
}, },
callback: data => { callback: data => {
setLoading(false); setLoading(false);
//以现有模版新增时
if (action === 'add') {
data.id = null;
}
setModelerData(data||{}); setModelerData(data||{});
setConstraint(data.easyDataModelerModelingConstraint||{}); setConstraint(data.easyDataModelerModelingConstraint||{});
setTemplate(data.easyDataModelerModelingTemplate||{}); setTemplate(data.easyDataModelerModelingTemplate||{});
......
...@@ -171,7 +171,7 @@ const ImportActionHeader = (props) => { ...@@ -171,7 +171,7 @@ const ImportActionHeader = (props) => {
labelAlign="left" labelAlign="left"
rules={[{ required: true, message: '请输入中文名称!' }]} rules={[{ required: true, message: '请输入中文名称!' }]}
> >
<Input style={{ width: 200 }} /> <Input style={{ width: 300 }} />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={8}> <Col span={8}>
...@@ -181,7 +181,7 @@ const ImportActionHeader = (props) => { ...@@ -181,7 +181,7 @@ const ImportActionHeader = (props) => {
labelAlign="left" labelAlign="left"
rules={[{ required: true, message: '请输入英文名称!' }]} rules={[{ required: true, message: '请输入英文名称!' }]}
> >
<AutoComplete options={options} onSearch={onSearch} style={{ width: 200 }} /> <AutoComplete options={options} onSearch={onSearch} style={{ width: 300 }} />
{/* <Input /> */} {/* <Input /> */}
</Form.Item> </Form.Item>
</Col> </Col>
...@@ -192,7 +192,7 @@ const ImportActionHeader = (props) => { ...@@ -192,7 +192,7 @@ const ImportActionHeader = (props) => {
labelAlign="left" labelAlign="left"
rules={[{ required: true, message: '请输入描述!' }]} rules={[{ required: true, message: '请输入描述!' }]}
> >
<Input style={{ width: 200 }} /> <Input style={{ width: 300 }} />
</Form.Item> </Form.Item>
</Col> </Col>
</Row> </Row>
......
import React, { useState, useCallback, useRef, useEffect } from 'react'; import React, { useState, useCallback, useRef, useEffect } from 'react';
import { Table, Input, Form, Typography, Divider, Button, Select, Row, Col, Popover, Checkbox, Tooltip } from 'antd'; import { Input, Form, Typography, Divider, Button, Select, Row, Col, Popover, Checkbox, Tooltip } from 'antd';
import { QuestionCircleOutlined, DeleteOutlined, CloseOutlined, CheckOutlined } from '@ant-design/icons'; import { QuestionCircleOutlined, DeleteOutlined, CloseOutlined, CheckOutlined } from '@ant-design/icons';
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 ProTable from "@ant-design/pro-table";
import Helper from './Help'; import Helper from './Help';
import { showMessage, highlightSearchContentByTerms } from '../../../../util'; import { showMessage, highlightSearchContentByTerms } from '../../../../util';
...@@ -680,7 +681,7 @@ const ImportActionIndex = (props) => { ...@@ -680,7 +681,7 @@ const ImportActionIndex = (props) => {
<div id="containerId"> <div id="containerId">
<DndProvider backend={HTML5Backend} > <DndProvider backend={HTML5Backend} >
<Form form={form} component={false} onValuesChange={onValuesChange}> <Form form={form} component={false} onValuesChange={onValuesChange}>
<Table <ProTable
components={{ components={{
body: { body: {
cell: EditableCell, cell: EditableCell,
...@@ -702,6 +703,12 @@ const ImportActionIndex = (props) => { ...@@ -702,6 +703,12 @@ const ImportActionIndex = (props) => {
rowKey='name' rowKey='name'
rowClassName="editable-row" rowClassName="editable-row"
pagination={false} pagination={false}
search={false}
options={{
density: false,
setting: false,
reload: false,
}}
sticky sticky
/> />
</Form> </Form>
......
import React, { useState, useCallback, useRef, useEffect } from 'react'; import React, { useState, useCallback, useRef, useEffect } from 'react';
import { Table, Input, Form, Typography, Radio, Divider, Button, Popconfirm, Select, Row, Col, Popover, Checkbox } from 'antd'; import { Input, Form, Typography, Radio, Divider, Button, Popconfirm, Select, Row, Col, Popover, Checkbox } from 'antd';
import { QuestionCircleOutlined, CloseOutlined, CheckOutlined } from '@ant-design/icons'; import { QuestionCircleOutlined, CloseOutlined, CheckOutlined } from '@ant-design/icons';
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 ProTable from "@ant-design/pro-table";
import { generateUUID, highlightSearchContentByTerms, showMessage } from '../../../../util'; import { generateUUID, highlightSearchContentByTerms, showMessage } from '../../../../util';
import { dispatchLatest } from '../../../../model'; import { dispatchLatest } from '../../../../model';
...@@ -13,6 +14,7 @@ import './ImportActionTable.less'; ...@@ -13,6 +14,7 @@ import './ImportActionTable.less';
const { Option } = Select; const { Option } = Select;
const type = 'DragableTableBodyRow'; const type = 'DragableTableBodyRow';
const perSuggestCount = 5;
const DatatypeInput = ({ value = {}, datatypes, onChange }) => { const DatatypeInput = ({ value = {}, datatypes, onChange }) => {
...@@ -234,6 +236,9 @@ const ImportActionTable = (props) => { ...@@ -234,6 +236,9 @@ const ImportActionTable = (props) => {
const [ form ] = Form.useForm(); const [ form ] = Form.useForm();
const [ editingKey, setEditingKey ] = useState(''); const [ editingKey, setEditingKey ] = useState('');
const [ suggests, setSuggests ] = useState([]); const [ suggests, setSuggests ] = useState([]);
const [ suggestHaveMore, setSuggestHaveMore ] = useState(false);
const [ suggestOffset, setSuggestOffset ] = useState(1);
const [ currentChangedValues, setCurrentChangedValues] = useState({});
const [ englishSuggests, setEnglishSuggests ] = useState([]); const [ englishSuggests, setEnglishSuggests ] = useState([]);
const [ keyword, setKeyword ] = useState(''); const [ keyword, setKeyword ] = useState('');
...@@ -353,7 +358,7 @@ const ImportActionTable = (props) => { ...@@ -353,7 +358,7 @@ const ImportActionTable = (props) => {
} }
}; };
const onValuesChange = (changedValues, allValues) => { const onValuesChange = (changedValues, allValues, offset = 1) => {
// console.log('changed values', changedValues); // console.log('changed values', changedValues);
// console.log('all values', allValues); // console.log('all values', allValues);
...@@ -371,19 +376,42 @@ const ImportActionTable = (props) => { ...@@ -371,19 +376,42 @@ const ImportActionTable = (props) => {
newData.splice(index, 1, { ...item, ...allValues }); newData.splice(index, 1, { ...item, ...allValues });
} }
setSuggestHaveMore(false);
setCurrentChangedValues(changedValues);
dispatchLatest({ dispatchLatest({
type: 'datamodel.suggest', type: 'datamodel.suggest',
payload: { payload: {
data: { ...modelerData, easyDataModelerDataModelAttributes: newData }, data: { ...modelerData, easyDataModelerDataModelAttributes: newData },
params: { params: {
easyDataModelerDataModelAttributeIid: editingKey easyDataModelerDataModelAttributeIid: editingKey,
topN: (offset+perSuggestCount-1),
offset
} }
}, },
callback: data => { callback: data => {
if (changedValues.hasOwnProperty('cnName')) { if (changedValues.hasOwnProperty('cnName')) {
setSuggests((data||[]).length>0?(data[0].suggestions||[]):[]);
const moreSuggests = (data||[]).length>0?(data[0].suggestions||[]):[];
const newSuggests = (offset===1 ? moreSuggests : [...suggests, ...moreSuggests]);
if (moreSuggests.length === perSuggestCount) {
setSuggestHaveMore(true);
}
setSuggestOffset(newSuggests.length+1);
setSuggests(newSuggests);
} else if (changedValues.hasOwnProperty('name')) { } else if (changedValues.hasOwnProperty('name')) {
setSuggests((data||[]).length>1?(data[1].suggestions||[]):[]); const moreSuggests = (data||[]).length>1?(data[1].suggestions||[]):[];
const newSuggests = (offset===1 ? moreSuggests : [...suggests, ...moreSuggests]);
if (moreSuggests.length === perSuggestCount) {
setSuggestHaveMore(true);
}
setSuggestOffset(newSuggests.length+1);
setSuggests(newSuggests);
} }
} }
}) })
...@@ -430,7 +458,7 @@ const ImportActionTable = (props) => { ...@@ -430,7 +458,7 @@ const ImportActionTable = (props) => {
}, },
{ {
title: '中文名称', title: '中文名称',
width: 100, width: 200,
dataIndex: 'cnName', dataIndex: 'cnName',
editable: true, editable: true,
ellipsis: true, ellipsis: true,
...@@ -444,7 +472,7 @@ const ImportActionTable = (props) => { ...@@ -444,7 +472,7 @@ const ImportActionTable = (props) => {
}, },
{ {
title: '英文名称', title: '英文名称',
width: 150, width: 200,
dataIndex: 'name', dataIndex: 'name',
editable: true, editable: true,
ellipsis: true, ellipsis: true,
...@@ -460,15 +488,14 @@ const ImportActionTable = (props) => { ...@@ -460,15 +488,14 @@ const ImportActionTable = (props) => {
dataIndex: 'datatype', dataIndex: 'datatype',
editable: true, editable: true,
ellipsis: true, ellipsis: true,
render: (datatype, _, __) => { render: (_, record, __) => {
if (record.datatype) {
if (datatype) {
let _text = `名称: ${datatype.name||''}`; let _text = `名称: ${record.datatype.name||''}`;
(datatype.parameterCnNames||[]).forEach((cnName, index) => { (record.datatype.parameterCnNames||[]).forEach((cnName, index) => {
_text += ` ${cnName}: ${(datatype.parameterValues[index]?datatype.parameterValues[index]:0)}`; _text += ` ${cnName}: ${(record.datatype.parameterValues[index]?record.datatype.parameterValues[index]:0)}`;
}) })
return _text; return _text;
...@@ -715,6 +742,20 @@ const ImportActionTable = (props) => { ...@@ -715,6 +742,20 @@ const ImportActionTable = (props) => {
setKeyword(e.target.value||''); setKeyword(e.target.value||'');
} }
const sourceOnClick = (id) => {
const timestamp = new Date().getTime();
if (id.indexOf('Column=')) {
window.open(`/center-home/menu/metasearch?id=${id}&timestamp=${timestamp}`);
} else {
window.open(`/center-home/menu/datastandard?id=${id}&timestamp=${timestamp}`);
}
}
const loadMoreSuggests = () => {
onValuesChange(currentChangedValues, form.getFieldsValue(), suggestOffset);
}
return ( return (
<div className='model-import-action-table'> <div className='model-import-action-table'>
<Divider orientation='left'> <Divider orientation='left'>
...@@ -746,7 +787,7 @@ const ImportActionTable = (props) => { ...@@ -746,7 +787,7 @@ const ImportActionTable = (props) => {
<div id="containerId"> <div id="containerId">
<DndProvider backend={HTML5Backend} > <DndProvider backend={HTML5Backend} >
<Form form={form} component={false} onValuesChange={onValuesChange}> <Form form={form} component={false} onValuesChange={onValuesChange}>
<Table <ProTable
components={{ components={{
body: { body: {
cell: EditableCell, cell: EditableCell,
...@@ -768,6 +809,12 @@ const ImportActionTable = (props) => { ...@@ -768,6 +809,12 @@ const ImportActionTable = (props) => {
rowKey='iid' rowKey='iid'
rowClassName="editable-row" rowClassName="editable-row"
pagination={false} pagination={false}
search={false}
options={{
density: false,
setting: false,
reload: false,
}}
sticky sticky
expandable={{ expandable={{
columnWidth: 0, columnWidth: 0,
...@@ -791,7 +838,14 @@ const ImportActionTable = (props) => { ...@@ -791,7 +838,14 @@ const ImportActionTable = (props) => {
<span style={{ color: '#f50' }}>{`${suggest.recommendedStats?.score}%`}</span> <span style={{ color: '#f50' }}>{`${suggest.recommendedStats?.score}%`}</span>
{ index===0 && <span style={{ color: '#f50' }}> 推荐</span> } { index===0 && <span style={{ color: '#f50' }}> 推荐</span> }
{` 使用次数: ${suggest.recommendedStats?.referencesCount}`} {` 使用次数: ${suggest.recommendedStats?.referencesCount}`}
{` 来源: ${suggest.recommendedStats?.pathInSource||''}`} {' 来源: '}
<a
href='#'
onClick={() => {
sourceOnClick(suggest.recommendedStats?.idInSource||'');
}}
>
{`${suggest.recommendedStats?.pathInSource||''}`}</a>
</Radio> </Radio>
) )
}) })
...@@ -802,6 +856,11 @@ const ImportActionTable = (props) => { ...@@ -802,6 +856,11 @@ const ImportActionTable = (props) => {
} }
</React.Fragment> </React.Fragment>
} }
{
suggestHaveMore && <div className='flex' style={{ justifyContent: 'center' }}>
<Button onClick={loadMoreSuggests}>加载更多</Button>
</div>
}
</React.Fragment> </React.Fragment>
), ),
expandIcon: ({ expanded, onExpand, record }) => { expandIcon: ({ expanded, onExpand, record }) => {
......
...@@ -4,4 +4,10 @@ ...@@ -4,4 +4,10 @@
white-space: normal !important; white-space: normal !important;
} }
} }
.yy-pro-table {
.yy-card-body {
padding: 0 !important;
}
}
} }
\ No newline at end of file
import React, { useState, useEffect, useRef } from "react"; import React, { useState, useEffect, useRef } from "react";
import { Space, Button, Tooltip, Modal, Select, Input, Divider } from 'antd'; import { Space, Button, Tooltip, Modal, Select, Input, Divider, Table } from 'antd';
import { EditOutlined, ReconciliationOutlined, DeleteOutlined } from '@ant-design/icons'; import { EditOutlined, ReconciliationOutlined, DeleteOutlined } from '@ant-design/icons';
import SmoothScroll from 'smooth-scroll'; import SmoothScroll from 'smooth-scroll';
import ProTable from "@ant-design/pro-table"; import ProTable from "@ant-design/pro-table";
import { Resizable } from 'react-resizable';
import { dispatchLatest } from '../../../../model'; import { dispatchLatest } from '../../../../model';
import { showMessage, getQueryParam } from '../../../../util'; import { showMessage, getQueryParam } from '../../../../util';
...@@ -12,50 +13,31 @@ import './ModelTable.less'; ...@@ -12,50 +13,31 @@ import './ModelTable.less';
const { Option } = Select; const { Option } = Select;
const ModelTable = (props) => { const ResizeableHeaderCell = props => {
const { onResize, width, ...restProps } = props;
const { data, onChange, onItemAction, onSelect, catalogId, onSearchInputChange, onModelStateChange, loadingStates, currentModelState, modelStates, view, keyword, onRecatalog } = props;
const [ selectedRowKeys, setSelectedRowKeys ] = useState([]);
const [modal, contextHolder] = Modal.useModal();
const anchorId = getQueryParam(AnchorId, props.location.search);
const anchorTimestamp = getQueryParam(AnchorTimestamp, props.location.search);
const shouldScrollRef = useRef(false);
useEffect(() => { if (!width) {
return <th {...restProps} />;
setSelectedRowKeys([]);
onSelect && onSelect([]);
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [ catalogId ]);
useEffect(() => {
if ((anchorId||'') !== '') {
shouldScrollRef.current = true;
} }
//eslint-disable-next-line react-hooks/exhaustive-deps return (
}, [anchorTimestamp]) <Resizable
width={width}
useEffect(() => { height={0}
if (shouldScrollRef.current) { onResize={onResize}
SmoothScroll('a[href*="#"]'); draggableOpts={{ enableUserSelectHack: false }}
>
<th {...restProps} />
</Resizable>
);
};
const _id = getQueryParam(AnchorId, props.location.search); const ModelTable = (props) => {
var scroll = new SmoothScroll();
var anchor = document.querySelector(`#data-model-${_id}`);
if (anchor) { const { data, onChange, onItemAction, onSelect, catalogId, onSearchInputChange, onModelStateChange, loadingStates, currentModelState, modelStates, view, keyword, onRecatalog } = props;
scroll.animateScroll(anchor);
shouldScrollRef.current = false;
}
}
})
const columns = [ const [ selectedRowKeys, setSelectedRowKeys ] = useState([]);
const [ columns, setColumns ] = useState([
{ {
title: '序号', title: '序号',
dataIndex: 'key', dataIndex: 'key',
...@@ -79,12 +61,13 @@ const ModelTable = (props) => { ...@@ -79,12 +61,13 @@ const ModelTable = (props) => {
{ {
title: '模型描述', title: '模型描述',
dataIndex: 'remark', dataIndex: 'remark',
width: 200,
ellipsis: true, ellipsis: true,
}, },
{ {
title: '操作', title: '操作',
key: 'action', key: 'action',
width: 230, width: 200,
render: (_,record) => { render: (_,record) => {
return ( return (
<Space size='small'> <Space size='small'>
...@@ -113,7 +96,45 @@ const ModelTable = (props) => { ...@@ -113,7 +96,45 @@ const ModelTable = (props) => {
) )
} }
} }
]; ]);
const [modal, contextHolder] = Modal.useModal();
const anchorId = getQueryParam(AnchorId, props.location.search);
const anchorTimestamp = getQueryParam(AnchorTimestamp, props.location.search);
const shouldScrollRef = useRef(false);
useEffect(() => {
setSelectedRowKeys([]);
onSelect && onSelect([]);
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [ catalogId ]);
useEffect(() => {
if ((anchorId||'') !== '') {
shouldScrollRef.current = true;
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [anchorTimestamp])
useEffect(() => {
if (shouldScrollRef.current) {
SmoothScroll('a[href*="#"]');
const _id = getQueryParam(AnchorId, props.location.search);
var scroll = new SmoothScroll();
var anchor = document.querySelector(`#data-model-${_id}`);
if (anchor) {
scroll.animateScroll(anchor);
shouldScrollRef.current = false;
}
}
})
const editItem = (record) => { const editItem = (record) => {
onItemAction && onItemAction(record.id||'', 'edit'); onItemAction && onItemAction(record.id||'', 'edit');
...@@ -187,6 +208,18 @@ const ModelTable = (props) => { ...@@ -187,6 +208,18 @@ const ModelTable = (props) => {
onSelect && onSelect(keys); onSelect && onSelect(keys);
}; };
const handleResize = index => (e, { size }) => {
const nextColumns = [...columns];
nextColumns[index] = {
...nextColumns[index],
width: size.width,
};
setColumns(nextColumns);
};
const rowSelection = { const rowSelection = {
selectedRowKeys, selectedRowKeys,
onChange: onSelectChange, onChange: onSelectChange,
...@@ -253,7 +286,15 @@ const ModelTable = (props) => { ...@@ -253,7 +286,15 @@ const ModelTable = (props) => {
} }
}} }}
rowSelection={rowSelection} rowSelection={rowSelection}
columns={columns} columns={
columns.map((col, index) => ({
...col,
onHeaderCell: column => ({
width: column.width,
onResize: handleResize(index),
}),
}))
}
rowKey={'id'} rowKey={'id'}
dataSource={data||[]} dataSource={data||[]}
pagination={false} pagination={false}
......
...@@ -17,7 +17,7 @@ const viewModes = [ ...@@ -17,7 +17,7 @@ const viewModes = [
}, },
{ {
key: 'state', key: 'state',
name: '发布状态视角' name: '模型状态视角'
} }
]; ];
......
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