Commit 5d8f2420 by zhaochengxiang

去掉不用的代码

parent 9ea2318b
......@@ -23,7 +23,7 @@ import TagCell from '../Model/Component/tag-help'
import { MetadataColumn } from '../AssetResourceManage/table'
import AssetDetailDrawer from '../AssetManage/Component/AssetDetailDrawer'
import '../AssetManage/Component/AssetTable.less'
import '../AssetManage/table.less'
const FC = (props) => {
const { node, onFullScreenChange } = props
......
import React, { useEffect, useState, useRef, useMemo } from 'react';
import {Card, Spin, Tooltip, Tree, Dropdown, Menu, Modal, AutoComplete} from 'antd';
import { PlusOutlined, ImportOutlined,ExportOutlined,ReloadOutlined, SettingOutlined } from '@ant-design/icons';
import classNames from 'classnames';
import { useContextMenu, Menu as RcMenu, Item as RcItem } from "react-contexify";
import { dispatch } from '../../../../model';
import ImportDirectory from './ImportDirectory';
import UpdateDirectoryModal from './UpdateDirectoryModal';
import CustomDirectoryModal from './CustomDirectoryModal';
import { showMessage, getQueryParam, getAssetRange } from '../../../../util';
import { AnchorTimestamp, AnchorId, AssetManageReference, AssetBrowseReference, ResourceBrowseReference, AssetMountReference, AnchorDirId } from '../../../../util/constant';
import { highlightSearchContentByTerms } from '../../../../util';
import PermissionRcItem from '../../../../util/Component/PermissionRcItem';
import './AssetManageTree.less';
import 'react-contexify/dist/ReactContexify.css';
const { Option } = AutoComplete;
function updateTreeData(list, key, children) {
return list.map((node) => {
if (node.nodeId === key) {
return { ...node, children };
}
if (node.children) {
return {
...node,
children: updateTreeData(node.children, key, children),
};
}
return node;
});
}
const AssetManageTree = (props) => {
const MENU_ID = 'asset-manage-tree';
const { show } = useContextMenu({
id: MENU_ID,
});
const { checkable = false, onSelect, className, onCheck, tableId, reference=AssetManageReference, onDirectoryChange, centerId } = props;
const [ keyword, setKeyword ] = useState('');
const [ loading, setLoading ] = useState(false);
const [ treeData, setTreeData ] = useState([]);
const [ dataList, setDataList ] = useState([]);
const [ groupIds, setGroupIds ] = useState([]);
const [ expandedKeys, setExpandedKeys ] = useState([]);
const [ checkedKeys, setCheckedKeys ] = useState([]);
const [ autoExpandParent, setAutoExpandParent ] = useState(false);
const [ currentDirId, setCurrentDirId ] = useState('');
const [ currentDirType, setCurrentDirType ] = useState('');
const [ currentRightClickDir, setCurrentRightClickDir ] = useState({});
const [ importDirectoryVisible, setImportDirectoryVisible ] = useState(false);
const [ updateDirectoryModalVisible, setUpdateDirectoryModalVisible ] = useState(false);
const [ updateDirectoryAction, setUpdateDirectoryAction ] = useState('');
const [ customDirectoryModalVisible, setCustomDirectoryModalVisible ] = useState(false);
const [ customDirectoryAction, setCustomDirectoryAction ] = useState('');
const [options, setOptions] = useState([]);
const [ loadedKeys, setLoadedKeys ] = useState([]);
const [ permissions, setPermissions ] = useState([]);
const [modal, contextHolder] = Modal.useModal();
const timestamp = getQueryParam(AnchorTimestamp, props?.location?.search);
const id = getQueryParam(AnchorId, props?.location?.search);
const did = getQueryParam(AnchorDirId, props?.location?.search);
const treeDataRef = useRef([]);
const dataListRef = useRef([]);
useEffect(() => {
getPermissions();
window?.addEventListener("storage", storageChange);
return () => {
window?.removeEventListener("storage", storageChange);
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
useEffect(() => {
if ((did||'') !== '') {
getAllDirectoryAsTree(true, did);
} else if ((id||'') !== '') {
getDataAssetLocationThenGetTreeData();
} else {
getAllDirectoryAsTree(true);
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [timestamp])
useEffect(() => {
if ((tableId||'') !== '') {
getTableDirIds();
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [tableId])
useEffect(() => {
if ((centerId||'')!=='' && centerId!==currentDirId) {
treeDirectoryChanged(centerId);
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [centerId])
const havePermission = useMemo(() => {
return (permissions||[]).findIndex(item => item === 'dirManage') !== -1
}, [permissions])
const storageChange = (e) => {
if (e.key === 'assetDirChangeEvent' || e.key === 'assetPathOnClickEvent') {
if ((e.dirId||'') !== '') {
treeDirectoryChanged(e.dirId);
}
} else if (e.key === 'assetRelationOnClickEvent') {
treeDirectoryChanged(e.relation?.dirId);
}
}
const getPermissions = () => {
if (!getAssetRange(reference)) return;
dispatch({
type: 'assetmanage.getPrivilegeByRange',
payload: {
range: getAssetRange(reference),
},
callback: data => {
setPermissions(data);
}
});
}
const getDataAssetLocationThenGetTreeData = () => {
setLoading(true);
dispatch({
type: 'assetmanage.getDataAssetLocation',
payload: {
dataAssetId: id
},
callback: data => {
getAllDirectoryAsTree(true, data.dirId||'');
},
error: () => {
setLoading(false);
getAllDirectoryAsTree(true);
}
});
}
const getTableDirIds = () => {
dispatch({
type: 'assetmanage.getDataAssetDetail',
payload: {
dataAssetId: tableId,
range: getAssetRange(AssetManageReference),
},
callback: data => {
setCheckedKeys(data.dirIds||[]);
setExpandedKeys(data.dirIds||[]);
setAutoExpandParent(true);
onCheck && onCheck(data.dirIds||[]);
},
})
}
const getAllDirectoryAsTree = (resetCurrentDirId=true, defaultSelectedId='') => {
setLoading(true);
if (resetCurrentDirId) {
onSelect && onSelect('', '');
}
let url = '';
if (reference === AssetManageReference) {
url = 'assetmanage.queryAllDirectoryAsTree';
}
if (reference === AssetMountReference) {
url = 'assetmanage.queryResourceDirectoryAsTree';
}
dispatch({
type: url,
callback: data => {
setLoading(false);
let newData = [...data];
if (reference === AssetMountReference) {
newData = newData.filter(item => item.resourceType!=='custom');
}
setLoadedKeys([]);
setTreeData(newData);
const _dataList = [], _groupIds = [];
generateList(newData, _dataList);
generateGroupIds(newData, _groupIds);
setDataList(_dataList);
setGroupIds(_groupIds);
treeDataRef.current = newData;
dataListRef.current = _dataList;
let defaultItem = null;
if ((defaultSelectedId||'') === '') {
_dataList.forEach(item => {
if ((defaultSelectedId||'')==='') {
defaultSelectedId = item.key;
}
})
}
function recursion(subCatalogs) {
if ((subCatalogs||[]).length===0) return;
(subCatalogs||[]).forEach(catalog=> {
if (catalog.nodeId === defaultSelectedId) {
defaultItem = catalog;
}
recursion(catalog.children);
})
}
if ((defaultSelectedId||'') !== '') {
recursion(newData);
}
if (resetCurrentDirId) {
if (defaultItem) {
const expandedKeys = _dataList
.map(item => {
if (item.key.indexOf(defaultSelectedId) > -1) {
return getParentKey(item.key, newData);
}
return null;
})
.filter((item, i, self) => item && self.indexOf(item) === i);
setExpandedKeys([...expandedKeys, defaultSelectedId]);
setAutoExpandParent(true);
setCurrentDirId(defaultItem.nodeId);
setCurrentDirType(defaultItem.type||'');
onSelect && onSelect(defaultItem.nodeId, defaultItem.type||'', defaultItem.level);
}
}
},
error: () => {
setLoading(false);
}
});
}
const treeDirectoryChanged = (did) => {
let defaultItem = null;
function recursion(subCatalogs) {
if ((subCatalogs||[]).length===0) return;
(subCatalogs||[]).forEach(catalog=> {
if (catalog.nodeId === did) {
defaultItem = catalog;
}
recursion(catalog.children);
})
}
if ((did||'') !== '') {
recursion(treeDataRef.current);
}
if (defaultItem) {
const expandedKeys = (dataListRef.current||[])
.map(item => {
if (item.key.indexOf(did) > -1) {
return getParentKey(item.key, treeDataRef.current);
}
return null;
})
.filter((item, i, self) => item && self.indexOf(item) === i);
setExpandedKeys([...expandedKeys, did]);
setAutoExpandParent(true);
setCurrentDirId(defaultItem.nodeId);
setCurrentDirType(defaultItem.type||'');
onSelect && onSelect(defaultItem.nodeId, defaultItem.type||'', defaultItem.level);
}
}
const generateList = (treeData, list, path = null) => {
for (let i = 0; i < treeData.length; i++) {
if (treeData[i].resourceType !== 'custom') {
const node = treeData[i];
const { nodeId, text } = node;
const currentPath = path ? `${path}/${text}` : text;
list.push({ key: nodeId , title: text, value: currentPath, level: node.level });
if (node.children) {
generateList(node.children, list, currentPath);
}
}
}
};
const generateGroupIds = (treeData, list) => {
function generateGroupItem(data, list) {
for (let i = 0; i < data.length; i++) {
const node = data[i];
list.push(node.nodeId);
if (node.children) {
generateGroupItem(node.children, list);
}
}
}
for (let i = 0; i < treeData.length; i++) {
const channelTreeData = treeData[i];
if (channelTreeData.children) {
for (let j =0; j < channelTreeData.children.length; j++) {
const node = channelTreeData.children[j];
const { nodeId } = node;
const groupItem = [nodeId];
if (node.children) {
generateGroupItem(node.children, groupItem);
}
list.push(groupItem);
}
}
}
};
const getParentKey = (key, tree) => {
let parentKey;
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
if (node.children) {
if (node.children.some(item => item.nodeId === key)) {
parentKey = node.nodeId;
} else if (getParentKey(key, node.children)) {
parentKey = getParentKey(key, node.children);
}
}
}
return parentKey;
};
const getCurrentType = (key, tree) => {
let type = '';
(tree||[]).forEach(node => {
if (node.nodeId === key) {
type = node.type||'';
} else if (node.children) {
if (getCurrentType(key, node.children)) {
type = getCurrentType(key, node.children);
}
}
})
return type;
}
const addDir = () => {
if (!havePermission || currentDirType==='custom') return;
setUpdateDirectoryAction('add');
setUpdateDirectoryModalVisible(true);
}
const editDir = () => {
if ((currentDirType||'') === '') {
setUpdateDirectoryAction('edit');
setUpdateDirectoryModalVisible(true);
} else if (currentDirType === 'custom') {
setCustomDirectoryAction('edit');
setCustomDirectoryModalVisible(true);
}
}
const refreshTree = () => {
getAllDirectoryAsTree(false);
}
const importDir = () => {
if (!havePermission || currentDirType==='custom') return;
setImportDirectoryVisible(true);
}
const exportAllDir = () => {
window.open('/api/dataassetmanager/directoryApi/export');
}
const exportCurrentDir = () => {
if(currentDirId){
dispatch({
type: 'assetmanage.getDirectoryById',
payload: {
dirId: currentDirId
},
callback: data => {
window.open(`/api/dataassetmanager/directoryApi/export?parentPath=${data.path}`);
}
})
} else {
showMessage("warn","请选择目录")
}
}
const deleteDir = () => {
if (currentRightClickDir.nodeId) {
modal.confirm({
title: '提示',
content: '节点下可能包含资产信息,删除后将把资产从该目录上移除,确定继续吗?',
onOk: () => {
dispatch({
type: 'assetmanage.deleteDirectory',
payload: {data: [ currentRightClickDir.nodeId ]},
callback: () => {
showMessage("success","删除成功");
getAllDirectoryAsTree(true, (currentRightClickDir.nodeId===currentDirId)?'':currentDirId);
}
})
}
})
} else {
showMessage('info', '请先选择目录');
}
}
const moveNode = (steps) => {
if ((currentRightClickDir.nodeId||'') === '') {
showMessage('info', '请先选择目录');
return;
}
setLoading(true);
dispatch({
type: 'assetmanage.upDownDirectory',
payload: {
params: {
dirId: currentRightClickDir.nodeId,
steps
}
},
callback: () => {
showMessage('success', (steps===1)?'上移目录成功':'下移目录成功');
getAllDirectoryAsTree(false);
},
error: () => {
setLoading(false);
}
});
}
const customDir = () => {
if (!havePermission) return;
setCustomDirectoryAction('add');
setCustomDirectoryModalVisible(true);
}
// const onChange = (e) => {
// const { value } = e.target;
// if (value === '') {
// setExpandedKeys([]);
// setAutoExpandParent(false);
// setKeyword(value);
// return;
// }
// const expandedKeys = dataList
// .map(item => {
// if (item.title.indexOf(value) > -1) {
// return getParentKey(item.key, treeData);
// }
// return null;
// })
// .filter((item, i, self) => item && self.indexOf(item) === i);
// setExpandedKeys(expandedKeys);
// setAutoExpandParent(true);
// setKeyword(value);
// }
const onTreeSelect = (keys, { node }) => {
if ((keys||[]).length === 0) {
return;
}
setCurrentDirId(keys[0]);
const _currentDirType = getCurrentType(keys[0], treeData);
setCurrentDirType(_currentDirType);
onSelect && onSelect(keys[0], _currentDirType, node.level);
}
const onTreeCheck = (values, e) => {
//同一主题下只能挂载一个目录
if (e.node?.level === 1) {
showMessage('warn', '栏目不允许勾选');
return;
}
const _checkedKeysValue = [...(values.checked||[])];
if (e.checked) {
const _currentNodeId = e.node?.key;
let _groupItem = [];
groupIds.forEach(groupItem => {
groupItem.forEach(id => {
if (id === _currentNodeId) {
_groupItem = groupItem;
}
})
})
const _filterKeys = (_checkedKeysValue.filter(item => item===_currentNodeId || !(_groupItem.includes(item))));
setCheckedKeys(_filterKeys);
onCheck && onCheck(_filterKeys);
} else {
setCheckedKeys(_checkedKeysValue);
onCheck && onCheck(_checkedKeysValue);
}
}
const onExpand = (expandedKeys) => {
setExpandedKeys(expandedKeys);
setAutoExpandParent(false);
};
const onUpdateDirectoryCancel = (refresh=false, id) => {
setUpdateDirectoryModalVisible(false);
if (refresh) {
if (updateDirectoryAction === 'add') {
getAllDirectoryAsTree(true, id);
} else {
getAllDirectoryAsTree();
onDirectoryChange && onDirectoryChange();
}
}
}
const onImportDirectoryCancel = (refresh=false, resetCurrentDirId=false) => {
setImportDirectoryVisible(false);
refresh && getAllDirectoryAsTree(resetCurrentDirId);
}
const onCustomDirectoryCancel = (refresh=false, id='') => {
setCustomDirectoryModalVisible(false);
if (refresh) {
if (customDirectoryAction === 'add') {
getAllDirectoryAsTree(true, id);
} else {
getAllDirectoryAsTree(false);
}
}
}
const displayMenu = (e) => {
show(e, {
position: {
x: e.clientX + 30,
y: e.clientY - 10
}
});
}
const onAutoCompleteSearch = (searchText) => {
setKeyword(searchText);
setOptions(
!searchText ? [] : (dataList||[]).filter(item => item.value.indexOf(searchText)!==-1),
);
};
const onAutoCompleteSelect = (value, option) => {
const paths = value.split('/');
setKeyword(paths[paths.length-1]);
treeDirectoryChanged(option.key);
};
const onLoadData = ({ key, children }) =>
new Promise((resolve) => {
if (children) {
resolve();
return;
}
setLoadedKeys([...loadedKeys, key]);
dispatch({
type: 'assetmanage.getDirectoryChild',
payload: {
parentId: key,
},
callback: (data) => {
if (data && data.length>0) {
let newTreeData = updateTreeData(treeData, key, data);
setTreeData(newTreeData);
treeDataRef.current = newTreeData;
}
resolve();
},
error: () => {
resolve();
}
});
});
const exportMenu = (
<Menu>
<Menu.Item>
<div style={{ textAlign: 'center' }} onClick={() => exportAllDir()}>
导出所有
</div>
</Menu.Item>
<Menu.Item>
<div style={{ textAlign: 'center' }} onClick={() => exportCurrentDir()}>
导出选中目录
</div>
</Menu.Item>
</Menu>
);
const loop = (data, rootResourceType = null) =>
data.map(item => {
if (item.level === 1) {
rootResourceType = item.resourceType;
}
const title = (
<span
className={(item.level===1)?'title-color': 'text-color'}
>
{item.text}
{
//自定义类型栏目不统计资产数
(reference===AssetManageReference) && (item.level!==1||(item.level===1&&item.resourceType!=='custom')) && <span>{` (${item.dataAssetAndSubDirCount})`}</span>
}
</span>
);
if (item.children && item.children.length>0) {
return { ...item, ...{title, key: item.nodeId, children: loop(item.children, rootResourceType), className: (item.level===1)?'root':''} };
}
if (rootResourceType !== 'custom') {
return { ...item, ...{ title, key: item.nodeId, isLeaf: true, className: (item.level===1)?'root':'' }};
}
return { ...item, ...{ title, key: item.nodeId, children: null, className: (item.level===1)?'root':''}};
});
const classes = classNames('asset-manage-tree', className, {
'asset-manage-tree-read-only': (reference===AssetBrowseReference||reference===ResourceBrowseReference),
'asset-manage-tree-asset-mount-reference': reference===AssetMountReference,
});
return (
<Card
className={classes}
title={ (reference===AssetBrowseReference||reference===ResourceBrowseReference || reference===AssetMountReference) ? null : (
<div
className='flex px-2'
style={{
height: 40,
alignItems: 'center',
justifyContent: 'space-around',
}}
>
<Tooltip title={havePermission?"新增目录":"暂无权限"}>
<PlusOutlined className={(!havePermission||currentDirType==='custom')?'disable': 'default'} onClick={addDir} style={{ fontSize:16,cursor: (!havePermission||currentDirType==='custom')?'not-allowed':'pointer' }}/>
</Tooltip>
<Tooltip title="刷新目录">
<ReloadOutlined className='default' onClick={refreshTree} style={{ fontSize:16,cursor:'pointer' }} />
</Tooltip>
<Tooltip title={havePermission?"导入目录":"暂无权限"}>
<ImportOutlined className={(!havePermission||currentDirType==='custom')?'disable': 'default'} onClick={importDir} style={{ fontSize:16,cursor:(!havePermission||currentDirType==='custom')?'not-allowed':'pointer' }} />
</Tooltip>
<Dropdown overlay={havePermission?exportMenu:<></>} placement="bottomCenter" >
<Tooltip title={havePermission?"导出目录":"暂无权限"}>
<ExportOutlined className={(!havePermission)?'disable': 'default'} style={{ fontSize:16,cursor:'pointer',cursor:(!havePermission)?'not-allowed':'pointer' }} />
</Tooltip>
</Dropdown>
<Tooltip title={havePermission?"自定义目录":"暂无权限"}>
<SettingOutlined className={(!havePermission)?'disable': 'default'} onClick={customDir} style={{ fontSize:16,cursor:(!havePermission)?'not-allowed':'pointer' }} />
</Tooltip>
</div>
)}
bordered={false}
bodyStyle={{ padding: '10px 15px' }}
headStyle={{ padding: 0 }}
style={{ width: '100%' }}
>
<Spin spinning={loading}>
<AutoComplete
allowClear
value={keyword}
style={{ marginBottom: 10, width: '100%' }}
onSelect={onAutoCompleteSelect}
onSearch={onAutoCompleteSearch}
onClear={() => { setKeyword(''); }}
>
{
(options||[]).map((item, index) => {
return (
<Option key={item.key} value={item.value}>
<div style={{ whiteSpace: 'normal' }}>
{highlightSearchContentByTerms(item.value, [keyword])}
</div>
</Option>
);
})
}
</AutoComplete>
<Tree
checkable={checkable}
showLine={true}
showIcon={false}
onExpand={onExpand}
expandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
treeData={loop(treeData)}
loadData={onLoadData}
loadedKeys={loadedKeys}
selectedKeys={[currentDirId||'']}
onSelect={onTreeSelect}
onCheck={onTreeCheck}
checkedKeys={checkedKeys}
checkStrictly
onRightClick={({event, node}) => {
if (reference === AssetManageReference) {
setCurrentRightClickDir(node);
setCurrentDirType(node.type||'');
displayMenu(event);
}
}}
/>
</Spin>
<UpdateDirectoryModal
visible={ updateDirectoryModalVisible }
onCancel={ onUpdateDirectoryCancel }
action={ updateDirectoryAction }
dirId={ (updateDirectoryAction==='add')?currentDirId:currentRightClickDir.nodeId }
/>
<ImportDirectory
visible={ importDirectoryVisible }
onCancel={ onImportDirectoryCancel }
dirId={ currentDirId }
/>
<CustomDirectoryModal
visible={ customDirectoryModalVisible }
onCancel={ onCustomDirectoryCancel }
action={ customDirectoryAction }
dirId= { currentDirId }
/>
{
(reference!==AssetMountReference) && <RcMenu id={MENU_ID}>
{
currentRightClickDir && (currentRightClickDir.type!=='custom') && <PermissionRcItem
id="edit"
onClick={editDir}
defaultPermission={havePermission}
>
{ (currentRightClickDir.level===1)?'修改栏目':'修改目录' }
</PermissionRcItem>
}
<PermissionRcItem
id="up"
onClick={() => { moveNode(1); }}
defaultPermission={havePermission}
>
{ (currentRightClickDir.level===1)?'上移栏目':'上移目录' }
</PermissionRcItem>
<PermissionRcItem
id="down"
onClick={() => { moveNode(-1); }}
defaultPermission={havePermission}
>
{ (currentRightClickDir.level===1)?'下移栏目':'下移目录' }
</PermissionRcItem>
{
currentRightClickDir && (currentRightClickDir.type!=='custom'||(currentRightClickDir.type==='custom'&&currentRightClickDir.level===2)) && <PermissionRcItem
id="delete"
onClick={deleteDir}
defaultPermission={havePermission}
>
{ (currentRightClickDir.level===1)?'删除栏目':'删除目录' }
</PermissionRcItem>
}
</RcMenu>
}
{contextHolder}
</Card>
)
}
export default AssetManageTree;
\ No newline at end of file
@import '../../../../variables.less';
.asset-manage-tree {
.yy-card-head-title {
padding: 0;
}
.yy-tree{
height: calc(100vh - @header-height - @breadcrumb-height - 25px - 40px - 62px) !important;
overflow: auto !important;
}
// .root {
// display: flex;
// position: relative;
// width: 100%;
// background-color: #e7f2ff;
// margin-bottom: 3px;
// padding: 5px;
// align-items: center;
// .yy-tree-switcher {
// display: block;
// position: absolute;
// opacity: 0 !important;
// left: 0;
// top: 0;
// width: 100%;
// height: 100%;
// }
// .yy-tree-node-content-wrapper {
// margin-left: 20px;
// }
// }
// .yy-tree-indent .yy-tree-indent-unit:first-child {
// opacity: 0 !important;
// }
.site-tree-search-value {
color: #f50;
}
}
.asset-manage-tree-read-only {
.yy-tree {
height: calc(100vh - @header-height - @breadcrumb-height - 25px - 62px) !important;;
overflow: auto !important;
}
}
.asset-manage-tree-asset-mount-reference {
.yy-tree {
height: 400px !important;
overflow: auto !important;
}
}
\ No newline at end of file
import React,{ useState, useEffect, useRef, useMemo } from "react";
import { Button, Pagination, Space, Modal, Input, Table, Tooltip, Checkbox, Typography, Dropdown, Menu, Select } from "antd";
import classNames from 'classnames';
import { Resizable } from 'react-resizable';
import ResizeObserver from 'rc-resize-observer';
import { useContextMenu, Menu as RcMenu, Item as RcItem } from "react-contexify";
import LocalStorage from 'local-storage';
import FilterElementModal from './FilterElementModal';
import AssetMount from '../../AssetRecycle/Component/AssetMount';
import ImportAssetDrawer from './ImportAssetDrawer';
import AssetEdit from './AddAssetModel';
import AssetDetailDrawer from "./AssetDetailDrawer";
import { dispatch, dispatchLatestHomepage } from '../../../../model';
import { showMessage, showNotifaction, getQueryParam, inputWidth, isSzseEnv, getAssetRange } from '../../../../util';
import { AnchorId, AnchorDirId, AnchorTimestamp, AssetBrowseReference, AssetManageReference, AssetRecycleReference, ResourceBrowseReference } from '../../../../util/constant';
import { FullScreenSvg, CancelFullScreenSvg } from './AssetSvg';
import AssetDeleteModal from './AssetDeleteModal';
import PermissionButton from '../../../../util/Component/PermissionButton';
import PermissionRcItem from '../../../../util/Component/PermissionRcItem';
import PermissionMenuItem from '../../../../util/Component/PermissionMenuItem';
import "./AssetTable.less";
import 'react-contexify/dist/ReactContexify.css';
const { Text } = Typography;
const { Search } = Input;
const { Column } = Table;
//资产项
const AssetItem = (props) => {
const { metadata } = props;
let content = '';
if (typeof metadata==='string') {
content = metadata;
} else {
(metadata?.columnItems||[]).forEach((item, index) => {
content += ((index===0)?'':',') + (((item.metadataColumnCnName||'')!=='')?(item.metadataColumnCnName||''):(item.metadataColumnName||''));
})
}
const cols = [
{
title: '序号',
dataIndex: 'key',
render: (text, record, index) => {
return (index+1).toString();
},
width: 60,
ellipsis: true,
},
{
title: '字段中文名称',
width: 160,
dataIndex: 'metadataColumnCnName',
editable: true,
ellipsis: true,
},
{
title: '字段英文名称',
width: 160,
dataIndex: 'metadataColumnName',
editable: true,
ellipsis: true,
},
];
return (
<Tooltip
overlayClassName='tooltip-common'
title={(typeof metadata==='string') ? (content||'') : <div style={{ width: 500 }}>
<Table
dataSource={metadata?.columnItems||[]}
columns={cols}
loading={false}
pagination={false}
size='small'
/>
</div>}
>
<Text ellipsis={true}>
{content||''}
</Text>
</Tooltip>
);
}
const ResizeableHeaderCell = props => {
const { onResize, width, onClick, ...restProps } = props;
if (!width) {
return <th {...restProps} />;
}
return (
<Resizable
width={width}
height={0}
handle={
<span
className="react-resizable-handle"
onClick={(e) => {
e.stopPropagation();
}}
/>
}
onResize={onResize}
draggableOpts={{ enableUserSelectHack: false }}
>
<th
onClick={onClick}
{...restProps}
/>
</Resizable>
);
};
const AssetTable = (props) => {
const { className, nodeId, nodeType, nodeLevel, elementsChanged, assetActionChanged, onSelect, onCountChange, reference = AssetManageReference, onFullScreenChange } = props;
const MENU_ID = 'asset-table';
const { show } = useContextMenu({
id: MENU_ID,
});
const [ loading, setLoading ] = useState(false);
const [ columns, setColumns ] = useState([]);
const [ realColumns, setRealColumns ] = useState([]);
const [ assets, setAssets ] = useState([]);
const [ total, setTotal ] = useState(0);
const [ selectItem, setSelectItem ] = useState({});
const [ contextMenuItem, setContextMenuItem ] = useState({});
const [ checkedKeys, setCheckedKeys ] = useState([]);
const [ importAssetVisible, setImportAssetVisible ] = useState(false);
const [ filterElementVisible, setFilterElementVisible ] = useState(false);
const [ assetEditVisible, setAssetEditVisible ] = useState(false);
const [ assetMountVisible, setAssetMountVisible ] = useState(false);
const [ assetDetailDrawerVisible, setAssetDetailDrawerVisible ] = useState(false);
// const [ currentAssetId, setCurrentAssetId ] = useState('');
const [ pagination, setPagination ] = useState( { pageNum: 1, pageSize: 20 } );
const { pageNum, pageSize } = pagination;
const [ keyword, setKeyword ] = useState('');
const [ batchCatalogChange, setBatchCatalogChange ] = useState(false);
const [ fullScreen, setFullScreen ] = useState(false);
const [ recursive, setRecursive ] = useState(true);
const [ fullSearch, setFullSearch ] = useState(false);
const [ TableWidth, setTableWidth ] = useState(0);
const [ compact, setCompact ] = useState(false);
const [ assetDeleteModalVisible, setAssetDeleteModalVisible ] = useState(false);
const [ permissions, setPermissions ] = useState([]);
const [ modal, contextHolder ] = Modal.useModal();
const anchorId = getQueryParam(AnchorId, props?.location?.search);
const timestamp = getQueryParam(AnchorTimestamp, props?.location?.search);
const anchorDid = getQueryParam(AnchorDirId, props?.location?.search);
const shouldScrollRef = useRef(false);
const metadataIndexRef = useRef('');
const remoteRelationRef = useRef(null);
useEffect(() => {
if (TableWidth>0 && columns.length>0) {
const currentWidth = (columns.reduce((preVal, col) => (col.width?col.width:0) + preVal, 0)) + 32.0;
if (currentWidth < TableWidth) {
columns.forEach(column => {
column.width = (TableWidth - 32.0)/columns.length;
})
}
setRealColumns([...columns, <Column key='auto' />]);
} else {
setRealColumns([]);
}
}, [columns, TableWidth])
useEffect(() => {
window?.addEventListener("storage", storageChange);
return () => {
window?.removeEventListener("storage", storageChange);
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
useEffect(() => {
if ((nodeId||'') !== '' ) {
setSelectItem({});
setCheckedKeys([]);
getPermissions();
if (shouldScrollRef.current === true) {
if (remoteRelationRef.current) {
getDataAssetLocationByRelation();
} else {
getDataAssetLocation();
}
} else {
setPagination({ ...pagination, pageNum: 1 });
}
} else if (reference === AssetRecycleReference) {
getRecyclePermissions();
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [ nodeId, reference ])
useEffect(() => {
if ((anchorId||'') !== '') {
shouldScrollRef.current = true;
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [timestamp])
useEffect(() => {
if ((nodeId||'') !== '' || reference===AssetRecycleReference) {
getFilterElementsGroupThenGetDataAssets();
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [ keyword, pagination, elementsChanged, assetActionChanged, recursive, fullSearch ])
const canAdd = useMemo(() => {
const allowIndex = (permissions||[]).findIndex(item => item==='add');
return (allowIndex !== -1);
}, [permissions])
const canImport = useMemo(() => {
let _canImport = true;
if ((checkedKeys||[]).length === 0) {
const allowIndex = (permissions||[]).findIndex(item => item==='import');
_canImport = (allowIndex !== -1);
} else {
checkedKeys?.forEach(key => {
const index = (assets||[]).findIndex(item => item.id === key);
if (index !== -1) {
const allowIndex = (assets[index].allowButtons||[]).findIndex(item => item==='import');
_canImport = (allowIndex !== -1);
}
});
}
return _canImport;
}, [assets, checkedKeys, permissions])
const canExport = useMemo(() => {
let _canExport = true;
if ((checkedKeys||[]).length === 0) {
const allowIndex = (permissions||[]).findIndex(item => item==='export');
_canExport = (allowIndex !== -1);
} else {
checkedKeys?.forEach(key => {
const index = (assets||[]).findIndex(item => item.id === key);
if (index !== -1) {
const allowIndex = (assets[index].allowButtons||[]).findIndex(item => item==='export');
_canExport = (allowIndex !== -1);
}
});
}
return _canExport;
}, [assets, checkedKeys, permissions])
const canChangeDir = useMemo(() => {
let _canChangeDir = true;
checkedKeys?.forEach(key => {
const index = (assets||[]).findIndex(item => item.id === key);
if (index !== -1) {
const allowIndex = (assets[index].allowButtons||[]).findIndex(item => item==='changeDir');
_canChangeDir = (allowIndex !== -1);
}
})
return _canChangeDir;
}, [assets, checkedKeys])
const canDelete= useMemo(() => {
let _canDelete = true;
checkedKeys?.forEach(key => {
const index = (assets||[]).findIndex(item => item.id === key);
if (index !== -1) {
const allowIndex = (assets[index].allowButtons||[]).findIndex(item => item==='delete');
_canDelete = (allowIndex !== -1);
}
})
return _canDelete;
}, [assets, checkedKeys])
const storageChange = (e) => {
if (e.key === 'assetRelationOnClickEvent') {
remoteRelationRef.current = e.relation;
shouldScrollRef.current = true;
} else if (e.key === 'assetPathOnClickEvent') {
remoteRelationRef.current = {
dataAssetId: e.id,
dirId: e.dirId
};
shouldScrollRef.current = true;
}
}
const getPermissions = () => {
dispatch({
type: 'assetmanage.getPrivilegeByRangeAndDirId',
payload: {
range: getAssetRange(reference),
optionId: nodeId
},
callback: data => {
setPermissions(data);
}
});
}
const getRecyclePermissions = () => {
dispatch({
type: 'assetmanage.getPrivilegeByRange',
payload: {
range: getAssetRange(reference),
},
callback: data => {
setPermissions(data);
}
});
}
const getDataAssetLocationByRelation = () => {
setLoading(true);
dispatch({
type: 'assetmanage.getDataAssetLocation',
payload: {
dataAssetId: remoteRelationRef.current?.dataAssetId,
dirId: remoteRelationRef.current?.dirId,
},
callback: data => {
const anchorLocation = data.offset;
const _pageNum = parseInt(anchorLocation/pageSize + ((anchorLocation%pageSize===0)?0:1));
setPagination({ ...pagination, pageNum: _pageNum });
},
error: () => {
setLoading(false);
remoteRelationRef.current = null;
setPagination({ ...pagination, pageNum: 1 });
}
});
}
const getDataAssetLocation = () => {
setLoading(true);
dispatch({
type: 'assetmanage.getDataAssetLocation',
payload: {
dataAssetId: anchorId||'',
dirId: anchorDid||'',
},
callback: data => {
const anchorLocation = data.offset;
const _pageNum = parseInt(anchorLocation/pageSize + ((anchorLocation%pageSize===0)?0:1));
setPagination({ ...pagination, pageNum: _pageNum });
},
error: () => {
setLoading(false);
setPagination({ ...pagination, pageNum: 1 });
}
});
}
const changeCurrent = (page,size) => {
setCheckedKeys([]);
setPagination({ pageNum: page, pageSize: size });
}
const getFilterElementsGroupThenGetDataAssets = () => {
setLoading(true);
dispatch({
type: 'assetmanage.listFilterElementsGroupByType',
payload: {
range: getAssetRange(reference)
},
callback: data => {
let _columns = [];
let index = 0, _metadataIndex = '';
(data||[]).forEach(group => {
(group.names||[]).forEach((name, i) => {
index++;
const params = {
title: name,
dataIndex: `element${index}`,
ellipsis: true,
width: 120,
render: (text, record) => {
return (
<Tooltip title={text||''}>
<Text ellipsis={true}>
{text||''}
</Text>
</Tooltip>
);
}
};
if (name === '编号') {
params.width = 60;
// params.fixed = 'left';
} else if (name === '中文名称') {
params.width = isSzseEnv?230:160;
// params.fixed = 'left';
} else if (name === '英文名称') {
params.width = isSzseEnv?224:160;
// 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.render = (metadata, _) => {
return (
<AssetItem metadata={metadata} />
);
}
_metadataIndex = `element${index}`;
} else if (name === '资产路径') {
params.render = (text, record) => {
return (
<Tooltip title={text||''}>
<Text ellipsis={true}>
<a onClick={()=>{
let event = new Event('storage');
event.key = 'assetDirChangeEvent';
event.dirId = record.dirId||'';
window?.dispatchEvent(event);
}}>
{text||''}
</a>
</Text>
</Tooltip>
);
}
}
_columns.push(params);
})
})
setAssets([]);
setColumns(_columns);
metadataIndexRef.current = _metadataIndex;
getDataAssets(_metadataIndex);
},
error: () => {
setLoading(false)
}
})
}
const getDataAssets = (projectIndex = metadataIndexRef.current) => {
setLoading(true);
let params = {
dirId: nodeId,
pageNum,
pageSize,
keyword: keyword,
range: getAssetRange(reference),
};
if (reference !== AssetRecycleReference) {
params.recursive = recursive;
//全局搜索资产
if (fullSearch) {
params.dirId = '';
}
}
let url = 'assetmanage.listDataAssetsByPage';
if (reference===AssetRecycleReference) {
url = 'assetmanage.listRecycleBinDataAssetsByPage';
} else if ((reference===AssetBrowseReference|| reference===ResourceBrowseReference)) {
params.checkPermission = true;
if (nodeType === 'custom') {
url = 'assetmanage.listDataAssetsByPersonalCustomType';
if (reference === AssetBrowseReference) {
params.resourceType = 'dataAsset';
} else if (reference === ResourceBrowseReference) {
params.resourceType = 'innerSource,outerSource';
}
}
}
dispatchLatestHomepage({
type: url,
payload: params,
callback: data => {
const _assets = [];
(data.data||[]).forEach(asset => {
let _asset = {...asset}, index = 0;
(asset.elementValues||[]).forEach((elementValue) => {
(elementValue.values||[]).forEach((value, i) => {
index++;
if (projectIndex === `element${index}`) {
let metadata = {};
try {
metadata = JSON.parse(value);
_asset['metadata'] = metadata;
_asset[`element${index}`] = metadata;
} catch(error) {
metadata = value;
_asset['metadata'] = metadata;
_asset[`element${index}`] = metadata;
}
} else {
_asset[`element${index}`] = value;
}
});
})
_assets.push(_asset);
})
setAssets(_assets);
if (shouldScrollRef.current) {
let scrollId = null;
if (remoteRelationRef.current) {
scrollId = remoteRelationRef.current.dataAssetId;
} else {
scrollId = anchorId;
}
shouldScrollRef.current = false;
setTimeout(() => {
var anchor = document.querySelector(`#data-asset-${scrollId}`);
anchor?.scrollIntoView();
}, 500)
}
if (reference === AssetManageReference) {
if (remoteRelationRef.current) {
const index = _assets.findIndex((asset) => asset.id === remoteRelationRef.current.dataAssetId);
remoteRelationRef.current = null;
if (index === -1) {
setSelectItem(_assets.length>0?_assets[0]:{});
onSelect && onSelect(_assets.length>0?_assets[0].id:'', _assets.length>0?_assets[0].dirId:'');
} else {
setSelectItem(_assets[index]);
onSelect && onSelect(_assets[index].id, _assets[index].dirId);
}
} else if ((selectItem?.id||'') !=='') {
const index = _assets.findIndex((asset) => asset.id === selectItem?.id);
if (index === -1) {
setSelectItem(_assets.length>0?_assets[0]:{});
onSelect && onSelect(_assets.length>0?_assets[0].id:'', _assets.length>0?_assets[0].dirId:'');
}
} else {
setSelectItem(_assets.length>0?_assets[0]:{});
onSelect && onSelect(_assets.length>0?_assets[0].id:'', _assets.length>0?_assets[0].dirId:'');
}
}
setTotal(data.total||0);
onCountChange && onCountChange(data.total||0);
setLoading(false);
},
error: () => {
setLoading(false)
}
})
}
const onSearchInputChange = (value) => {
setKeyword(value||'');
setPagination({ ...pagination, pageNum: 1 });
}
const addAsset =()=>{
setAssetEditVisible(true);
}
const onAssetEditCancel=(refresh = false) => {
setAssetEditVisible(false);
refresh && getDataAssets();
}
const onAssetMountCancel = (refresh = false) => {
setAssetMountVisible(false);
if (refresh) {
setCheckedKeys([]);
getDataAssets();
}
}
const importAsset = () => {
setImportAssetVisible(true);
}
const onFilterElementClick = () => {
setFilterElementVisible(true);
}
const onRecursiveChange = (e) => {
setRecursive(!e.target.checked);
}
const onFullSearchChange = (e) => {
setFullSearch(e.target.checked);
}
const exportAsset = () => {
if ((checkedKeys||[]).length === 0) {
modal.confirm({
title: '提示',
content: '是否导出选中目录下的所有资产?',
onOk: () => {
window.open(`/api/dataassetmanager/dataAssetApi/exportByDataAssetIds?dirId=${nodeId}&recursive=${recursive}`);
}
})
} else {
window.open(`/api/dataassetmanager/dataAssetApi/exportByDataAssetIds?dataAssetIds=${checkedKeys.join(',')}`);
}
}
// const detailAsset = (item)=>{
// setCurrentAssetId(item.id);
// window.open(`/center-home/asset-detail?id=${item.id}&dirId=${nodeId}`);
// }
const deleteAssets = () => {
if ((checkedKeys||[]).length > 0) {
if (reference === AssetManageReference) {
setAssetDeleteModalVisible(true);
} else {
modal.confirm({
title: '提示',
content: '您确定要永久删除这些资产吗?',
onOk: () => {
let payload = {
data: checkedKeys
}
dispatch({
type: 'assetmanage.deleteDataAssets',
payload,
callback: () => {
showMessage("success","删除成功");
getDataAssets();
setCheckedKeys([]);
},
error: () => {
}
})
}
})
}
}else{
showMessage("warn","请先选择资产")
}
}
const onImportAssetCancel = () => {
setImportAssetVisible(false);
}
const onImportAssetSuccess = (tip = '') => {
getDataAssets();
if ((tip||'') !== '') {
showNotifaction('导入提示', tip, 5);
}
}
const onFilterElementModalCancel = (refresh = false) => {
setFilterElementVisible(false);
refresh && getFilterElementsGroupThenGetDataAssets();
}
const onAssetDetailDrawerCancel = () => {
setAssetDetailDrawerVisible(false);
}
const onBatchCatalogChangeBtnClick = () => {
setBatchCatalogChange(true);
setAssetMountVisible(true);
}
const onAssetDeleteModalCancel = () => {
setAssetDeleteModalVisible(false);
}
const onAssetDeleteModalDelete = () => {
setAssetDeleteModalVisible(false);
const asssetIdsAndDirIds = [];
(assets||[]).forEach(asset => {
if (checkedKeys.indexOf(asset.id) !== -1) {
asssetIdsAndDirIds.push({ dataAssetId: asset.id||'', dirId: asset.dirId||'' });
}
})
let payload = {
data: asssetIdsAndDirIds
};
dispatch({
type: 'assetmanage.unloadDataAssets',
payload,
callback: () => {
showMessage("success","删除成功");
getDataAssets();
setCheckedKeys([]);
}
})
}
const onAssetDeleteModalDeleteAll = () => {
setAssetDeleteModalVisible(false);
let payload = {
data: checkedKeys
};
dispatch({
type: 'assetmanage.unloadDataAssetsFromAllDirs',
payload,
callback: () => {
showMessage("success","删除成功");
getDataAssets();
setCheckedKeys([]);
}
})
}
const recoveryAssets = () => {
if ((checkedKeys||[]).length > 0) {
modal.confirm({
title: '提示',
content: '您确定要恢复这些资产吗?',
onOk: () => {
let payload = {
data: checkedKeys
}
dispatch({
type: 'assetmanage.recoveryFromRecycleBin',
payload,
callback: (data) => {
if (data?.message) {
showNotifaction('提示', data?.message, 5);
}
getDataAssets();
setCheckedKeys([]);
}
})
}
})
}else{
showMessage("warn","请选择资产");
}
}
const onSelectChange = keys => {
setCheckedKeys(keys);
};
const onFullScreenClick = () => {
setFullScreen(!fullScreen);
onFullScreenChange && onFullScreenChange(!fullScreen);
}
const handleResize = index => (e, { size }) => {
const nextColumns = [...realColumns];
nextColumns[index] = {
...nextColumns[index],
width: size.width,
};
setRealColumns(nextColumns);
};
const displayMenu = (e) => {
show(e);
}
const handleItemClick = ({ event, props, data, triggerEvent }) => {
const key = event.currentTarget.id;
if (key === 'uncombed') {
modal.confirm({
title: '提示',
content: '是否将该条非资产的资源转为未梳理状态?',
onOk: () => {
dispatch({
type: 'assetmanage.updateResourceState',
payload: {
params: {
dataAssetId: contextMenuItem.id,
resourceState: 'uncombed'
}
},
callback: () => {
LocalStorage.set('assetResourceChange', !(LocalStorage.get('assetResourceChange')||false));
let event = new Event('storage');
event.key = 'assetResourceChange';
window?.dispatchEvent(event);
getDataAssets();
}
});
}
});
} else if (key === 'notRelatedAsset') {
modal.confirm({
title: '提示',
content: '是否将该条未梳理的资源转为非资产?',
onOk: () => {
dispatch({
type: 'assetmanage.updateResourceState',
payload: {
params: {
dataAssetId: contextMenuItem.id,
resourceState: 'notRelatedAsset'
}
},
callback: () => {
LocalStorage.set('assetResourceChange', !(LocalStorage.get('assetResourceChange')||false));
let event = new Event('storage');
event.key = 'assetResourceChange';
window?.dispatchEvent(event);
getDataAssets();
}
});
}
});
}
}
const onMenuClick = ({ key }) => {
console.log('key', key);
if (key === 'import') {
importAsset();
} else if (key === 'export') {
exportAsset();
} else if (key === 'changeDir') {
onBatchCatalogChangeBtnClick();
} else if (key === 'delete') {
deleteAssets();
} else if (key === 'colConfig') {
onFilterElementClick();
}
}
const moreMenu = (
<Menu onClick={onMenuClick}>
{
(reference===AssetManageReference && nodeType!=='custom') && <PermissionMenuItem key='import' defaultPermission={canImport}>
<div className='text-center'>
导入
</div>
</PermissionMenuItem>
}
{
(reference===AssetManageReference || reference===AssetRecycleReference) && <React.Fragment>
<PermissionMenuItem key='export' defaultPermission={canExport}>
<div className='text-center'>
导出
</div>
</PermissionMenuItem>
<PermissionMenuItem
key='changeDir'
defaultPermission={canChangeDir}
disabled={(checkedKeys||[]).length===0}
tip={(checkedKeys||[]).length===0?'请先选择资产':''}
>
<div className='text-center'>
变更目录
</div>
</PermissionMenuItem>
{
//自定义目录下的资产不允许新增 删除
(nodeType!=='custom') && <PermissionMenuItem
key='delete'
defaultPermission={canDelete}
disabled={(checkedKeys||[]).length===0}
tip={(checkedKeys||[]).length===0?'请先选择资产':''}
>
<div className='text-center'>
删除
</div>
</PermissionMenuItem>
}
</React.Fragment>
}
<Menu.Item key='colConfig'>
<div className='text-center'>
可见列设置
</div>
</Menu.Item>
</Menu>
);
const rowSelection = {
selectedRowKeys: checkedKeys,
onChange: onSelectChange,
};
const classes = classNames('asset-list', className, {
'asset-list-fullscreen': fullScreen,
});
let scrollY = null;
if ((assets||[]).length>0) {
if (fullScreen) {
scrollY = 'calc(100vh - 209px - 72px)';
} else if (reference===AssetManageReference) {
scrollY = 'calc(100vh - 209px - 123px - 15px - 72px)';
} else if (reference===AssetBrowseReference ||reference===ResourceBrowseReference) {
scrollY = 'calc(100vh - 209px - 94px - 15px - 72px)';
} else if (reference===AssetRecycleReference) {
scrollY = 'calc(100vh - 209px - 72px)';
}
}
const ResourceHead = (
<React.Fragment>
<Space>
<Button onClick={onFilterElementClick}>可见列设置</Button>
</Space>
<Space>
<Select
onChange={(value) => {
}}
style={{ width: 140 }}
>
<Select.Option value='current'>
当前目录
</Select.Option>
<Select.Option value='currentRecursive'>
当前及子孙目录
</Select.Option>
<Select.Option value='fullSearch'>
全部数据
</Select.Option>
</Select>
<Search
placeholder="请输入资产要素值"
allowClear
onSearch={onSearchInputChange}
enterButton
style={{ width: inputWidth }}
/>
<Tooltip title={fullScreen?'取消全屏':'全屏'}>
<Button onClick={onFullScreenClick} icon={fullScreen?<CancelFullScreenSvg style={{ width: 20, height: 20 }} />:<FullScreenSvg style={{ width: 20, height: 20 }} />} type='text'></Button>
</Tooltip>
</Space>
</React.Fragment>
)
const AssetHead = (
<React.Fragment>
<Space>
<Button onClick={onFilterElementClick}>可见列设置</Button>
</Space>
<Space>
<Select
onChange={(value) => {
}}
style={{ width: 140 }}
>
<Select.Option value='current'>
当前目录
</Select.Option>
<Select.Option value='currentRecursive'>
当前及子孙目录
</Select.Option>
<Select.Option value='fullSearch'>
全部数据
</Select.Option>
</Select>
<Search
placeholder="请输入资产要素值"
allowClear
onSearch={onSearchInputChange}
enterButton
style={{ width: inputWidth }}
/>
<Tooltip title={fullScreen?'取消全屏':'全屏'}>
<Button onClick={onFullScreenClick} icon={fullScreen?<CancelFullScreenSvg style={{ width: 20, height: 20 }} />:<FullScreenSvg style={{ width: 20, height: 20 }} />} type='text'></Button>
</Tooltip>
</Space>
</React.Fragment>
)
const RecycleHead = (
<React.Fragment>
<Space>
<PermissionButton
defaultPermission={canExport}
onClick={exportAsset}
>
导出
</PermissionButton>
<PermissionButton
onClick={onBatchCatalogChangeBtnClick}
disabled={(checkedKeys||[]).length===0}
permissionKey='loadDataAsset'
permissions={permissions}
tip={(checkedKeys||[]).length===0?'请先选择资产':''}
>
挂载
</PermissionButton>
<PermissionButton
onClick={recoveryAssets}
disabled={(checkedKeys||[]).length===0}
permissionKey='resumeDataAsset'
permissions={permissions}
tip={(checkedKeys||[]).length===0?'请先选择资产':''}
>
恢复
</PermissionButton>
<PermissionButton
defaultPermission={canDelete}
tip={(checkedKeys||[]).length===0?'请先选择资产':''}
onClick={deleteAssets}
disabled={(checkedKeys||[]).length===0}
>
删除
</PermissionButton>
<Button onClick={onFilterElementClick}>可见列设置</Button>
</Space>
<Space>
<Search
placeholder="请输入资产要素值"
allowClear
onSearch={onSearchInputChange}
enterButton
style={{ width: inputWidth }}
/>
</Space>
</React.Fragment>
)
return(
<div className={classes}>
<div
className='flex p-common'
style={{
alignItems: 'center',
justifyContent: 'space-between',
}}
>
{
reference === ResourceBrowseReference && ResourceHead
}
{
reference === AssetBrowseReference && AssetHead
}
{
reference === AssetRecycleReference && RecycleHead
}
</div>
<div
className='px-common'
>
<ResizeObserver
onResize={({ width }) => {
setTableWidth(width);
if (width < 1030 && !compact) {
setCompact(true);
} else if (width >= 1030 && compact) {
setCompact(false);
}
}}
>
<Table
rowSelection={rowSelection}
components={{
header: {
cell: ResizeableHeaderCell,
}
}}
onRow={(record) => {
return {
id: `data-asset-${record?.id}`,
onClick: (e) => {
setSelectItem(record);
onSelect && onSelect(record?.id, record?.dirId);
if (reference !== AssetManageReference) {
setAssetDetailDrawerVisible(true);
}
},
onContextMenu: event => {
if (reference===AssetManageReference && (record.resourceState==='uncombed'||record.resourceState==='notRelatedAsset')) {
setContextMenuItem(record);
displayMenu(event);
}
},
}
}}
rowClassName={(record, index) => {
if (record?.id===anchorId || record?.id===selectItem?.id) {
return 'yy-table-select-row';
}
return '';
}}
loading={loading}
columns={
(realColumns||[]).map((column, index) => {
return {
...column,
onHeaderCell: column => ({
width: column.width,
onResize: handleResize(index),
}),
};
})
}
rowKey='id'
dataSource={assets}
pagination={false}
size='default'
scroll={{ y: scrollY }}
/>
</ResizeObserver>
</div>
<Pagination
size="small"
className="text-center m-3"
showSizeChanger
showQuickJumper
onChange={changeCurrent}
onShowSizeChange={changeCurrent}
current={pageNum}
pageSize={pageSize}
defaultCurrent={1}
total={total}
showTotal={total => `共 ${total} 条`}
/>
<AssetEdit
visible={assetEditVisible}
nodeId={nodeId}
onCancel={onAssetEditCancel}
/>
<ImportAssetDrawer
visible={importAssetVisible}
nodeId={nodeId}
onCancel={onImportAssetCancel}
onSuccess={onImportAssetSuccess}
/>
<AssetMount
visible={ assetMountVisible }
reference={reference}
ids={ batchCatalogChange?checkedKeys:[] }
onCancel={ onAssetMountCancel }
{...props}
/>
<FilterElementModal
type={(reference===AssetManageReference)?'admin': 'user'}
reference={reference}
visible={ filterElementVisible }
onCancel={ onFilterElementModalCancel}
/>
<AssetDetailDrawer
id={selectItem?.id}
dirId={selectItem?.dirId}
reference={reference}
visible={assetDetailDrawerVisible}
onCancel={onAssetDetailDrawerCancel}
/>
<AssetDeleteModal
visible={assetDeleteModalVisible}
onCancel={onAssetDeleteModalCancel}
onDelete={onAssetDeleteModalDelete}
onDeleteAll={onAssetDeleteModalDeleteAll}
/>
<RcMenu id={MENU_ID}>
{
(contextMenuItem.resourceState==='notRelatedAsset') && <PermissionRcItem
id="uncombed"
permissionKey='changeToUncombed'
permissions={contextMenuItem?.allowButtons}
onClick={handleItemClick}
>
转为未梳理
</PermissionRcItem>
}
{
(contextMenuItem.resourceState==='uncombed') && <PermissionRcItem
id="notRelatedAsset"
permissionKey='changeToNotAsset'
permissions={contextMenuItem?.allowButtons}
onClick={handleItemClick}
>
转为非资产
</PermissionRcItem>
}
</RcMenu>
{contextHolder}
</div>
)
}
export default AssetTable;
\ No newline at end of file
import React, { useEffect, useState } from 'react';
import { Modal, Form, Input, Space, Button, Radio, Select } from 'antd';
import { dispatch } from '../../../../model';
import { showMessage } from '../../../../util';
const resourceTypes = [
{ key: 'innerSource', name: '内部资源' },
{ key: 'outerSource', name: '外部资源' },
{ key: 'dataAsset', name: '资产' },
{ key: 'custom', name: '自定义' },
]
const UpdateDirectoryModal = (props) => {
const { visible, onCancel, dirId, action } = props;
const [ form ] = Form.useForm();
const [ dir, setDir ] = useState(null);
const [ confirmLoading, setConfirmLoading ] = useState(false);
const [ isThemeAdd, setIsThemeAdd ] = useState(false);
useEffect(() => {
if (visible) {
setDir(null);
form.resetFields();
if ((dirId||'')!=='') {
getDirectory();
}
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [ visible ])
const getDirectory = () => {
setDir(null);
dispatch({
type: 'assetmanage.getDirectoryById',
payload: {
dirId
},
callback: data => {
setDir(data);
if (action !== 'add') {
form.setFieldsValue({ code: data?.code, name: data?.name||'', desc: data?.desc||'', remarks: data?.remarks||'', resourceType: data?.resourceType });
}
}
})
}
const onOk = async () => {
try {
const row = await form.validateFields();
setConfirmLoading(true);
let payload = {
data: {
code: row.code,
name: row.name,
desc: row.desc,
remarks: row.remarks,
resourceType: row.resourceType
}
};
if (action === 'add') {
if (row.type === 'directory') {
if (dir === null) {
showMessage('warn', '资产目录节点信息正在加载中...');
return;
}
payload = { ...payload, params: {
parentPath: dir.path||''
}};
} else {
payload.data.resourceType = row.resourceType;
}
} else {
if (dir === null) {
showMessage('warn', '资产目录节点信息正在加载中...');
return;
}
payload.data = { ...payload.data, ...{ order: dir.order, id: dirId } };
const parentPath = dir.path.substring(0, dir.path.lastIndexOf("/"));;
payload = { ...payload, params: {
parentPath
}};
}
dispatch({
type: 'assetmanage.addOrUpdateDirectory',
payload: payload,
callback: data => {
setConfirmLoading(false);
onCancel && onCancel(true, data?.id||'');
},
error: () => {
setConfirmLoading(false);
}
})
} catch (errInfo) {
console.log('Validate Failed:', errInfo);
}
}
const onReset = () => {
if(action === 'add') {
setIsThemeAdd(false);
form.resetFields();
} else {
if (dir === null) {
showMessage('warn', '资产目录节点信息正在加载中...');
return;
}
form.resetFields();
}
}
const onValuesChange = (changedValues, allValues) => {
if (action==='add') {
if (changedValues.type === 'theme') {
setIsThemeAdd(true);
} else if (changedValues.type === 'directory') {
setIsThemeAdd(false);
}
}
}
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 17 },
},
};
return (
<Modal
forceRender
title={'资产目录信息'}
visible={visible}
width={600}
onCancel={() => { onCancel && onCancel() }}
footer={
<Space>
<Button type="primary" onClick={onOk} loading={confirmLoading}>提交</Button>
<Button onClick={onReset} >重置</Button>
<Button onClick={() => onCancel && onCancel() }>返回</Button>
</Space>
}
>
<Form {...formItemLayout} form={form} onValuesChange={onValuesChange}>
{
action==='add' && <Form.Item
label="类型"
name="type"
rules={[{ required: true, message: '必填项' }]}
>
<Radio.Group>
<Radio value='theme'>栏目</Radio>
<Radio value='directory' disabled={ dirId===null }>目录</Radio>
</Radio.Group>
</Form.Item>
}
{
((action==='add'&&isThemeAdd) || action!=='add') && <Form.Item
label="资产类型"
name="resourceType"
rules={[{ required: false }]}
>
<Select allowClear>
{
resourceTypes.map((item,index) => {
return <Select.Option key={item.key}>{item.name}</Select.Option>
})
}
</Select>
</Form.Item>
}
<Form.Item
label="编号"
name="code"
rules={[{ required: true, message: '必填项' }]}
>
<Input placeholder="请输入编号" />
</Form.Item>
<Form.Item
label="名称"
name="name"
rules={[{ required: true, message: '必填项' }]}
>
<Input placeholder="请输入名称" />
</Form.Item>
{
action !== 'add' && (
<Form.Item
label="路径"
name="path"
>
<span>{ dir ? (dir.path||''):'' }</span>
</Form.Item>
)
}
<Form.Item
label="描述"
name="desc"
>
<Input.TextArea placeholder="请输入描述" autoSize={{ minRows: 4, maxRows: 4 }} />
</Form.Item>
<Form.Item
label="备注"
name="remarks"
>
<Input.TextArea placeholder="请输入备注" autoSize={{ minRows: 4, maxRows: 4 }} />
</Form.Item>
</Form>
</Modal>
);
}
export default UpdateDirectoryModal;
\ No newline at end of file
......@@ -27,7 +27,7 @@ import { AssetDirectorySubject } from './Component/AssetDirectory'
import { AssetActionSubject } from './Component/AssetAction'
import TagCell from '../Model/Component/tag-help'
import './Component/AssetTable.less'
import './table.less'
import { MetadataColumn } from '../AssetResourceManage/table'
const operationMap = {
......
@import '../../../../variables.less';
@import '../../../variables.less';
.asset-list {
background-color: #fff;
......
import React, { useState } from "react";
import { Modal } from "antd";
import { dispatch } from '../../../../model';
import AssetTree from '../../AssetManage/Component/AssetManageTree';
import { showMessage, showNotifaction } from '../../../../util';
import { AssetManageReference, AssetRecycleReference, AssetMountReference } from "../../../../util/constant";
const AssetMount = (props) => {
const { onCancel, visible, ids, reference = AssetManageReference } = props;
const [ dirIds, setDirIds ] = useState([]);
const [ confirmLoading, setConfirmLoading ] = useState(false);
const onCheck = (values) => {
setDirIds(values||[]);
}
const onOk = () => {
if ((dirIds||[]).length === 0) {
showMessage('warn', '请先选择资产目录');
return;
}
setConfirmLoading(true);
dispatch({
type: 'assetmanage.loadDataAssets',
payload: {
params: {
dirId: dirIds.join(","),
},
data: ids
},
callback: data => {
setConfirmLoading(false);
if (data?.message) {
showNotifaction('提示', data?.message, 5);
}
reset();
onCancel && onCancel(true);
},
error: () => {
setConfirmLoading(false);
}
})
}
const reset = () => {
setConfirmLoading(false);
}
return(
<Modal
title={(reference===AssetRecycleReference)?'挂载目录详情':'变更目录详情'}
visible={ visible }
width={ 400 }
confirmLoading={ confirmLoading }
onCancel={()=>{
reset();
onCancel && onCancel()
}}
onOk={ onOk }
>
<AssetTree
checkable={true}
onCheck={onCheck}
tableId={(reference===AssetManageReference&&(ids||[].length>0))?ids[0]:''}
reference={AssetMountReference}
/>
</Modal>
)
}
export default AssetMount;
\ No newline at end of file
......@@ -20,7 +20,7 @@ import TagCell from '../Model/Component/tag-help'
import { MetadataColumn } from '../AssetResourceManage/table'
import AssetDetailDrawer from '../AssetManage/Component/AssetDetailDrawer'
import '../AssetManage/Component/AssetTable.less'
import '../AssetManage/table.less'
const FC = () => {
const [args, setArgs] = React.useState(() => ({
......
......@@ -23,7 +23,7 @@ import TagCell from '../Model/Component/tag-help'
import { MetadataColumn } from '../AssetResourceManage/table'
import AssetDetailDrawer from '../AssetManage/Component/AssetDetailDrawer'
import '../AssetManage/Component/AssetTable.less'
import '../AssetManage/table.less'
const FC = (props) => {
const { node, onFullScreenChange } = props
......
......@@ -31,7 +31,7 @@ import RedistributeTask from './redistribute-task'
import AutoDistributeTask from './auto-distribute-task'
import CheckAssets from './check-assets'
import '../AssetManage/Component/AssetTable.less'
import '../AssetManage/table.less'
const operationMap = {
addAsAsset: '新增为资产',
......
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