Commit a97633ae by zhaochengxiang

Merge branch 'asset-ui' into 'master'

Asset ui

See merge request !7
parents c657a0f2 e8552565
...@@ -15,6 +15,7 @@ import AssetManage from './view/Manage/AssetManage'; ...@@ -15,6 +15,7 @@ import AssetManage from './view/Manage/AssetManage';
import AssetBrowse from './view/Manage/AssetBrowse'; import AssetBrowse from './view/Manage/AssetBrowse';
import AssetRecycle from './view/Manage/AssetRecycle'; import AssetRecycle from './view/Manage/AssetRecycle';
import DatasourceManage from './view/Manage/DatasourceManage'; import DatasourceManage from './view/Manage/DatasourceManage';
import AssetDetailPage from './view/Manage/AssetManage/Component/AssetDetailPage';
import AssetDetail from './view/Manage/AssetManage/Component/AssetDetail'; import AssetDetail from './view/Manage/AssetManage/Component/AssetDetail';
import ImportAction from './view/Manage/Model/Component/ImportAction'; import ImportAction from './view/Manage/Model/Component/ImportAction';
import EditModel from './view/Manage/Model/Component/EditModel'; import EditModel from './view/Manage/Model/Component/EditModel';
...@@ -38,23 +39,30 @@ export class App extends React.Component { ...@@ -38,23 +39,30 @@ export class App extends React.Component {
if (message === 'showDataModelDetail') { if (message === 'showDataModelDetail') {
return ( return (
<AppContext.Provider value={{
setGlobalState,
onGlobalStateChange
}}>
<ImportAction <ImportAction
modelerId={id} modelerId={id}
action='detail' action='detail'
terms={terms} terms={terms}
/> />
</AppContext.Provider>
); );
} }
if (message === 'showAssetDetail') { if (message === 'showAssetDetail') {
return ( return (
<AppContext.Provider value={{
setGlobalState,
onGlobalStateChange
}}>
<AssetDetail <AssetDetail
id={id} id={id}
reference='search'
action='detail'
terms={terms} terms={terms}
visible={true}
/> />
</AppContext.Provider>
); );
} }
...@@ -86,6 +94,8 @@ export class App extends React.Component { ...@@ -86,6 +94,8 @@ export class App extends React.Component {
<Route path={`${ContextPath}/manage`} component={Manage} /> <Route path={`${ContextPath}/manage`} component={Manage} />
<Route path={`${ContextPath}/data-model-action`} component={EditModel} exact /> <Route path={`${ContextPath}/data-model-action`} component={EditModel} exact />
<Route path={`${ContextPath}/model-template-action`} component={EditTemplate} exact /> <Route path={`${ContextPath}/model-template-action`} component={EditTemplate} exact />
<Route path={`${ContextPath}/asset-detail`} component={AssetDetailPage} exact />
<Route path={'/center-home/view/datasource-manage'} component={DatasourceManage} exact /> <Route path={'/center-home/view/datasource-manage'} component={DatasourceManage} exact />
<Route path={'/center-home/view/data-model'} component={Model} exact /> <Route path={'/center-home/view/data-model'} component={Model} exact />
...@@ -103,6 +113,7 @@ export class App extends React.Component { ...@@ -103,6 +113,7 @@ export class App extends React.Component {
<Route path={'/center-home/menu/asset-browse'} component={AssetBrowse} exact /> <Route path={'/center-home/menu/asset-browse'} component={AssetBrowse} exact />
<Route path={'/center-home/menu/asset-recycle'} component={AssetRecycle} exact /> <Route path={'/center-home/menu/asset-recycle'} component={AssetRecycle} exact />
<Route path={'/center-home/data-model-action'} component={EditModel} exact /> <Route path={'/center-home/data-model-action'} component={EditModel} exact />
<Route path={'/center-home/asset-detail'} component={AssetDetailPage} exact />
</Switch> </Switch>
</Router> </Router>
</AppContext.Provider> </AppContext.Provider>
......
...@@ -202,6 +202,10 @@ export function* importWordGenerateModelDraft(payload) { ...@@ -202,6 +202,10 @@ export function* importWordGenerateModelDraft(payload) {
return yield call(datamodelerService.importWordGenerateModelDraft, payload); return yield call(datamodelerService.importWordGenerateModelDraft, payload);
} }
export function* heartbeat() {
return yield call(datamodelerService.heartbeat);
}
export function* validateDataModel(payload) { export function* validateDataModel(payload) {
return yield call(datamodelerService.validateDataModel, payload); return yield call(datamodelerService.validateDataModel, payload);
} }
......
import { createStore, applyMiddleware } from 'redux' import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga' import createSagaMiddleware from 'redux-saga'
import { all, call, takeLatest, takeEvery } from 'redux-saga/effects' import { all, call, takeLatest, takeEvery, delay } from 'redux-saga/effects'
import { Connect, showErrorNotifaction } from '../util'; import { Connect, showErrorNotifaction } from '../util';
import { reducers } from './reducer'; import { reducers } from './reducer';
...@@ -16,6 +16,7 @@ function* request(args) { ...@@ -16,6 +16,7 @@ function* request(args) {
const { type, payload, callback, error } = args.args; const { type, payload, callback, error } = args.args;
try { try {
yield delay(100);
const rs = yield call(funcs[type], payload) const rs = yield call(funcs[type], payload)
if (callback) if (callback)
yield call(callback, rs) yield call(callback, rs)
......
...@@ -181,6 +181,10 @@ export function importWordGenerateModelDraft(payload) { ...@@ -181,6 +181,10 @@ export function importWordGenerateModelDraft(payload) {
return PostFile("/datamodeler/easyDataModelerExport/word/draft", payload); return PostFile("/datamodeler/easyDataModelerExport/word/draft", payload);
} }
export function heartbeat() {
return Get("/datamodeler/easyDataModelerExport/heartbeat");
}
export function validateDataModel(payload) { export function validateDataModel(payload) {
return PostJSON("/datamodeler/easyDataModelerConstraint/validateDataModel", payload); return PostJSON("/datamodeler/easyDataModelerConstraint/validateDataModel", payload);
} }
...@@ -212,3 +216,4 @@ export function getParent(payload) { ...@@ -212,3 +216,4 @@ export function getParent(payload) {
export function autoCreateTable(payload) { export function autoCreateTable(payload) {
return PostJSON("/metadataharvester/datasource/createTableByDDLList", payload); return PostJSON("/metadataharvester/datasource/createTableByDDLList", payload);
} }
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { Modal, Typography, Spin } from "antd"; import { Spin, Tabs, Descriptions } from "antd";
import AssetDetailItem from './AssetDetailItem'; import MetadataInfo from './MetadataInfo';
import { highlightSearchContentByTerms } from '../../../../util';
import { dispatch } from '../../../../model'; import { dispatch } from '../../../../model';
const { TabPane } = Tabs;
const AssetDetail = (props)=>{ const AssetDetail = (props)=>{
const { onCancel, visible, id, reference=null, terms } = props; const { id, terms } = props;
const [ asset, setAsset ] = useState(''); const [ asset, setAsset ] = useState('');
const [ assetName, setAssetName ] = useState(''); const [ types, setTypes ] = useState([]);
const [ loading, setLoading ] = useState(false); const [ loading, setLoading ] = useState(false);
const [ tabKey, setTabKey ] = useState('0');
useEffect(() => { useEffect(() => {
if (visible && (id||'') !== '') { if ((id||'') !== '') {
getAssetThenGetAssetName(); getAssetThenGetAssetName();
} }
//eslint-disable-next-line react-hooks/exhaustive-deps //eslint-disable-next-line react-hooks/exhaustive-deps
}, [ visible, id ]) }, [ id ])
const getAssetThenGetAssetName = () => { const getAssetThenGetAssetName = () => {
setLoading(true); setLoading(true);
...@@ -29,7 +33,15 @@ const AssetDetail = (props)=>{ ...@@ -29,7 +33,15 @@ const AssetDetail = (props)=>{
callback: data => { callback: data => {
setLoading(false); setLoading(false);
setAsset(data); setAsset(data);
getAssetName(data);
const _types = [];
(data?.elements||[]).forEach(element => {
if (_types.indexOf(element.type) === -1) {
_types.push(element.type);
}
})
setTypes(_types);
}, },
error: () => { error: () => {
setLoading(false); setLoading(false);
...@@ -37,43 +49,39 @@ const AssetDetail = (props)=>{ ...@@ -37,43 +49,39 @@ const AssetDetail = (props)=>{
}) })
} }
const getAssetName = (data) => { const onTabChange = (key) => {
if (data) { setTabKey(key);
const index = (data.elements||[]).findIndex(element => element.name==='中文名称');
if (index !== -1) {
setAssetName(data.elements[index].value||'');
}
}
} }
return( return(
<>
{
!reference && <Modal
title={
<Typography.Paragraph
className='mr-5'
title={`资产: ${assetName||''}`}
ellipsis
>
{`资产: ${assetName||''}`}
</Typography.Paragraph>}
visible={visible}
width={800}
onCancel={()=>{ onCancel && onCancel()}}
footer={null}
>
<Spin spinning={loading}> <Spin spinning={loading}>
<AssetDetailItem data={asset} /> <Tabs activeKey={tabKey} onChange={onTabChange}>
</Spin>
</Modal>
}
{ {
reference && <Spin spinning={loading}> (types||[]).map((type, index) => {
<AssetDetailItem data={asset} terms={terms} />
</Spin> const _currentValues = (asset.elements||[]).filter(element => element.type===type);
return (
<TabPane tab={type} key={index}>
<Descriptions column={2}>
{
(_currentValues||[]).map((item, index) => {
return (
<Descriptions.Item label={item.name||''} key={index}>
{
item.name==='资产项' ? <MetadataInfo config={false} value={item.value||''} /> : <span>{highlightSearchContentByTerms(item.value||'', terms)}</span>
}
</Descriptions.Item>
);
})
} }
</> </Descriptions>
</TabPane>
)
})
}
</Tabs>
</Spin>
) )
} }
......
import React, { useEffect, useState } from 'react';
import { Row, Col, Typography } from 'antd';
import { highlightSearchContentByTerms } from '../../../../util';
import MetadataInfo from './MetadataInfo';
import './AssetItem.less';
const AssetItem = (props) => {
const { data, terms } = props;
const [ typesOfElements, setTypesOfElements ] = useState([]);
useEffect(() => {
if (data) {
convertData();
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [ data ]);
const convertData = () => {
const _typesOfElements = [];
const _types = [];
data && (data.elements||[]).forEach(element => {
if (_types.indexOf(element.type||'') === -1) {
_types.push(element.type||'');
const _elements = (data.elements||[]).filter(_element => (_element.type||'') === (element.type||''));
_typesOfElements.push({ type: element.type||'', elements: _elements||[] });
}
})
setTypesOfElements(_typesOfElements);
}
return (
<div className='asset-item'>
{
(typesOfElements||[]).map((elementGroup, index) => {
const _type = elementGroup.type||'';
return (
<div>
<div className='flex' style={{ alignItems: 'center', padding: '15px 0' }}>
<div style={{ width: 3, height: 14, backgroundColor: '#0069AC', marginRight: 5 }} />
<span style={{ fontWeight: 'bold', color: '#464646' }}>{_type||''}</span>
</div>
<Row>
{
elementGroup && elementGroup.elements && elementGroup.elements.map((element, _index) => {
return (
<Col className='mb-3' key={_index} md={8}>
<Typography.Paragraph title={ `${element.name||''}: ${element.value||''}` } style={{ color: '#464646' }} ellipsis>
{ `${element.name||''}: `}
{
(element.name==='资产项')?<MetadataInfo config={false} value={element.value||''} />:highlightSearchContentByTerms(element.value||'', terms)
}
</Typography.Paragraph>
</Col>
);
})
}
</Row>
<div style={{ width: '100%', height: 2, backgroundColor: '#ededed' }} />
</div>
)
})
}
</div>
);
}
export default AssetItem;
import React, { useEffect, useState } from "react";
import AssetDetail from './AssetDetail';
import { getQueryParam } from '../../../../util';
import './AssetDetailPage.less';
const AssetDetailPage = (props)=>{
const [ id, setId ] = useState('');
useEffect(() => {
const _id = getQueryParam('id', props.location.search);
setId(_id);
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
return(
<div className='asset-detail position-relative'>
<div className='detail-header'>
<span style={{ fontSize: 16, fontWeight: 'bold', color: '#fff' }}>资产详情</span>
</div>
<div className='detail-container'>
<div className='detail-container-card'>
<AssetDetail id={id} />
</div>
</div>
</div>
)
}
export default AssetDetailPage;
\ No newline at end of file
.asset-detail {
.detail-header {
display: flex;
width: 100%;
height: 44px;
padding: 0 15px;
background-color: #464d6e;
align-items: center;
position: fixed;
justify-content: space-between;
border-bottom: 1px solid #EFEFEF;
z-index: 100;
}
.detail-container {
top: 44px;
width: 100%;
height: calc(100vh - 44px);
overflow: auto;
background: #EDF0F5;
padding: 10px 20px;
position: absolute;
}
.detail-container-card {
padding: 20px 20px 0;
background: #fff;
}
}
\ No newline at end of file
import React,{ useState, useEffect, useRef } from "react"; import React,{ useState, useEffect, useRef } from "react";
import { Card, Checkbox, Button, List, Pagination, Space, Modal, Switch, Tooltip, Popover, Input, Spin } from "antd"; import { Card, Button, Pagination, Space, Modal, Input, Table, Divider, Dropdown, Menu, Tooltip } from "antd";
import { EditOutlined, ReconciliationOutlined, DeleteOutlined, UndoOutlined } from '@ant-design/icons'; import { DownOutlined } from '@ant-design/icons';
import classNames from 'classnames'; import classNames from 'classnames';
import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer'; import SmoothScroll from 'smooth-scroll';
import VList from 'react-virtualized/dist/commonjs/List';
import { CellMeasurer, CellMeasurerCache } from 'react-virtualized/dist/commonjs/CellMeasurer';
import ImportElement from './ImportElement'; import ImportElement from './ImportElement';
import FilterElement from './FilterElement'; import FilterElementModal from './FilterElementModal';
import AssetMount from '../../AssetRecycle/Component/AssetMount'; import AssetMount from '../../AssetRecycle/Component/AssetMount';
import AttributeRelationModal from "./AttributeRelationModal"; import AttributeRelationModal from "./AttributeRelationModal";
import ImportAsset from './ImportAsset'; import ImportAsset from './ImportAsset';
import AssetEdit from './AssetEdit'; import AssetEdit from './AssetEdit';
import AssetDetail from "./AssetDetail"; import MetadataInfo from './MetadataInfo';
import AssetItem from './AssetItem';
import { dispatch, dispatchLatestHomepage } from '../../../../model'; import { dispatch, dispatchLatestHomepage } from '../../../../model';
import { showMessage, showNotifaction, getQueryParam, inputWidth } from '../../../../util'; import { showMessage, showNotifaction, getQueryParam, inputWidth, isSzseEnv } from '../../../../util';
import { AnchorId, AnchorTimestamp } from '../../../../util/constant'; import { AnchorId, AnchorTimestamp } from '../../../../util/constant';
import "./AssetTable.less"; import "./AssetTable.less";
...@@ -24,38 +21,72 @@ const AssetTable = (props) => { ...@@ -24,38 +21,72 @@ const AssetTable = (props) => {
const { readOnly = false, className, nodeId } = props; const { readOnly = false, className, nodeId } = props;
const [ loading, setLoading ] = useState(false); const [ loading, setLoading ] = useState(false);
const [filterElementsGroup, setFilterElementsGroup] = useState([]); const [ columns, setColumns ] = useState([]);
const [ assetNames, setAssetNames ] = useState([]);
const [ assets, setAssets ] = useState([]); const [ assets, setAssets ] = useState([]);
const [ total, setTotal ] = useState(0); const [ total, setTotal ] = useState(0);
const [ selectedKeys, setSelectedKeys ] = useState([]); const [ selectedKeys, setSelectedKeys ] = useState([]);
const [ checkAllValue, setCheckAllValue ] = useState(false);
const [ importAssetVisible, setImportAssetVisible ] = useState(false); const [ importAssetVisible, setImportAssetVisible ] = useState(false);
const [ importElementVisible, setImportElementVisible ] = useState(false); const [ importElementVisible, setImportElementVisible ] = useState(false);
const [ filterElementVisible, setFilterElementVisible ] = useState(false); const [ filterElementVisible, setFilterElementVisible ] = useState(false);
const [ attributeRelationModalVisible, setAttributeRelationModalVisible ] = useState(false); const [ attributeRelationModalVisible, setAttributeRelationModalVisible ] = useState(false);
const [ assetEditVisible, setAssetEditVisible ] = useState(false); const [ assetEditVisible, setAssetEditVisible ] = useState(false);
const [ assetDetailVisible, setAssetDetailVisible ] = useState(false);
const [ assetMountVisible, setAssetMountVisible ] = useState(false); const [ assetMountVisible, setAssetMountVisible ] = useState(false);
const [ currentAssetId, setCurrentAssetId ] = useState(''); const [ currentAssetId, setCurrentAssetId ] = useState('');
const [ assetEditAction, setAssetEditAction ] = useState(''); const [ assetEditAction, setAssetEditAction ] = useState('');
const [ pagination, setPagination ] = useState( { pageNum: 1, pageSize: 20 } ); const [ pagination, setPagination ] = useState( { pageNum: 1, pageSize: 20 } );
const { pageNum, pageSize } = pagination; const { pageNum, pageSize } = pagination;
const [ keyword, setKeyword ] = useState(''); const [ keyword, setKeyword ] = useState('');
const [ scrollToIndex, setScrollToIndex ] = useState(-1); const [ batchCatalogChange, setBatchCatalogChange ] = useState(false);
const actionColumn = {
title: '操作',
key: 'action',
width: 140,
fixed: 'right',
render: (_,record) => {
return (
<div style={{ display: 'flex', alignItems: 'center' }}>
<Button
type='link'
size='small'
onClick={() => { editAsset(record); }}
style={{ padding: 0 }}
>
编辑
</Button>
<div>
<Divider type='vertical' />
</div>
<Button
type='link'
size='small'
onClick={() => { deleteAsset(record); }}
style={{ padding: 0 }}
>
删除
</Button>
<div>
<Divider type='vertical' />
</div>
<Button
type='link'
size='small'
onClick={() => { mountAsset(record); }}
style={{ padding: 0 }}
>
变更
</Button>
</div>
)
}
};
const [ modal, contextHolder ] = Modal.useModal(); const [ modal, contextHolder ] = Modal.useModal();
const anchorId = getQueryParam(AnchorId, props.location.search); const anchorId = getQueryParam(AnchorId, props.location.search);
const timestamp = getQueryParam(AnchorTimestamp, props.location.search); const timestamp = getQueryParam(AnchorTimestamp, props.location.search);
const shouldScrollRef = useRef(false); const shouldScrollRef = useRef(false);
const cellCache = new CellMeasurerCache({
fixedWidth: true,
minHeight: 50,
});
useEffect(() => { useEffect(() => {
if ((nodeId||'') !== '' ) { if ((nodeId||'') !== '' ) {
...@@ -72,7 +103,7 @@ const AssetTable = (props) => { ...@@ -72,7 +103,7 @@ const AssetTable = (props) => {
setKeyword(''); setKeyword('');
setSelectedKeys([]); setSelectedKeys([]);
setCheckAllValue(false);
} }
//eslint-disable-next-line react-hooks/exhaustive-deps //eslint-disable-next-line react-hooks/exhaustive-deps
}, [ nodeId ]) }, [ nodeId ])
...@@ -88,15 +119,25 @@ const AssetTable = (props) => { ...@@ -88,15 +119,25 @@ const AssetTable = (props) => {
useEffect(() => { useEffect(() => {
if ((nodeId||'') !== '' ) { if ((nodeId||'') !== '' ) {
if (filterElementsGroup.length === 0) {
getFilterElementsGroupThenGetDataAssets(); getFilterElementsGroupThenGetDataAssets();
} else {
getDataAssets();
}
} }
//eslint-disable-next-line react-hooks/exhaustive-deps //eslint-disable-next-line react-hooks/exhaustive-deps
}, [ keyword, pagination ]) }, [ keyword, pagination ])
useEffect(() => {
if (shouldScrollRef.current) {
SmoothScroll('a[href*="#"]');
var scroll = new SmoothScroll();
var anchor = document.querySelector(`#data-asset-${anchorId}`);
if (anchor) {
scroll.animateScroll(anchor);
shouldScrollRef.current = false;
}
}
})
const getDataAssetLocation = () => { const getDataAssetLocation = () => {
setLoading(true); setLoading(true);
dispatch({ dispatch({
...@@ -107,8 +148,6 @@ const AssetTable = (props) => { ...@@ -107,8 +148,6 @@ const AssetTable = (props) => {
callback: data => { callback: data => {
const anchorLocation = data.offset; const anchorLocation = data.offset;
const _pageNum = parseInt(anchorLocation/pageSize + ((anchorLocation%pageSize===0)?0:1)); const _pageNum = parseInt(anchorLocation/pageSize + ((anchorLocation%pageSize===0)?0:1));
const _index = anchorLocation - (_pageNum - 1)*pageSize - 1;
setScrollToIndex(_index);
setPagination({ ...pagination, pageNum: _pageNum }); setPagination({ ...pagination, pageNum: _pageNum });
}, },
error: () => { error: () => {
...@@ -119,9 +158,7 @@ const AssetTable = (props) => { ...@@ -119,9 +158,7 @@ const AssetTable = (props) => {
} }
const changeCurrent = (page,size) => { const changeCurrent = (page,size) => {
setCheckAllValue(false);
setSelectedKeys([]); setSelectedKeys([]);
setScrollToIndex(-1);
setPagination({ pageNum: page, pageSize: size }); setPagination({ pageNum: page, pageSize: size });
} }
...@@ -130,8 +167,67 @@ const AssetTable = (props) => { ...@@ -130,8 +167,67 @@ const AssetTable = (props) => {
dispatch({ dispatch({
type: 'assetmanage.listFilterElementsGroupByType', type: 'assetmanage.listFilterElementsGroupByType',
callback: data => { callback: data => {
setFilterElementsGroup(data||[]); const _columns = [];
getDataAssets(data||[]);
let index = 0;
(data||[]).forEach(group => {
(group.names||[]).forEach((name, i) => {
index += (i+1);
const params = {
title: name,
dataIndex: `element${index}`,
ellipsis: true,
width: 120,
render: (text, record) => {
return (
<Tooltip title={text||''}>
{text||''}
</Tooltip>
);
}
};
if (name === '编号') {
params.width = 60;
params.fixed = 'left';
} else if (name === '中文名称') {
params.fixed = 'left';
} else if (name === '英文名称') {
params.width = isSzseEnv?250:120;
params.fixed = 'left';
params.render = (text, record) => {
return (
<Tooltip title={text||''}>
<a onClick={()=>{detailAsset(record);}}>
{text||''}
</a>
</Tooltip>
);
}
} else if (name === '资产项') {
params.width = isSzseEnv?250:120;
params.fixed = 'right';
params.render = (text, _) => {
return (
<MetadataInfo config={false} value={text||''} />
);
}
}
_columns.push(params);
})
})
if (readOnly) {
setColumns(_columns);
} else {
setColumns([..._columns, actionColumn]);
}
getDataAssets();
}, },
error: () => { error: () => {
setLoading(false) setLoading(false)
...@@ -139,7 +235,7 @@ const AssetTable = (props) => { ...@@ -139,7 +235,7 @@ const AssetTable = (props) => {
}) })
} }
const getDataAssets = (elmentsGroup = filterElementsGroup) => { const getDataAssets = () => {
setLoading(true); setLoading(true);
dispatchLatestHomepage({ dispatchLatestHomepage({
type: 'assetmanage.listDataAssetsByPage', type: 'assetmanage.listDataAssetsByPage',
...@@ -150,28 +246,23 @@ const AssetTable = (props) => { ...@@ -150,28 +246,23 @@ const AssetTable = (props) => {
keyword: keyword keyword: keyword
}, },
callback: data => { callback: data => {
const _assetNames = []; const _assets = [];
(data.data||[]).forEach((asset, index) => {
asset.elementsGroup = []; (data.data||[]).forEach(asset => {
(elmentsGroup||[]).forEach((elementGroup, _index) => {
let _processElementGroup = { type: elementGroup.type, elements: [] };
((elementGroup||[]).names||[]).forEach((name, __index) => { let _asset = {...asset}, index = 0;
_processElementGroup.elements.push({ name, value: asset?.elementValues[_index].values[__index] }); (asset.elementValues||[]).forEach((elementValue) => {
if (name === '中文名称') { (elementValue.values||[]).forEach((value, i) => {
_assetNames.push(`${index+1}. ${asset?.elementValues[_index].values[__index]||''}`); index += (i+1);
} _asset[`element${index}`] = value;
}); });
asset.elementsGroup.push(_processElementGroup);
}) })
_assets.push(_asset);
}) })
setAssetNames(_assetNames); setAssets(_assets);
setAssets(data.data||[]);
setTotal(data.total||0); setTotal(data.total||0);
setLoading(false); setLoading(false);
}, },
...@@ -203,6 +294,7 @@ const AssetTable = (props) => { ...@@ -203,6 +294,7 @@ const AssetTable = (props) => {
} }
const mountAsset = (item) => { const mountAsset = (item) => {
setBatchCatalogChange(false);
setCurrentAssetId(item.id); setCurrentAssetId(item.id);
setAssetMountVisible(true); setAssetMountVisible(true);
} }
...@@ -234,7 +326,6 @@ const AssetTable = (props) => { ...@@ -234,7 +326,6 @@ const AssetTable = (props) => {
newSelectedKeys.splice(index, 1); newSelectedKeys.splice(index, 1);
setSelectedKeys(newSelectedKeys); setSelectedKeys(newSelectedKeys);
} }
setCheckAllValue(false);
}, },
error: () => { error: () => {
} }
...@@ -247,6 +338,10 @@ const AssetTable = (props) => { ...@@ -247,6 +338,10 @@ const AssetTable = (props) => {
setImportAssetVisible(true); setImportAssetVisible(true);
} }
const onFilterElementClick = () => {
setFilterElementVisible(true);
}
const exportAsset = () => { const exportAsset = () => {
if ((selectedKeys||[]).length === 0) { if ((selectedKeys||[]).length === 0) {
showMessage('warn', '请先选择资产'); showMessage('warn', '请先选择资产');
...@@ -257,41 +352,7 @@ const AssetTable = (props) => { ...@@ -257,41 +352,7 @@ const AssetTable = (props) => {
const detailAsset = (item)=>{ const detailAsset = (item)=>{
setCurrentAssetId(item.id); setCurrentAssetId(item.id);
setAssetDetailVisible(true); window.open(`/center-home/asset-detail?id=${item.id}`);
}
const onAssetDetailCancel = () => {
setAssetDetailVisible(false);
}
const onCheckAll =(checked)=>{
setCheckAllValue(checked);
if (checked) {
const ids = [];
(assets||[]).forEach(asset => {
ids.push(asset.id||'');
})
setSelectedKeys(ids);
} else {
setSelectedKeys([]);
}
}
const onAssetCheckboxChange = (e) => {
let newSelectedKeys = [...selectedKeys];
if (e.target.checked) {
newSelectedKeys = [...newSelectedKeys, e.target.value];
} else {
const index = newSelectedKeys.findIndex((key) => key === e.target.value);
newSelectedKeys.splice(index, 1);
}
setSelectedKeys(newSelectedKeys||[]);
setCheckAllValue((newSelectedKeys||[].length!==0) && (newSelectedKeys||[]).length===(assets||[]).length);
} }
const deleteAssets = () => { const deleteAssets = () => {
...@@ -313,7 +374,6 @@ const AssetTable = (props) => { ...@@ -313,7 +374,6 @@ const AssetTable = (props) => {
showMessage("success","删除成功"); showMessage("success","删除成功");
getDataAssets(); getDataAssets();
setSelectedKeys([]); setSelectedKeys([]);
setCheckAllValue(false);
}, },
error: () => { error: () => {
} }
...@@ -341,8 +401,8 @@ const AssetTable = (props) => { ...@@ -341,8 +401,8 @@ const AssetTable = (props) => {
} }
} }
const onFilterElementVisibleChange = (visible = false, refresh = false) => { const onFilterElementModalCancel = (refresh = false) => {
setFilterElementVisible(visible); setFilterElementVisible(false);
refresh && getFilterElementsGroupThenGetDataAssets(); refresh && getFilterElementsGroupThenGetDataAssets();
} }
...@@ -358,10 +418,64 @@ const AssetTable = (props) => { ...@@ -358,10 +418,64 @@ const AssetTable = (props) => {
setAttributeRelationModalVisible(true); setAttributeRelationModalVisible(true);
} }
const onBatchCatalogChangeBtnClick = () => {
setBatchCatalogChange(true);
setAssetMountVisible(true);
}
const onAttributeRelationModalCancel = () => { const onAttributeRelationModalCancel = () => {
setAttributeRelationModalVisible(false); setAttributeRelationModalVisible(false);
} }
const onSelectChange = keys => {
setSelectedKeys(keys);
};
const rowSelection = {
selectedRowKeys: selectedKeys,
onChange: onSelectChange,
};
const onMoreMenuClick = (e) => {
const { key } = e;
if (key === 'element-import') {
onImportElementBtnClick();
} else if (key === 'element-export') {
onExportElementBtnClick();
} else if (key === 'attribute-relation') {
onAttributeRelationBtnClick();
} else if (key === 'catalog-change') {
onBatchCatalogChangeBtnClick();
} else if (key === 'delete') {
deleteAssets();
}
}
const moreMenu = () => {
return <Menu onClick={onMoreMenuClick}>
<Menu.Item key='element-import'>
导入要素
</Menu.Item>
<Menu.Item key='element-export'>
导出要素
</Menu.Item>
<Menu.Item key='attribute-relation'>
元数据属性关联
</Menu.Item>
<Menu.Item key='catalog-change' disabled={(selectedKeys||[]).length===0}>
<Tooltip title={(selectedKeys||[]).length===0?'请先选择资产':''}>
变更目录
</Tooltip>
</Menu.Item>
<Menu.Item key='delete' disabled={(selectedKeys||[]).length===0}>
<Tooltip title={(selectedKeys||[]).length===0?'请先选择资产':''}>
删除
</Tooltip>
</Menu.Item>
</Menu>
}
const classes = classNames('asset-list', className, { const classes = classNames('asset-list', className, {
'asset-list-read-only': readOnly 'asset-list-read-only': readOnly
}); });
...@@ -370,12 +484,25 @@ const AssetTable = (props) => { ...@@ -370,12 +484,25 @@ const AssetTable = (props) => {
<Card <Card
bordered={false} bordered={false}
className={classes} className={classes}
bodyStyle={{ padding: '0 10px' }} bodyStyle={{ padding: '10px 10px 0' }}
headStyle={{ padding: 10 }} headStyle={{ padding: 10 }}
title={ title={
<div className='d-flex' style={{ justifyContent: 'space-between' }}> <div className='d-flex' style={{ justifyContent: 'space-between' }}>
<Space> <Space>
<span>资产搜索:</span> { !readOnly && <Button onClick={addAsset}>新增</Button> }
{ !readOnly && <Button onClick={importAsset} >导入</Button> }
<Tooltip title={(selectedKeys||[]).length===0?'请先选择资产':''}>
<Button onClick={exportAsset} disabled={(selectedKeys||[]).length===0} >导出</Button>
</Tooltip>
<Button onClick={onFilterElementClick}>要素过滤</Button>
{ readOnly && <Button onClick={onAttributeRelationBtnClick}>元数据属性关联</Button> }
{
!readOnly && <Dropdown overlay={moreMenu} trigger={['click']} placement="bottomLeft">
<Button>更多<DownOutlined /></Button>
</Dropdown>
}
</Space>
<Space>
<Input <Input
placeholder="请输入资产要素值" placeholder="请输入资产要素值"
allowClear allowClear
...@@ -387,133 +514,29 @@ const AssetTable = (props) => { ...@@ -387,133 +514,29 @@ const AssetTable = (props) => {
</div> </div>
} }
> >
<div <Table
style={{ rowSelection={rowSelection}
display: 'flex', onRow={(record) => {
justifyContent: 'space-between', return {
alignItems: 'center', id: `data-asset-${record?.id}`,
height: 52,
padding: '10px 0',
borderBottom:'1px solid #f0f0f0'
}} >
<Switch
checkedChildren="全不选"
unCheckedChildren="全选"
checked={ checkAllValue }
onChange={ onCheckAll }
/>
<div>
<Space>
<span>资产要素:</span>
{
!readOnly && <>
<Button type="primary" onClick={onImportElementBtnClick}>导入</Button>
<Button type="primary" onClick={onExportElementBtnClick}>导出</Button>
</>
}
<Popover
placement="bottom"
content={<FilterElement onCancel={onFilterElementVisibleChange} />}
title='资产要素过滤'
visible={filterElementVisible}
onVisibleChange={onFilterElementVisibleChange}
trigger="hover">
<Button type="primary">过滤</Button>
</Popover>
<Button type='primary' onClick={onAttributeRelationBtnClick}>属性关联</Button>
</Space>
<Space className='ml-5'>
<span>资产:</span>
{
!readOnly && <>
<Button type="primary" onClick={ addAsset }>新增</Button>
<Button type="danger" onClick={ deleteAssets } >删除</Button>
<Button type="primary" onClick={importAsset} >导入</Button>
</>
} }
<Button type="primary" onClick={exportAsset} >导出</Button> }}
</Space> rowClassName={(record, index) => {
</div> if (record?.id===anchorId) {
</div> return 'highlight-row';
<Spin spinning={loading}>
{
loading && <div className='data-asset-spin' />
}
{
!loading && (
<>
<Checkbox.Group
style={{ width: '100%' }}
value={ selectedKeys }
>
<AutoSizer>
{({width, height}) => (
<VList
deferredMeasurementCache={cellCache}
overscanRowCount={2}
height={height}
width={width}
rowCount={(assets||[]).length}
rowHeight={cellCache.rowHeight}
scrollToIndex={scrollToIndex}
rowRenderer={({index, key, parent, style}) => {
const item = assets[index];
return (
<CellMeasurer
cache={cellCache}
columnIndex={0}
key={key}
rowIndex={index}
parent={parent}>
{({measure, registerChild}) => (
<List.Item
onLoad={measure}
id={`data-asset-${item.id||''}`}
style={{ ...style, backgroundColor: (item.id===anchorId)?'#e7f7ff':'transparent' }}
>
<List.Item.Meta
title={
<>
<div className='d-flex mt-3 mb-1' style={{ alignItems: 'center' }}>
<div className='textOverflow' style={{ flex: 1 }}>
<Checkbox value={item.id} onChange={onAssetCheckboxChange}></Checkbox>
<span title={assetNames[index]||''} style={{ marginLeft:8, fontSize: 18, fontWeight: 'bold' }}>{assetNames[index]||''}</span>
</div>
<Space className='m-3' style={{ marginLeft: 'auto' }} size='small'>
{
!readOnly && <Tooltip placement='bottom' title={'修改'}>
<Button icon={<EditOutlined />} size='small' onClick={() => { editAsset(item); }} />
</Tooltip>
}
<Tooltip placement='bottom' title={'详情'}>
<Button icon={<ReconciliationOutlined />} size='small' onClick={() => { detailAsset(item); }} />
</Tooltip>
{
!readOnly && <Tooltip placement='bottom' title={'挂载'}>
<Button icon={<UndoOutlined />} size='small' onClick={() => { mountAsset(item); }} />
</Tooltip>
}
{
!readOnly && <Tooltip placement='bottom' title={'删除'}>
<Button icon={<DeleteOutlined />} size='small' onClick={() => { deleteAsset(item); }} />
</Tooltip>
}
</Space>
</div>
<div style={{ width: '100%', height: 2, backgroundColor: '#ededed' }} />
</>
} }
description={ <AssetItem data={item} /> }
/> return '';
</List.Item>
)}
</CellMeasurer>
);
}} }}
loading={loading}
columns={columns}
rowKey='id'
dataSource={assets}
pagination={false}
size='default'
scroll={{ x: 1000, y: 'calc(100vh - 64px - 30px - 57px - 39px - 10px - 42px)' }}
/> />
)}
</AutoSizer>
</Checkbox.Group>
<Pagination <Pagination
size="small" size="small"
className="text-center m-3" className="text-center m-3"
...@@ -527,9 +550,7 @@ const AssetTable = (props) => { ...@@ -527,9 +550,7 @@ const AssetTable = (props) => {
total={total} total={total}
showTotal={total => `共 ${total} 条`} showTotal={total => `共 ${total} 条`}
/> />
</>
)}
</Spin>
<AssetEdit <AssetEdit
visible={assetEditVisible} visible={assetEditVisible}
action={assetEditAction} action={assetEditAction}
...@@ -537,11 +558,6 @@ const AssetTable = (props) => { ...@@ -537,11 +558,6 @@ const AssetTable = (props) => {
nodeId={nodeId} nodeId={nodeId}
onCancel={onAssetEditCancel} onCancel={onAssetEditCancel}
/> />
<AssetDetail
visible={assetDetailVisible}
id={currentAssetId}
onCancel={onAssetDetailCancel}
/>
<ImportElement <ImportElement
visible={importElementVisible} visible={importElementVisible}
onCancel={onImportElementCancel} onCancel={onImportElementCancel}
...@@ -553,7 +569,7 @@ const AssetTable = (props) => { ...@@ -553,7 +569,7 @@ const AssetTable = (props) => {
/> />
<AssetMount <AssetMount
visible={ assetMountVisible } visible={ assetMountVisible }
id={ currentAssetId } ids={ batchCatalogChange?selectedKeys:[currentAssetId] }
onCancel={ onAssetMountCancel } onCancel={ onAssetMountCancel }
{...props} {...props}
/> />
...@@ -562,6 +578,10 @@ const AssetTable = (props) => { ...@@ -562,6 +578,10 @@ const AssetTable = (props) => {
readOnly={ readOnly } readOnly={ readOnly }
onCancel={ onAttributeRelationModalCancel } onCancel={ onAttributeRelationModalCancel }
/> />
<FilterElementModal
visible={ filterElementVisible }
onCancel={ onFilterElementModalCancel}
/>
{contextHolder} {contextHolder}
</Card> </Card>
) )
......
@import '../../../../variables.less'; @import '../../../../variables.less';
.asset-list { .asset-list {
.yy-list-item-action {
text-align: right;
}
.yy-card-head-title { .yy-card-head-title {
font-weight: normal; font-weight: normal;
font-size: 14px; font-size: 14px;
padding: 0; padding: 0;
} }
.yy-list-vertical .yy-list-item-action > li {
padding: 0 ; .highlight-row {
} .yy-table-cell {
.data-asset-spin { background-color: #e7f7ff !important;
height: calc(100vh - @header-height - @pm-4 - 53px - 52px + 1px);
}
.yy-checkbox-group {
height: calc(100vh - @header-height - @pm-4 - 53px - 52px - 53px) !important;
overflow: auto !important;
}
.yy-divider-horizontal {
margin: 0 !important;
}
.yy-list-vertical {
.yy-list-item-meta, .yy-list-item-meta-title {
margin-bottom: 0 !important;
}
} }
.yy-list-item {
padding: 0 !important;
} }
} }
\ No newline at end of file
...@@ -76,6 +76,7 @@ const AssetTree = (props) => { ...@@ -76,6 +76,7 @@ const AssetTree = (props) => {
}, },
callback: data => { callback: data => {
setCheckedKeys(data.dirIds||[]); setCheckedKeys(data.dirIds||[]);
onCheck && onCheck(data.dirIds||[]);
}, },
}) })
} }
......
...@@ -207,7 +207,7 @@ const AttributeRelationModal = (props) => { ...@@ -207,7 +207,7 @@ const AttributeRelationModal = (props) => {
name={element.id||''} name={element.id||''}
key={index} key={index}
> >
<Select> <Select allowClear>
{ {
(attributes||[]).map((attribute, _index) => { (attributes||[]).map((attribute, _index) => {
return ( return (
......
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Row, Col, Checkbox, Typography, Space, Button, Switch } from 'antd'; import { Row, Col, Checkbox, Typography, Button, Switch, Modal } from 'antd';
import { dispatch } from '../../../../model'; import { dispatch } from '../../../../model';
import './FilterElement.less'; import './FilterElementModal.less';
const FilterElement = (props) => { const FilterElementModal = (props) => {
const { onCancel } = props; const { visible, onCancel } = props;
const [ elements, setElements ] = useState([]); const [ elements, setElements ] = useState([]);
const [ typesOfElements, setTypesOfElements ] = useState([]); const [ typesOfElements, setTypesOfElements ] = useState([]);
const [ selectedKeys, setSelectedKeys ] = useState([]); const [ selectedKeys, setSelectedKeys ] = useState([]);
const [ confirmLoading, setConfirmLoading ] = useState(false);
useEffect(() => { useEffect(() => {
if (visible) {
getAllFilterElementIdsThenGetAllElements(); getAllFilterElementIdsThenGetAllElements();
}
//eslint-disable-next-line react-hooks/exhaustive-deps //eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, [visible]);
const getAllFilterElementIdsThenGetAllElements = () => { const getAllFilterElementIdsThenGetAllElements = () => {
dispatch({ dispatch({
...@@ -87,19 +90,56 @@ const FilterElement = (props) => { ...@@ -87,19 +90,56 @@ const FilterElement = (props) => {
const onOk = () => { const onOk = () => {
setConfirmLoading(true);
dispatch({ dispatch({
type: 'assetmanage.setupFilterElementIds', type: 'assetmanage.setupFilterElementIds',
payload: { payload: {
data: selectedKeys data: selectedKeys
}, },
callback: () => { callback: () => {
onCancel && onCancel(false, true); reset();
onCancel && onCancel(true);
},
error: () => {
reset();
} }
}) })
} }
const cancel = () => {
reset();
onCancel && onCancel();
}
const reset = () => {
setConfirmLoading(false);
}
return ( return (
<div className='filter-element' style={{ width: 500 }}> <Modal
forceRender
visible={visible}
title='资产要素过滤'
width={520}
onCancel={cancel}
footer={[
<Button
key="0"
onClick={cancel}
>
取消
</Button>,
<Button
key="1"
type="primary"
onClick={onOk}
loading={confirmLoading}
>
确定
</Button>,
]}
>
<div className='d-flex'> <div className='d-flex'>
<Switch <Switch
checkedChildren="全不选" checkedChildren="全不选"
...@@ -108,13 +148,13 @@ const FilterElement = (props) => { ...@@ -108,13 +148,13 @@ const FilterElement = (props) => {
style={{ marginLeft: 'auto' }} style={{ marginLeft: 'auto' }}
/> />
</div> </div>
<div style={{ maxHeight: 450, overflow: 'auto' }}> <div className='mt-3' style={{ maxHeight: 450, overflow: 'auto' }}>
{ {
(typesOfElements||[]).map((typeOfElements, index) => { (typesOfElements||[]).map((typeOfElements, index) => {
const _type = typeOfElements.type||''; const _type = typeOfElements.type||'';
return ( return (
<div> <div key={index}>
<div className='flex' style={{ alignItems: 'center', padding: '15px 0' }}> <div className='flex' style={{ alignItems: 'center', padding: '15px 0' }}>
<div style={{ width: 3, height: 14, backgroundColor: '#0069AC', marginRight: 5 }} /> <div style={{ width: 3, height: 14, backgroundColor: '#0069AC', marginRight: 5 }} />
<span style={{ fontWeight: 'bold', color: '#464646' }}>{_type||''}</span> <span style={{ fontWeight: 'bold', color: '#464646' }}>{_type||''}</span>
...@@ -141,16 +181,8 @@ const FilterElement = (props) => { ...@@ -141,16 +181,8 @@ const FilterElement = (props) => {
}) })
} }
</div> </div>
<div className='mt-3 d-flex pt-3' style={{ borderTop: '1px solid rgba(0, 0, 0, 0.06)' }} > </Modal>
<Space style={{ marginLeft: 'auto' }}>
<Button onClick={() => {
onCancel && onCancel();
}}>取消</Button>
<Button type='primary' onClick={onOk} >确定</Button>
</Space>
</div>
</div>
); );
} }
export default FilterElement; export default FilterElementModal;
\ No newline at end of file \ No newline at end of file
...@@ -19,7 +19,7 @@ const MetadataInfo = ({ value = '', config = true }) => { ...@@ -19,7 +19,7 @@ const MetadataInfo = ({ value = '', config = true }) => {
value => <span> value => <span>
{ {
(typeof metadata==='string') ? <span style={{ marginRight: 5 }}>{metadata||''}</span> : <a onClick={() => { (typeof metadata==='string') ? <span style={{ marginRight: 5 }}>{metadata||''}</span> : <a onClick={() => {
value?.setGlobalState({ value?.setGlobalState && value?.setGlobalState({
message: 'data-govern-show-metadata-message', message: 'data-govern-show-metadata-message',
data: metadata data: metadata
}) })
......
...@@ -7,7 +7,7 @@ import { showMessage } from '../../../../util'; ...@@ -7,7 +7,7 @@ import { showMessage } from '../../../../util';
const AssetMount = (props) => { const AssetMount = (props) => {
const { onCancel, visible, id, recycleIds, refrence = 'asset-manage' } = props; const { onCancel, visible, ids, refrence = 'asset-manage' } = props;
const [ dirIds, setDirIds ] = useState([]); const [ dirIds, setDirIds ] = useState([]);
const [ confirmLoading, setConfirmLoading ] = useState(false); const [ confirmLoading, setConfirmLoading ] = useState(false);
...@@ -28,7 +28,7 @@ const AssetMount = (props) => { ...@@ -28,7 +28,7 @@ const AssetMount = (props) => {
params: { params: {
dirId: dirIds.join(","), dirId: dirIds.join(","),
}, },
data: (refrence==='asset-recycle') ? recycleIds : [id||''] data: ids
}, },
callback: data => { callback: data => {
setConfirmLoading(false); setConfirmLoading(false);
...@@ -48,7 +48,7 @@ const AssetMount = (props) => { ...@@ -48,7 +48,7 @@ const AssetMount = (props) => {
return( return(
<Modal <Modal
title='挂载详情' title='变更目录详情'
visible={ visible } visible={ visible }
width={ 400 } width={ 400 }
confirmLoading={ confirmLoading } confirmLoading={ confirmLoading }
...@@ -63,7 +63,7 @@ const AssetMount = (props) => { ...@@ -63,7 +63,7 @@ const AssetMount = (props) => {
checkable={true} checkable={true}
showCustom={false} showCustom={false}
onCheck={onCheck} onCheck={onCheck}
tableId={refrence==='asset-manage'?id:''} tableId={(refrence==='asset-manage'&&(ids||[].length>0))?ids[0]:''}
reference='mount' reference='mount'
{...props} {...props}
/> />
......
...@@ -3,7 +3,6 @@ import { Table, Pagination, Space, Tooltip, Button, Modal } from 'antd'; ...@@ -3,7 +3,6 @@ import { Table, Pagination, Space, Tooltip, Button, Modal } from 'antd';
import { ReconciliationOutlined, DeleteOutlined, UndoOutlined } from '@ant-design/icons'; import { ReconciliationOutlined, DeleteOutlined, UndoOutlined } from '@ant-design/icons';
import { dispatchLatest } from '../../../model'; import { dispatchLatest } from '../../../model';
import AssetDetail from '../AssetManage/Component/AssetDetail';
import AssetMount from './Component/AssetMount'; import AssetMount from './Component/AssetMount';
import { showMessage } from '../../../util'; import { showMessage } from '../../../util';
...@@ -16,7 +15,6 @@ const AssetRecycle = (props) => { ...@@ -16,7 +15,6 @@ const AssetRecycle = (props) => {
const [ total, setTotal ] = useState(0); const [ total, setTotal ] = useState(0);
const [ pagination, setPagination ] = useState( { pageNum: 1, pageSize: 20 } ); const [ pagination, setPagination ] = useState( { pageNum: 1, pageSize: 20 } );
const [ currentAssetId, setCurrentAssetId ] = useState(''); const [ currentAssetId, setCurrentAssetId ] = useState('');
const [ assetDetailVisible, setAssetDetailVisible ] = useState(false);
const [ assetMountVisible, setAssetMountVisible ] = useState(false); const [ assetMountVisible, setAssetMountVisible ] = useState(false);
const [ selectedRowKeys, setSelectedRowKeys ] = useState([]); const [ selectedRowKeys, setSelectedRowKeys ] = useState([]);
const [ batchMount, setBatchMount ] = useState(false); const [ batchMount, setBatchMount ] = useState(false);
...@@ -108,15 +106,7 @@ const AssetRecycle = (props) => { ...@@ -108,15 +106,7 @@ const AssetRecycle = (props) => {
const detailItem = (record) => { const detailItem = (record) => {
setCurrentAssetId(record.id); setCurrentAssetId(record.id);
window.open(`/center-home/asset-detail?id=${record.id}`);
const index = selectedRowKeys.findIndex((rowKey) => rowKey === record.id);
if (index !== -1) {
const newSelectedRowKeys = [...selectedRowKeys];
newSelectedRowKeys.splice(index, 1);
setSelectedRowKeys(newSelectedRowKeys);
}
setAssetDetailVisible(true);
} }
const mountItem = (record) => { const mountItem = (record) => {
...@@ -179,10 +169,6 @@ const AssetRecycle = (props) => { ...@@ -179,10 +169,6 @@ const AssetRecycle = (props) => {
}); });
} }
const onAssetDetailCancel = () => {
setAssetDetailVisible(false);
}
const onAssetMountCancel = (refresh = false) => { const onAssetMountCancel = (refresh = false) => {
setAssetMountVisible(false); setAssetMountVisible(false);
...@@ -240,15 +226,10 @@ const AssetRecycle = (props) => { ...@@ -240,15 +226,10 @@ const AssetRecycle = (props) => {
showTotal={total => `共 ${total} 条`} showTotal={total => `共 ${total} 条`}
/> />
</div> </div>
<AssetDetail
visible={ assetDetailVisible }
id={ currentAssetId }
onCancel={ onAssetDetailCancel }
/>
<AssetMount <AssetMount
refrence='asset-recycle' refrence='asset-recycle'
visible={ assetMountVisible } visible={ assetMountVisible }
recycleIds={ batchMount ? selectedRowKeys : [ currentAssetId ] } ids={ batchMount ? selectedRowKeys : [ currentAssetId ] }
onCancel={ onAssetMountCancel } onCancel={ onAssetMountCancel }
{...props} {...props}
/> />
......
...@@ -48,9 +48,23 @@ const EditModel = (props) => { ...@@ -48,9 +48,23 @@ const EditModel = (props) => {
setActionData({ action: _action, catalogId: _catalogId, modelerId: _modelerId, hints: _hints, roughModelerData: _roughModelerData, permitCheckOut: _permitCheckOut, editable: _editable, stateId: _stateId, versionId: _versionId }); setActionData({ action: _action, catalogId: _catalogId, modelerId: _modelerId, hints: _hints, roughModelerData: _roughModelerData, permitCheckOut: _permitCheckOut, editable: _editable, stateId: _stateId, versionId: _versionId });
const interval = setInterval(() => {
heartbeat();
}, 10*60*1000);
return () => {
clearInterval(interval);
}
//eslint-disable-next-line react-hooks/exhaustive-deps //eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])
const heartbeat = () => {
dispatchLatest({
type: 'datamodel.heartbeat'
});
}
const save = async (e, cid = '') => { const save = async (e, cid = '') => {
try { try {
const row = await form.validateFields(); const row = await form.validateFields();
......
...@@ -83,7 +83,7 @@ const ImportActionHeader = (props) => { ...@@ -83,7 +83,7 @@ const ImportActionHeader = (props) => {
setAutoTranslate((modelerData.name||'')===''); setAutoTranslate((modelerData.name||'')==='');
if (modelerData) { if (modelerData) {
form.setFieldsValue(modelerData); form?.setFieldsValue(modelerData);
} }
//eslint-disable-next-line react-hooks/exhaustive-deps //eslint-disable-next-line react-hooks/exhaustive-deps
...@@ -159,7 +159,7 @@ const ImportActionHeader = (props) => { ...@@ -159,7 +159,7 @@ const ImportActionHeader = (props) => {
}, },
callback: data => { callback: data => {
if ((data?.translated||'') !== '') { if ((data?.translated||'') !== '') {
form.setFieldsValue({ name: data?.translated||'' }); form?.setFieldsValue({ name: data?.translated||'' });
} }
onChange && onChange(changedValues, allValues); onChange && onChange(changedValues, allValues);
} }
......
...@@ -753,7 +753,7 @@ const ImportActionTable = (props) => { ...@@ -753,7 +753,7 @@ const ImportActionTable = (props) => {
} }
{ {
record?.isPossibleNewTerm?.possible && <Typography.Link className='mr-3' onClick={() => { record?.isPossibleNewTerm?.possible && <Typography.Link className='mr-3' onClick={() => {
value?.setGlobalState({ value?.setGlobalState && value?.setGlobalState({
message: 'data-govern-show-standard-create', message: 'data-govern-show-standard-create',
data: { data: {
column: record, column: record,
......
...@@ -135,7 +135,7 @@ const ModelTable = (props) => { ...@@ -135,7 +135,7 @@ const ModelTable = (props) => {
if (record?.state?.id === '2') { if (record?.state?.id === '2') {
editTip = '待发布的模型不允许编辑'; editTip = '待发布的模型不允许编辑';
} else if (record?.state?.id === '4') { } else if (record?.state?.id === '4') {
editTip = '已发布模型下存在未发布的模型,不允许再编辑'; editTip = `${record.holder||''}正在编辑中, 不允许再编辑`;
} }
} }
......
...@@ -45,7 +45,7 @@ class Model extends React.Component { ...@@ -45,7 +45,7 @@ class Model extends React.Component {
hints: [], hints: [],
loadingStates: false, loadingStates: false,
modelStates: [], modelStates: [],
currentModelState: '4', currentModelState: '',
currentView: '', currentView: '',
exportDDLModalReference: 'exportDDL', exportDDLModalReference: 'exportDDL',
currentModel: {}, currentModel: {},
...@@ -72,8 +72,7 @@ class Model extends React.Component { ...@@ -72,8 +72,7 @@ class Model extends React.Component {
callback: data => { callback: data => {
this.setState({ this.setState({
loadingStates: false, loadingStates: false,
// modelStates: [{ name: 'all', id: '', cnName: '所有状态' }, ...(data?.subCatalogs||[])] modelStates: [{ name: 'all', id: '', cnName: '所有状态' }, ...(data?.subCatalogs||[])]
modelStates: data?.subCatalogs||[],
}); });
}, },
error: () => { error: () => {
...@@ -93,9 +92,9 @@ class Model extends React.Component { ...@@ -93,9 +92,9 @@ class Model extends React.Component {
}) })
} }
onTreeSelect = (key, offset) => { onTreeSelect = (key, offset=null) => {
this.setState({ catalogId: key, keyword: '', offset }, () => { this.setState({ catalogId: key, keyword: '', offset, currentModelState: (offset!==null)?'':this.state.currentModelState }, () => {
if (!key || key==='') { if (!key || key==='') {
this.setState({ tableData: [], filterTableData: [] }); this.setState({ tableData: [], filterTableData: [] });
} else { } else {
...@@ -110,12 +109,18 @@ class Model extends React.Component { ...@@ -110,12 +109,18 @@ class Model extends React.Component {
this.setState({ loadingTableData: true }, () => { this.setState({ loadingTableData: true }, () => {
if (keyword === '') { if (keyword === '') {
if (currentView === 'dir') { if (currentView === 'dir') {
const params = {
easyDataModelerCatalogId: catalogId,
};
if (currentModelState !== '') {
params.stateId = currentModelState;
}
dispatchLatestHomepage({ dispatchLatestHomepage({
type: 'datamodel.getCurrentDataModelCatalog', type: 'datamodel.getCurrentDataModelCatalog',
payload: { payload: params,
easyDataModelerCatalogId: catalogId,
stateId: currentModelState
},
callback: data => { callback: data => {
this.setState({ loadingTableData: false, tableData: data.easyDataModelerDataModels||[], filterTableData: data.easyDataModelerDataModels||[] }); this.setState({ loadingTableData: false, tableData: data.easyDataModelerDataModels||[], filterTableData: data.easyDataModelerDataModels||[] });
}, },
...@@ -138,12 +143,18 @@ class Model extends React.Component { ...@@ -138,12 +143,18 @@ class Model extends React.Component {
}) })
} }
} else { } else {
const params = {
term: keyword,
};
if (currentModelState !== '') {
params.stateId = currentModelState;
}
dispatchLatestHomepage({ dispatchLatestHomepage({
type: 'datamodel.searchModel', type: 'datamodel.searchModel',
payload: { payload: params,
term: keyword,
stateId: currentModelState
},
callback: data => { callback: data => {
this.setState({ loadingTableData: false, tableData: data||[], filterTableData: data||[] }); this.setState({ loadingTableData: false, tableData: data||[], filterTableData: data||[] });
}, },
......
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