Commit ab53a797 by zhaochengxiang

推荐更多

parent 502e002f
......@@ -26,6 +26,7 @@
"react-dnd-html5-backend": "^14.0.0",
"react-dom": "^17.0.1",
"react-redux": "^7.1.0",
"react-resizable": "^3.0.4",
"react-router-dom": "^5.0.1",
"react-scripts": "4.0.3",
"react-virtualized": "^9.22.3",
......
......@@ -125,4 +125,19 @@ tr.drop-over-downward td {
tr.drop-over-upward td {
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) {
return yield call(datamodelerService.recatalogDataModel, payload);
}
export function* modelCopy(payload) {
return yield call(datamodelerService.modelCopy, payload);
}
export function* extractExcelContent(payload) {
return yield call(datamodelerService.extractExcelContent, payload);
}
......
......@@ -39,6 +39,10 @@ export function recatalogDataModel(payload) {
return PostJSON("/datamodeler/easyDataModelerCURD/recatalogDataModel", payload);
}
export function modelCopy(payload) {
return GetJSON("/datamodeler/easyDataModelerCURD/copy", payload);
}
export function extractExcelContent(payload) {
return PostFile("/datamodeler/easyDataModelerDesign/kickStart", payload);
}
......
......@@ -137,18 +137,13 @@ const ImportAction = (props) => {
const getCurrentDataModel = () => {
dispatch({
type: 'datamodel.getDataModel',
type: (action==='add') ? 'datamodel.modelCopy' : 'datamodel.getDataModel',
payload: {
id: modelerId||''
},
callback: data => {
setLoading(false);
//以现有模版新增时
if (action === 'add') {
data.id = null;
}
setModelerData(data||{});
setConstraint(data.easyDataModelerModelingConstraint||{});
setTemplate(data.easyDataModelerModelingTemplate||{});
......
......@@ -171,7 +171,7 @@ const ImportActionHeader = (props) => {
labelAlign="left"
rules={[{ required: true, message: '请输入中文名称!' }]}
>
<Input style={{ width: 200 }} />
<Input style={{ width: 300 }} />
</Form.Item>
</Col>
<Col span={8}>
......@@ -181,7 +181,7 @@ const ImportActionHeader = (props) => {
labelAlign="left"
rules={[{ required: true, message: '请输入英文名称!' }]}
>
<AutoComplete options={options} onSearch={onSearch} style={{ width: 200 }} />
<AutoComplete options={options} onSearch={onSearch} style={{ width: 300 }} />
{/* <Input /> */}
</Form.Item>
</Col>
......@@ -192,7 +192,7 @@ const ImportActionHeader = (props) => {
labelAlign="left"
rules={[{ required: true, message: '请输入描述!' }]}
>
<Input style={{ width: 200 }} />
<Input style={{ width: 300 }} />
</Form.Item>
</Col>
</Row>
......
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 { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import update from 'immutability-helper';
import ProTable from "@ant-design/pro-table";
import Helper from './Help';
import { showMessage, highlightSearchContentByTerms } from '../../../../util';
......@@ -680,7 +681,7 @@ const ImportActionIndex = (props) => {
<div id="containerId">
<DndProvider backend={HTML5Backend} >
<Form form={form} component={false} onValuesChange={onValuesChange}>
<Table
<ProTable
components={{
body: {
cell: EditableCell,
......@@ -702,6 +703,12 @@ const ImportActionIndex = (props) => {
rowKey='name'
rowClassName="editable-row"
pagination={false}
search={false}
options={{
density: false,
setting: false,
reload: false,
}}
sticky
/>
</Form>
......
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 { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import update from 'immutability-helper';
import ProTable from "@ant-design/pro-table";
import { generateUUID, highlightSearchContentByTerms, showMessage } from '../../../../util';
import { dispatchLatest } from '../../../../model';
......@@ -13,6 +14,7 @@ import './ImportActionTable.less';
const { Option } = Select;
const type = 'DragableTableBodyRow';
const perSuggestCount = 5;
const DatatypeInput = ({ value = {}, datatypes, onChange }) => {
......@@ -234,6 +236,9 @@ const ImportActionTable = (props) => {
const [ form ] = Form.useForm();
const [ editingKey, setEditingKey ] = useState('');
const [ suggests, setSuggests ] = useState([]);
const [ suggestHaveMore, setSuggestHaveMore ] = useState(false);
const [ suggestOffset, setSuggestOffset ] = useState(1);
const [ currentChangedValues, setCurrentChangedValues] = useState({});
const [ englishSuggests, setEnglishSuggests ] = useState([]);
const [ keyword, setKeyword ] = useState('');
......@@ -353,7 +358,7 @@ const ImportActionTable = (props) => {
}
};
const onValuesChange = (changedValues, allValues) => {
const onValuesChange = (changedValues, allValues, offset = 1) => {
// console.log('changed values', changedValues);
// console.log('all values', allValues);
......@@ -371,19 +376,42 @@ const ImportActionTable = (props) => {
newData.splice(index, 1, { ...item, ...allValues });
}
setSuggestHaveMore(false);
setCurrentChangedValues(changedValues);
dispatchLatest({
type: 'datamodel.suggest',
payload: {
data: { ...modelerData, easyDataModelerDataModelAttributes: newData },
params: {
easyDataModelerDataModelAttributeIid: editingKey
easyDataModelerDataModelAttributeIid: editingKey,
topN: (offset+perSuggestCount-1),
offset
}
},
callback: data => {
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')) {
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) => {
},
{
title: '中文名称',
width: 100,
width: 200,
dataIndex: 'cnName',
editable: true,
ellipsis: true,
......@@ -444,7 +472,7 @@ const ImportActionTable = (props) => {
},
{
title: '英文名称',
width: 150,
width: 200,
dataIndex: 'name',
editable: true,
ellipsis: true,
......@@ -460,15 +488,14 @@ const ImportActionTable = (props) => {
dataIndex: 'datatype',
editable: true,
ellipsis: true,
render: (datatype, _, __) => {
if (datatype) {
render: (_, record, __) => {
if (record.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;
......@@ -715,6 +742,20 @@ const ImportActionTable = (props) => {
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 (
<div className='model-import-action-table'>
<Divider orientation='left'>
......@@ -746,7 +787,7 @@ const ImportActionTable = (props) => {
<div id="containerId">
<DndProvider backend={HTML5Backend} >
<Form form={form} component={false} onValuesChange={onValuesChange}>
<Table
<ProTable
components={{
body: {
cell: EditableCell,
......@@ -768,6 +809,12 @@ const ImportActionTable = (props) => {
rowKey='iid'
rowClassName="editable-row"
pagination={false}
search={false}
options={{
density: false,
setting: false,
reload: false,
}}
sticky
expandable={{
columnWidth: 0,
......@@ -791,7 +838,14 @@ const ImportActionTable = (props) => {
<span style={{ color: '#f50' }}>{`${suggest.recommendedStats?.score}%`}</span>
{ index===0 && <span style={{ color: '#f50' }}> 推荐</span> }
{` 使用次数: ${suggest.recommendedStats?.referencesCount}`}
{` 来源: ${suggest.recommendedStats?.pathInSource||''}`}
{' 来源: '}
<a
href='#'
onClick={() => {
sourceOnClick(suggest.recommendedStats?.idInSource||'');
}}
>
{`${suggest.recommendedStats?.pathInSource||''}`}</a>
</Radio>
)
})
......@@ -802,6 +856,11 @@ const ImportActionTable = (props) => {
}
</React.Fragment>
}
{
suggestHaveMore && <div className='flex' style={{ justifyContent: 'center' }}>
<Button onClick={loadMoreSuggests}>加载更多</Button>
</div>
}
</React.Fragment>
),
expandIcon: ({ expanded, onExpand, record }) => {
......
......@@ -4,4 +4,10 @@
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 { 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 SmoothScroll from 'smooth-scroll';
import ProTable from "@ant-design/pro-table";
import { Resizable } from 'react-resizable';
import { dispatchLatest } from '../../../../model';
import { showMessage, getQueryParam } from '../../../../util';
......@@ -12,50 +13,31 @@ import './ModelTable.less';
const { Option } = Select;
const ModelTable = (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(() => {
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])
const ResizeableHeaderCell = props => {
const { onResize, width, ...restProps } = props;
useEffect(() => {
if (shouldScrollRef.current) {
SmoothScroll('a[href*="#"]');
if (!width) {
return <th {...restProps} />;
}
const _id = getQueryParam(AnchorId, props.location.search);
var scroll = new SmoothScroll();
var anchor = document.querySelector(`#data-model-${_id}`);
return (
<Resizable
width={width}
height={0}
onResize={onResize}
draggableOpts={{ enableUserSelectHack: false }}
>
<th {...restProps} />
</Resizable>
);
};
if (anchor) {
scroll.animateScroll(anchor);
shouldScrollRef.current = false;
}
}
})
const ModelTable = (props) => {
const columns = [
const { data, onChange, onItemAction, onSelect, catalogId, onSearchInputChange, onModelStateChange, loadingStates, currentModelState, modelStates, view, keyword, onRecatalog } = props;
const [ selectedRowKeys, setSelectedRowKeys ] = useState([]);
const [ columns, setColumns ] = useState([
{
title: '序号',
dataIndex: 'key',
......@@ -79,12 +61,13 @@ const ModelTable = (props) => {
{
title: '模型描述',
dataIndex: 'remark',
width: 200,
ellipsis: true,
},
{
title: '操作',
key: 'action',
width: 230,
width: 200,
render: (_,record) => {
return (
<Space size='small'>
......@@ -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) => {
onItemAction && onItemAction(record.id||'', 'edit');
......@@ -187,6 +208,18 @@ const ModelTable = (props) => {
onSelect && onSelect(keys);
};
const handleResize = index => (e, { size }) => {
const nextColumns = [...columns];
nextColumns[index] = {
...nextColumns[index],
width: size.width,
};
setColumns(nextColumns);
};
const rowSelection = {
selectedRowKeys,
onChange: onSelectChange,
......@@ -253,7 +286,15 @@ const ModelTable = (props) => {
}
}}
rowSelection={rowSelection}
columns={columns}
columns={
columns.map((col, index) => ({
...col,
onHeaderCell: column => ({
width: column.width,
onResize: handleResize(index),
}),
}))
}
rowKey={'id'}
dataSource={data||[]}
pagination={false}
......
......@@ -17,7 +17,7 @@ const viewModes = [
},
{
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