diff --git a/dinky-web/src/pages/DataStudioNew/CenterTabContent/SqlTask.tsx b/dinky-web/src/pages/DataStudioNew/CenterTabContent/SqlTask.tsx index 79709851b4..ff825a4786 100644 --- a/dinky-web/src/pages/DataStudioNew/CenterTabContent/SqlTask.tsx +++ b/dinky-web/src/pages/DataStudioNew/CenterTabContent/SqlTask.tsx @@ -435,7 +435,7 @@ export const SqlTask = memo((props: FlinkSqlProps & any) => { }, [currentState, updateAction]); const handleStop = useCallback(async () => { - const result = await cancelTask('', currentState.taskId, false); + const result = await cancelTask(l('pages.datastudio.editor.stop.job'), currentState.taskId, false); if (result.success) { setCurrentState((prevState) => { return { diff --git a/dinky-web/src/pages/DataStudioNew/ContextMenuSpace.tsx b/dinky-web/src/pages/DataStudioNew/ContextMenuSpace.tsx new file mode 100644 index 0000000000..afed1a0fc0 --- /dev/null +++ b/dinky-web/src/pages/DataStudioNew/ContextMenuSpace.tsx @@ -0,0 +1,18 @@ +import {Space} from "antd"; +import React from "react"; + + +interface ContextMenuSpaceProps { + onContextMenu: (e: React.MouseEvent) => void; + children: React.ReactNode| JSX.Element | string; +} + +export const ContextMenuSpace = (props: ContextMenuSpaceProps) => { + + const {onContextMenu, children} = props; + return <> + + {children} + + +} diff --git a/dinky-web/src/pages/DataStudioNew/constants.tsx b/dinky-web/src/pages/DataStudioNew/constants.tsx new file mode 100644 index 0000000000..3254b29620 --- /dev/null +++ b/dinky-web/src/pages/DataStudioNew/constants.tsx @@ -0,0 +1,45 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { l } from '@/utils/intl'; +import { CloseCircleTwoTone, IssuesCloseOutlined } from '@ant-design/icons'; +import { Space } from 'antd'; +import { DefaultOptionType } from 'antd/es/select'; +import { MenuItemType } from 'rc-menu/lib/interface'; + +export const TAG_RIGHT_CONTEXT_MENU: MenuItemType[] = [ + { + key: 'closeAll', + label: ( + + + {l('right.menu.closeAll')} + + ) + }, + { + key: 'closeOther', + label: ( + + + {l('right.menu.closeOther')} + + ) + } +]; diff --git a/dinky-web/src/pages/DataStudioNew/function.tsx b/dinky-web/src/pages/DataStudioNew/function.tsx index 1ab64a712b..9c96b4ad5b 100644 --- a/dinky-web/src/pages/DataStudioNew/function.tsx +++ b/dinky-web/src/pages/DataStudioNew/function.tsx @@ -88,6 +88,7 @@ export const handleRightClick = ( e: any, stateAction: Dispatch> ) => { + e.preventDefault(); // 阻止浏览器默认的右键行为 let x = e.clientX; let y = e.clientY; // 判断右键的位置是否超出屏幕 , 如果超出屏幕则设置为屏幕的最大值 diff --git a/dinky-web/src/pages/DataStudioNew/index.tsx b/dinky-web/src/pages/DataStudioNew/index.tsx index dfaf6247be..9f1c7e5193 100644 --- a/dinky-web/src/pages/DataStudioNew/index.tsx +++ b/dinky-web/src/pages/DataStudioNew/index.tsx @@ -17,12 +17,12 @@ * */ -import { DockLayout, TabData } from 'rc-dock'; -import React, { lazy, useEffect, useMemo, useRef, useState } from 'react'; -import { PageContainer } from '@ant-design/pro-layout'; -import { Col, ConfigProvider, Row, Spin, theme, theme as antdTheme } from 'antd'; +import {DockLayout, TabData} from 'rc-dock'; +import React, {lazy, useEffect, useMemo, useRef, useState} from 'react'; +import {PageContainer} from '@ant-design/pro-layout'; +import {Col, ConfigProvider, Row, Space, Spin, theme as antdTheme} from 'antd'; import Toolbar from '@/pages/DataStudioNew/Toolbar'; -import { DataStudioActionType, RightContextMenuState } from '@/pages/DataStudioNew/data.d'; +import {DataStudioActionType, RightContextMenuState} from '@/pages/DataStudioNew/data.d'; import { getAllPanel, getLayoutState, @@ -32,25 +32,28 @@ import { } from '@/pages/DataStudioNew/function'; // import 'rc-dock/dist/rc-dock.css'; // import 'rc-dock/dist/rc-dock-dark.css'; -import RightContextMenu, { useRightMenuItem } from '@/pages/DataStudioNew/RightContextMenu'; -import { MenuInfo } from 'rc-menu/es/interface'; -import { lazyComponent, ToolbarRoutes } from '@/pages/DataStudioNew/Toolbar/ToolbarRoute'; -import { ToolbarPosition, ToolbarRoute } from '@/pages/DataStudioNew/Toolbar/data.d'; -import { groups } from '@/pages/DataStudioNew/ContentLayout'; -import { connect } from 'umi'; -import { CenterTab, DataStudioState } from '@/pages/DataStudioNew/model'; -import { mapDispatchToProps } from '@/pages/DataStudioNew/DvaFunction'; -import { AliveScope, KeepAlive, useAliveController } from 'react-activation'; -import { activeTab, createNewPanel } from '@/pages/DataStudioNew/DockLayoutFunction'; +import RightContextMenu, {useRightMenuItem} from '@/pages/DataStudioNew/RightContextMenu'; +import {MenuInfo} from 'rc-menu/es/interface'; +import {lazyComponent, ToolbarRoutes} from '@/pages/DataStudioNew/Toolbar/ToolbarRoute'; +import {ToolbarPosition, ToolbarRoute} from '@/pages/DataStudioNew/Toolbar/data.d'; +import {groups} from '@/pages/DataStudioNew/ContentLayout'; +import {connect} from 'umi'; +import {CenterTab, DataStudioState} from '@/pages/DataStudioNew/model'; +import {mapDispatchToProps} from '@/pages/DataStudioNew/DvaFunction'; +import {AliveScope, KeepAlive, useAliveController} from 'react-activation'; +import {activeTab, createNewPanel} from '@/pages/DataStudioNew/DockLayoutFunction'; import * as Algorithm from './Algorithm'; -import { PanelData } from 'rc-dock/lib/DockData'; -import { useAsyncEffect } from 'ahooks'; -import { useTheme } from '@/hooks/useThemeValue'; -import { DataStudioContext } from '@/pages/DataStudioNew/DataStudioContext'; +import {PanelData} from 'rc-dock/lib/DockData'; +import {useAsyncEffect} from 'ahooks'; +import {useTheme} from '@/hooks/useThemeValue'; +import {DataStudioContext} from '@/pages/DataStudioNew/DataStudioContext'; import './css/index.less'; -import { getTenantByLocalStorage } from '@/utils/function'; +import {getTenantByLocalStorage} from '@/utils/function'; import FooterContainer from '@/pages/DataStudioNew/FooterContainer'; -import { useToken } from 'antd/es/theme/internal'; +import {useToken} from 'antd/es/theme/internal'; +import {TAG_RIGHT_CONTEXT_MENU} from "@/pages/DataStudioNew/constants"; +import {ContextMenuSpace} from "@/pages/DataStudioNew/ContextMenuSpace"; + const SqlTask = lazy(() => import('@/pages/DataStudioNew/CenterTabContent/SqlTask')); const DataSourceDetail = lazy( () => import('@/pages/DataStudioNew/CenterTabContent/DataSourceDetail') @@ -79,15 +82,21 @@ const DataStudioNew: React.FC = (props: any) => { const [_, token] = useToken(); const dockLayoutRef = useRef(null); - const { drop } = useAliveController(); - const menuItem = useRightMenuItem({ dataStudioState }); + const {drop} = useAliveController(); + const menuItem = useRightMenuItem({dataStudioState}); - // 右键弹出框状态 + // 作业树右键弹出框状态 const [rightContextMenuState, setRightContextMenuState] = useState({ show: false, position: InitContextMenuPosition }); + // 标签右键弹出框状态 + const [rightContextTagMenuState, setRightContextTagMenuState] = useState({ + show: false, + position: InitContextMenuPosition + }); + const [loading, setLoading] = useState(true); const theme = useTheme() as 'realDark' | 'light'; const themeAlgorithm = useMemo(() => { @@ -123,10 +132,10 @@ const DataStudioNew: React.FC = (props: any) => { await queryFlinkUdfOptions(); await queryDataSourceDataList(); await querySuggestions(); - await queryUserData({ id: getTenantByLocalStorage() }); + await queryUserData({id: getTenantByLocalStorage()}); }, []); useEffect(() => { - const { actionType, params } = dataStudioState.action; + const {actionType, params} = dataStudioState.action; if (actionType?.includes('task-run-')) { const dockLayout = dockLayoutRef.current!!; let position: ToolbarPosition = 'leftBottom'; @@ -212,7 +221,7 @@ const DataStudioNew: React.FC = (props: any) => { const rightContextMenuHandle = (e: any) => handleRightClick(e, setRightContextMenuState); const handleMenuClick = (values: MenuInfo) => { - setRightContextMenuState((prevState) => ({ ...prevState, show: false })); + setRightContextMenuState((prevState) => ({...prevState, show: false})); switch (values.key) { case 'showToolbarDesc': @@ -258,12 +267,41 @@ const DataStudioNew: React.FC = (props: any) => { } }; + /** + * 标签右键菜单handle | the right-click menu handle of the tag + * @param e + */ + const rightContextTagMenuHandle = (e: any) => handleRightClick(e, setRightContextTagMenuState); + + + /** + * 右键菜单的点击事件 | right-click menu click event of the right-click menu + * @param {MenuInfo} node + */ + const handleTagRightMenuClick = (node: MenuInfo) => { + setRightContextTagMenuState((prevState) => ({...prevState, show: false})); + const {key} = node; + console.log('key', key,node); + switch (key) { + case 'closeAll': + console.log('closeAll'); + // handleCloseAllTabs(); + break; + case 'closeOther': + console.log('closeOther'); + // handleCloseOtherTabs(); + break; + default: + break; + } + }; + const saveTab = (tabData: TabData & any) => { - let { id, group, title } = tabData; - return { id, group, title }; + let {id, group, title} = tabData; + return {id, group, title}; }; const loadTab = (tab: TabData) => { - const { id, title, group } = tab; + const {id, title, group} = tab; if (group !== 'centerContent') { const route = ToolbarRoutes.find((x) => x.key === id) as ToolbarRoute; const content = ToolbarRoutes.find((item) => item.key === route.key)!!.content(); @@ -300,28 +338,30 @@ const DataStudioNew: React.FC = (props: any) => { switch (tabData.tabType) { case 'task': const titleContent = ( - <> + {getTabIcon(tabData.params.dialect, 19)} {tabData.title} - + ); if (tabData.isUpdate) { return ( - - {titleContent} - {' *'} - + + + {titleContent} + {' *'} + + ); } - return {titleContent}; + return {titleContent}; case 'dataSource': const dialect = tabData.params.type; return ( - <> + {getTabIcon(dialect, 19)} {tabData.title} - + ); default: - return <>{tabData.title}; + return {tabData.title}; } }; @@ -333,7 +373,7 @@ const DataStudioNew: React.FC = (props: any) => { // todo 添加中间tab内容 switch (tabData.tabType) { case 'task': - content = ; + content = ; break; case 'dataSource': content = ; @@ -419,7 +459,7 @@ const DataStudioNew: React.FC = (props: any) => { }); }; return ( - + { - + {/*左边工具栏*/} { onContextMenu={rightContextMenuHandle} > {/*左上工具栏*/} - + { {/* 中间内容栏*/} - + { // todo 这里移到方向会导致布局和算法异常,先暂时规避掉 if ( @@ -511,7 +551,7 @@ const DataStudioNew: React.FC = (props: any) => { currentTabId && direction === 'remove' && (dockLayoutRef.current?.find(currentTabId) as PanelData)?.group === - 'centerContent' + 'centerContent' ) { drop(currentTabId).then(); @@ -551,7 +591,7 @@ const DataStudioNew: React.FC = (props: any) => { {/*右边工具栏*/} @@ -566,18 +606,26 @@ const DataStudioNew: React.FC = (props: any) => { - + - {/*右键菜单*/} + {/* 树的右键菜单*/} - setRightContextMenuState((prevState) => ({ ...prevState, show: false })) + setRightContextMenuState((prevState) => ({...prevState, show: false})) } items={menuItem} onClick={handleMenuClick} /> + {/*标签的右键菜单*/} + setRightContextTagMenuState(prevState => ({...prevState, show: false}))} + /> @@ -586,7 +634,7 @@ const DataStudioNew: React.FC = (props: any) => { }; export default connect( - ({ DataStudio }: { DataStudio: DataStudioState }) => ({ + ({DataStudio}: { DataStudio: DataStudioState }) => ({ dataStudioState: DataStudio }), mapDispatchToProps diff --git a/dinky-web/src/pages/RegCenter/Resource/components/ResourceOverView/index.tsx b/dinky-web/src/pages/RegCenter/Resource/components/ResourceOverView/index.tsx index 9046a60cd9..582081d431 100644 --- a/dinky-web/src/pages/RegCenter/Resource/components/ResourceOverView/index.tsx +++ b/dinky-web/src/pages/RegCenter/Resource/components/ResourceOverView/index.tsx @@ -73,17 +73,17 @@ const ResourceOverView: React.FC = (props) => { ); }; - useAsyncEffect(() => { + useEffect(() => { dispatch({ type: CONFIG_MODEL_ASYNC.queryResourceConfig, payload: SettingConfigKeyEnum.RESOURCE.toLowerCase() }); }, []); - useAsyncEffect(async () => { + useEffect( () => { // if enableResource is true, then refresh the tree, otherwise do nothing if (enableResource) { - await refreshTree(); + refreshTree(); } }, [enableResource]);