Commit a1bbe440 authored by coderTomato's avatar coderTomato

前端右键菜单位置优化

parent b23cc76b
import React, {useEffect, useRef, useState} from "react"; import React, {useEffect, useState,Key} from "react";
import {connect} from "umi"; import {connect} from "umi";
import {DownOutlined, SwitcherOutlined, FrownOutlined, MehOutlined, SmileOutlined,FolderAddOutlined} from "@ant-design/icons"; import {DownOutlined, SwitcherOutlined, FolderAddOutlined} from "@ant-design/icons";
import {Tree, Input, Menu, Empty, Button, message, Modal,Tooltip,Row,Col} from 'antd'; import {Tree, Menu, Empty, Button, message, Modal,Tooltip,Row,Col} from 'antd';
import {getCatalogueTreeData} from "@/pages/FlinkSqlStudio/service"; import {getCatalogueTreeData} from "@/pages/FlinkSqlStudio/service";
import {convertToTreeData, DataType, getTreeNodeByKey, TreeDataNode} from "@/components/Studio/StudioTree/Function"; import {convertToTreeData, getTreeNodeByKey, TreeDataNode} from "@/components/Studio/StudioTree/Function";
import style from "./index.less"; import style from "./index.less";
import {StateType} from "@/pages/FlinkSqlStudio/model"; import {StateType} from "@/pages/FlinkSqlStudio/model";
import { import {
getInfoById, handleAddOrUpdate, handleAddOrUpdateWithResult, handleInfo, handleRemove, handleRemoveById, getInfoById, handleAddOrUpdate, handleAddOrUpdateWithResult, handleRemoveById,
handleSubmit handleSubmit
} from "@/components/Common/crud"; } from "@/components/Common/crud";
import UpdateCatalogueForm from './components/UpdateCatalogueForm'; import UpdateCatalogueForm from './components/UpdateCatalogueForm';
import {ActionType} from "@ant-design/pro-table";
import SimpleTaskForm from "@/components/Studio/StudioTree/components/SimpleTaskForm"; import SimpleTaskForm from "@/components/Studio/StudioTree/components/SimpleTaskForm";
import { Scrollbars } from 'react-custom-scrollbars'; import { Scrollbars } from "react-custom-scrollbars";
const { DirectoryTree } = Tree; const { DirectoryTree } = Tree;
const {Search} = Input;
type StudioTreeProps = { type StudioTreeProps = {
...@@ -34,26 +32,26 @@ type RightClickMenu = { ...@@ -34,26 +32,26 @@ type RightClickMenu = {
categoryName: string categoryName: string
}; };
const getParentKey = (key, tree) => { // const getParentKey = (key:any, tree:any) => {
let parentKey; // let parentKey;
for (let i = 0; i < tree.length; i++) { // for (let i = 0; i < tree.length; i++) {
const node = tree[i]; // const node = tree[i];
if (node.children) { // if (node.children) {
if (node.children.some(item => item.key === key)) { // if (node.children.some((item:any) => item.key === key)) {
parentKey = node.key; // parentKey = node.key;
} else if (getParentKey(key, node.children)) { // } else if (getParentKey(key, node.children)) {
parentKey = getParentKey(key, node.children); // parentKey = getParentKey(key, node.children);
} // }
} // }
} // }
return parentKey; // return parentKey;
}; // };
const StudioTree: React.FC<StudioTreeProps> = (props) => { const StudioTree: React.FC<StudioTreeProps> = (props) => {
const {rightClickMenu,dispatch,tabs,refs,toolHeight} = props; const {rightClickMenu,dispatch,tabs,refs,toolHeight} = props;
const [treeData, setTreeData] = useState<TreeDataNode[]>(); const [treeData, setTreeData] = useState<TreeDataNode[]>();
const [dataList, setDataList] = useState<[]>(); //const [dataList, setDataList] = useState<[]>();
const [expandedKeys, setExpandedKeys] = useState<[]>(); const [expandedKeys, setExpandedKeys] = useState<Key[]>();
const [rightClickNodeTreeItem,setRightClickNodeTreeItem] = useState<RightClickMenu>(); const [rightClickNodeTreeItem,setRightClickNodeTreeItem] = useState<RightClickMenu>();
const [updateCatalogueModalVisible, handleUpdateCatalogueModalVisible] = useState<boolean>(false); const [updateCatalogueModalVisible, handleUpdateCatalogueModalVisible] = useState<boolean>(false);
const [updateTaskModalVisible, handleUpdateTaskModalVisible] = useState<boolean>(false); const [updateTaskModalVisible, handleUpdateTaskModalVisible] = useState<boolean>(false);
...@@ -62,7 +60,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -62,7 +60,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
const [taskFormValues, setTaskFormValues] = useState({}); const [taskFormValues, setTaskFormValues] = useState({});
const [rightClickNode, setRightClickNode] = useState<TreeDataNode>(); const [rightClickNode, setRightClickNode] = useState<TreeDataNode>();
const [available, setAvailable] = useState<boolean>(true); const [available, setAvailable] = useState<boolean>(true);
let sref = React.createRef<Scrollbars>(); let sref:any = React.createRef<Scrollbars>();
const getTreeData = async () => { const getTreeData = async () => {
const result = await getCatalogueTreeData(); const result = await getCatalogueTreeData();
...@@ -72,12 +70,12 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -72,12 +70,12 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
list[i].title=list[i].name; list[i].title=list[i].name;
list[i].key=list[i].id; list[i].key=list[i].id;
} }
setDataList(list); // setDataList(list);
data = convertToTreeData(data, 0); data = convertToTreeData(data, 0);
setTreeData(data); setTreeData(data);
}; };
const openByKey = async (key)=>{ const openByKey = async (key:any)=>{
const result = await getCatalogueTreeData(); const result = await getCatalogueTreeData();
let data = result.datas; let data = result.datas;
let list = data; let list = data;
...@@ -85,7 +83,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -85,7 +83,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
list[i].title=list[i].name; list[i].title=list[i].name;
list[i].key=list[i].id; list[i].key=list[i].id;
} }
setDataList(list); //setDataList(list);
data = convertToTreeData(data, 0); data = convertToTreeData(data, 0);
setTreeData(data); setTreeData(data);
let node = getTreeNodeByKey(data,key); let node = getTreeNodeByKey(data,key);
...@@ -105,7 +103,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -105,7 +103,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
}else if(key=='CreateCatalogue'){ }else if(key=='CreateCatalogue'){
createCatalogue(rightClickNode); createCatalogue(rightClickNode);
}else if(key=='CreateRootCatalogue'){ }else if(key=='CreateRootCatalogue'){
createRootCatalogue(rightClickNode); createRootCatalogue();
}else if(key=='CreateTask'){ }else if(key=='CreateTask'){
createTask(rightClickNode); createTask(rightClickNode);
}else if(key=='Rename'){ }else if(key=='Rename'){
...@@ -115,13 +113,14 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -115,13 +113,14 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
} }
}; };
const toOpen=(node:TreeDataNode)=>{ const toOpen=(node:TreeDataNode|undefined)=>{
if(!available){return} if(!available){return}
setAvailable(false); setAvailable(false);
setTimeout(()=>{ setTimeout(()=>{
setAvailable(true); setAvailable(true);
},200); },200);
if(node.isLeaf&&node.taskId) { if(node?.isLeaf&&node.taskId) {
// @ts-ignore
for(let item of tabs.panes){ for(let item of tabs.panes){
if(item.key==node.taskId){ if(item.key==node.taskId){
dispatch&&dispatch({ dispatch&&dispatch({
...@@ -138,16 +137,16 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -138,16 +137,16 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
const result = getInfoById('/api/task',node.taskId); const result = getInfoById('/api/task',node.taskId);
result.then(result=>{ result.then(result=>{
let newTabs = tabs; let newTabs = tabs;
let newPane = { let newPane:any = {
title: node.name, title: node!.name,
key: node.taskId, key: node!.taskId,
value:(result.datas.statement?result.datas.statement:''), value:(result.datas.statement?result.datas.statement:''),
closable: true, closable: true,
path: node.path, path: node!.path,
task:{ task:{
session:'', session:'',
maxRowNum: 100, maxRowNum: 100,
jobName:node.name, jobName:node!.name,
useResult:false, useResult:false,
useSession:false, useSession:false,
useRemote:true, useRemote:true,
...@@ -158,8 +157,8 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -158,8 +157,8 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
}, },
monaco: React.createRef(), monaco: React.createRef(),
}; };
newTabs.activeKey = node.taskId; newTabs!.activeKey = node!.taskId;
newTabs.panes.push(newPane); newTabs!.panes!.push(newPane);
dispatch&&dispatch({ dispatch&&dispatch({
type: "Studio/saveTabs", type: "Studio/saveTabs",
payload: newTabs, payload: newTabs,
...@@ -168,13 +167,13 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -168,13 +167,13 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
} }
}; };
const createCatalogue=(node:TreeDataNode)=>{ const createCatalogue=(node:TreeDataNode|undefined)=>{
if(!node.isLeaf) { if(!node?.isLeaf) {
handleUpdateCatalogueModalVisible(true); handleUpdateCatalogueModalVisible(true);
setIsCreate(true); setIsCreate(true);
setCatalogueFormValues({ setCatalogueFormValues({
isLeaf: false, isLeaf: false,
parentId: node.id, parentId: node?.id,
}); });
getTreeData(); getTreeData();
}else{ }else{
...@@ -192,7 +191,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -192,7 +191,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
getTreeData(); getTreeData();
}; };
const toSubmit=(node:TreeDataNode)=>{ const toSubmit=(node:TreeDataNode|undefined)=>{
Modal.confirm({ Modal.confirm({
title: '提交作业', title: '提交作业',
content: '确定提交该作业到其配置的集群吗?', content: '确定提交该作业到其配置的集群吗?',
...@@ -200,7 +199,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -200,7 +199,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
cancelText: '取消', cancelText: '取消',
onOk:async () => { onOk:async () => {
let task = { let task = {
id:node.taskId, id:node?.taskId,
}; };
setTimeout(()=>{ setTimeout(()=>{
refs?.history?.current?.reload(); refs?.history?.current?.reload();
...@@ -210,22 +209,22 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -210,22 +209,22 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
}); });
}; };
const toRename=(node:TreeDataNode)=>{ const toRename=(node:TreeDataNode|undefined)=>{
handleUpdateCatalogueModalVisible(true); handleUpdateCatalogueModalVisible(true);
setIsCreate(false); setIsCreate(false);
setCatalogueFormValues({ setCatalogueFormValues({
id: node.id, id: node?.id,
name: node.name, name: node?.name,
}); });
getTreeData(); getTreeData();
}; };
const createTask=(node:TreeDataNode)=>{ const createTask=(node:TreeDataNode|undefined)=>{
if(!node.isLeaf) { if(!node?.isLeaf) {
handleUpdateTaskModalVisible(true); handleUpdateTaskModalVisible(true);
setIsCreate(true); setIsCreate(true);
setTaskFormValues({ setTaskFormValues({
parentId: node.id, parentId: node?.id,
}); });
//getTreeData(); //getTreeData();
}else{ }else{
...@@ -233,19 +232,19 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -233,19 +232,19 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
} }
}; };
const toDelete= (node:TreeDataNode)=>{ const toDelete= (node:TreeDataNode|undefined)=>{
let label = (node.taskId==null)?'目录':'作业'; let label = (node?.taskId==null)?'目录':'作业';
Modal.confirm({ Modal.confirm({
title: `删除${label}`, title: `删除${label}`,
content: `确定删除该${label}吗?`, content: `确定删除该${label}吗?`,
okText: '确认', okText: '确认',
cancelText: '取消', cancelText: '取消',
onOk:async () => { onOk:async () => {
await handleRemoveById('/api/catalogue',node.id); await handleRemoveById('/api/catalogue',node!.id);
if(node.taskId) { if(node?.taskId) {
dispatch({ dispatch({
type: "Studio/deleteTabByKey", type: "Studio/deleteTabByKey",
payload: node.taskId, payload: node?.taskId,
}); });
} }
getTreeData(); getTreeData();
...@@ -255,10 +254,10 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -255,10 +254,10 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
const getNodeTreeRightClickMenu = () => { const getNodeTreeRightClickMenu = () => {
const {pageX, pageY} = {...rightClickNodeTreeItem}; const {pageX, pageY} = {...rightClickNodeTreeItem};
const tmpStyle = { const tmpStyle:any = {
position: 'absolute', position: 'absolute',
left: `${pageX - 40}px`, left: pageX,
top: `${pageY - 150}px`, top: pageY,
}; };
let menuItems; let menuItems;
if(rightClickNode&&rightClickNode.isLeaf){ if(rightClickNode&&rightClickNode.isLeaf){
...@@ -309,10 +308,12 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -309,10 +308,12 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
}; };
const handleContextMenu = (e: React.MouseEvent, node: TreeDataNode) => { const handleContextMenu = (e: React.MouseEvent, node: TreeDataNode) => {
let position = e.currentTarget.getBoundingClientRect();
let scrollTop = document.documentElement.scrollTop;
setRightClickNode(node); setRightClickNode(node);
setRightClickNodeTreeItem({ setRightClickNodeTreeItem({
pageX: e.pageX, pageX: e.pageX-20,
pageY: e.pageY+sref.current.getScrollTop(), pageY: position.y+sref.current.getScrollTop()+scrollTop-115-position.height,
id: node.id, id: node.id,
categoryName: node.name categoryName: node.name
}); });
...@@ -322,7 +323,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -322,7 +323,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
}); });
}; };
const onSelect = (selectedKeys:[], e:any) => { const onSelect = (selectedKeys:Key[], e:any) => {
if(e.node&&e.node.isLeaf) { if(e.node&&e.node.isLeaf) {
dispatch({ dispatch({
type: "Studio/saveCurrentPath", type: "Studio/saveCurrentPath",
...@@ -336,7 +337,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -336,7 +337,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
setExpandedKeys([]); setExpandedKeys([]);
}; };
const onExpand=(expandedKeys:[])=>{ const onExpand=(expandedKeys:Key[])=>{
setExpandedKeys(expandedKeys); setExpandedKeys(expandedKeys);
}; };
......
...@@ -99,6 +99,15 @@ ...@@ -99,6 +99,15 @@
.ant-tabs > .ant-tabs-nav .ant-tabs-nav-more, .ant-tabs > div > .ant-tabs-nav .ant-tabs-nav-more { .ant-tabs > .ant-tabs-nav .ant-tabs-nav-more, .ant-tabs > div > .ant-tabs-nav .ant-tabs-nav-more {
padding: 8px; padding: 8px;
} }
/* --- 树文字显示 --- start */
.ant-tree-node-content-wrapper{
white-space: nowrap;
//max-width: 100%;
height: 15px;
overflow: hidden;
text-overflow-ellipsis: true;
}
} }
} }
/* --- tabs 垂直样式 --- end */ /* --- tabs 垂直样式 --- end */
......
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