Commit 61576e02 authored by godkaikai's avatar godkaikai

0.2.1

parent 58683396
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>dlink-client</artifactId> <artifactId>dlink-client</artifactId>
<groupId>com.dlink</groupId> <groupId>com.dlink</groupId>
<version>0.2.0</version> <version>0.3.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>dlink-client-1.12</artifactId> <artifactId>dlink-client-1.12</artifactId>
......
...@@ -59,12 +59,12 @@ ...@@ -59,12 +59,12 @@
<dependency> <dependency>
<groupId>com.dlink</groupId> <groupId>com.dlink</groupId>
<artifactId>dlink-client-1.12</artifactId> <artifactId>dlink-client-1.12</artifactId>
<scope>provided</scope> <!--<scope>provided</scope>-->
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.dlink</groupId> <groupId>com.dlink</groupId>
<artifactId>dlink-connector-jdbc</artifactId> <artifactId>dlink-connector-jdbc</artifactId>
<scope>provided</scope> <!--<scope>provided</scope>-->
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>
\ No newline at end of file
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
"nzh": "^1.0.3", "nzh": "^1.0.3",
"omit.js": "^2.0.2", "omit.js": "^2.0.2",
"react": "^17.0.0", "react": "^17.0.0",
"react-custom-scrollbars": "^4.2.1",
"react-dev-inspector": "^1.1.1", "react-dev-inspector": "^1.1.1",
"react-dom": "^17.0.0", "react-dom": "^17.0.0",
"react-helmet-async": "^1.0.4", "react-helmet-async": "^1.0.4",
......
...@@ -16,7 +16,7 @@ const { TabPane } = Tabs; ...@@ -16,7 +16,7 @@ const { TabPane } = Tabs;
const StudioConsole = (props:any) => { const StudioConsole = (props:any) => {
return ( return (
<Tabs defaultActiveKey="StudioMsg" size="small"> <Tabs defaultActiveKey="StudioMsg" size="small" tabPosition="bottom" style={{ border: "1px solid #f0f0f0"}}>
<TabPane <TabPane
tab={ tab={
<span> <span>
......
.edit-tabs{
:global {
.ant-tabs-nav, .ant-tabs-bottom > .ant-tabs-nav, .ant-tabs-top > div > .ant-tabs-nav, .ant-tabs-bottom > div > .ant-tabs-nav {
margin: 0;
}
}
}
import {message, Tabs } from 'antd'; import {message, Tabs } from 'antd';
import React, {useState} from 'react'; import React, {useState} from 'react';
import StudioEdit from "../StudioEdit";
import {connect} from "umi"; import {connect} from "umi";
import {StateType} from "@/pages/FlinkSqlStudio/model"; import {StateType} from "@/pages/FlinkSqlStudio/model";
import styles from './index.less';
const { TabPane } = Tabs; const { TabPane } = Tabs;
const EditorTabs = (props: any) => { const EditorTabs = (props: any) => {
const {tabs,dispatch} = props; const {tabs,dispatch,current} = props;
const [newTabIndex, setNewTabIndex] = useState<number>(0); const [newTabIndex, setNewTabIndex] = useState<number>(0);
const [activeKey, setActiveKey] = useState<number>(tabs.activeKey); const [activeKey, setActiveKey] = useState<number>(tabs.activeKey);
const [panes, setPanes] = useState<any>(tabs.panes); const [panes, setPanes] = useState<any>(tabs.panes);
...@@ -29,25 +29,19 @@ const EditorTabs = (props: any) => { ...@@ -29,25 +29,19 @@ const EditorTabs = (props: any) => {
const add = () => { const add = () => {
message.warn('敬请期待'); message.warn('敬请期待');
/*let index = newTabIndex + 1;
const newPanes = [...panes];
newPanes.push({ title: `未命名${index}`,value:'', key: -index });
setPanes(newPanes);
setActiveKey(-index);
setNewTabIndex(index);*/
}; };
const remove = (targetKey:any) => { const remove = (targetKey:any) => {
let newActiveKey = tabs.activeKey; let newActiveKey = tabs.activeKey;
let lastIndex = 0; let lastIndex = 0;
tabs.panes.forEach((pane, i) => { tabs.panes.forEach((pane, i) => {
if (pane.key === targetKey) { if (pane.key.toString() === targetKey) {
lastIndex = i - 1; lastIndex = i - 1;
} }
}); });
let panes = tabs.panes; let panes = tabs.panes;
const newPanes = panes.filter(pane => pane.key != targetKey); const newPanes = panes.filter(pane => pane.key.toString() != targetKey);
if (newPanes.length && newActiveKey === targetKey) { if (newPanes.length && newActiveKey.toString() === targetKey) {
if (lastIndex > 0) { if (lastIndex > 0) {
newActiveKey = newPanes[lastIndex].key; newActiveKey = newPanes[lastIndex].key;
} else { } else {
...@@ -66,11 +60,13 @@ const EditorTabs = (props: any) => { ...@@ -66,11 +60,13 @@ const EditorTabs = (props: any) => {
return ( return (
<> <>
<Tabs <Tabs
hideAdd
type="editable-card" type="editable-card"
size="small" size="small"
onChange={onChange} onChange={onChange}
activeKey={tabs.activeKey+''} activeKey={tabs.activeKey+''}
onEdit={onEdit} onEdit={onEdit}
className={styles["edit-tabs"]}
> >
{tabs.panes.map(pane => ( {tabs.panes.map(pane => (
<TabPane tab={pane.title} key={pane.key} closable={pane.closable}> <TabPane tab={pane.title} key={pane.key} closable={pane.closable}>
......
...@@ -15,7 +15,12 @@ const { DirectoryTree } = Tree; ...@@ -15,7 +15,12 @@ const { DirectoryTree } = Tree;
const {Search} = Input; const {Search} = Input;
type StudioTreeProps = {}; type StudioTreeProps = {
rightClickMenu:StateType['rightClickMenu'];
dispatch:any;
tabs:StateType['tabs'];
current:StateType['current'];
};
type RightClickMenu = { type RightClickMenu = {
pageX: number, pageX: number,
...@@ -44,7 +49,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -44,7 +49,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
const [treeData, setTreeData] = useState<TreeDataNode[]>(); const [treeData, setTreeData] = useState<TreeDataNode[]>();
const [dataList, setDataList] = useState<[]>(); const [dataList, setDataList] = useState<[]>();
const [rightClickNodeTreeItem,setRightClickNodeTreeItem] = useState<RightClickMenu>(); const [rightClickNodeTreeItem,setRightClickNodeTreeItem] = useState<RightClickMenu>();
const {currentPath,dispatch,tabs} = props; const {rightClickMenu,dispatch,tabs} = props;
const [updateCatalogueModalVisible, handleUpdateCatalogueModalVisible] = useState<boolean>(false); const [updateCatalogueModalVisible, handleUpdateCatalogueModalVisible] = useState<boolean>(false);
const [updateTaskModalVisible, handleUpdateTaskModalVisible] = useState<boolean>(false); const [updateTaskModalVisible, handleUpdateTaskModalVisible] = useState<boolean>(false);
const [isCreate, setIsCreate] = useState<boolean>(true); const [isCreate, setIsCreate] = useState<boolean>(true);
...@@ -74,7 +79,6 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -74,7 +79,6 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
}; };
const handleMenuClick=(key:string)=>{ const handleMenuClick=(key:string)=>{
setRightClickNodeTreeItem(null);
if(key=='Open'){ if(key=='Open'){
toOpen(rightClickNode); toOpen(rightClickNode);
}else if(key=='Submit'){ }else if(key=='Submit'){
...@@ -109,6 +113,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -109,6 +113,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
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,
task:{ task:{
session:'admin', session:'admin',
maxRowNum: 100, maxRowNum: 100,
...@@ -200,8 +205,8 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -200,8 +205,8 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
position: 'absolute', position: 'absolute',
// left: `${pageX - 50}px`, // left: `${pageX - 50}px`,
// top: `${pageY - 202}px`, // top: `${pageY - 202}px`,
left: `${pageX - 30}px`, left: `${pageX - 25}px`,
top: `${pageY - 152}px`, top: `${pageY - 140}px`,
}; };
let menuItems; let menuItems;
if(rightClickNode&&rightClickNode.isLeaf){ if(rightClickNode&&rightClickNode.isLeaf){
...@@ -216,6 +221,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -216,6 +221,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
<Menu.Item key='CreateCatalogue'>{'创建目录'}</Menu.Item> <Menu.Item key='CreateCatalogue'>{'创建目录'}</Menu.Item>
<Menu.Item key='CreateTask'>{'创建作业'}</Menu.Item> <Menu.Item key='CreateTask'>{'创建作业'}</Menu.Item>
<Menu.Item key='Rename'>{'重命名'}</Menu.Item> <Menu.Item key='Rename'>{'重命名'}</Menu.Item>
<Menu.Item disabled>{'删除'}</Menu.Item>
</>) </>)
}else{ }else{
menuItems=(<> menuItems=(<>
...@@ -234,7 +240,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -234,7 +240,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
{menuItems} {menuItems}
</Menu> </Menu>
); );
return (rightClickNodeTreeItem == null) ? '' : menu; return rightClickMenu? menu: '';
}; };
const getEmpty = () =>{ const getEmpty = () =>{
...@@ -257,6 +263,10 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -257,6 +263,10 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
id: e.node.id, id: e.node.id,
categoryName: e.node.name categoryName: e.node.name
}); });
dispatch&&dispatch({
type: "Studio/showRightClickMenu",
payload: true,
});
}; };
const onSelect = (selectedKeys:[], e:any) => { const onSelect = (selectedKeys:[], e:any) => {
...@@ -267,7 +277,6 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -267,7 +277,6 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
}); });
toOpen(e.node); toOpen(e.node);
} }
setRightClickNodeTreeItem(null);
}; };
return ( return (
...@@ -329,4 +338,5 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -329,4 +338,5 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
export default connect(({Studio}: { Studio: StateType }) => ({ export default connect(({Studio}: { Studio: StateType }) => ({
currentPath:Studio.currentPath, currentPath:Studio.currentPath,
tabs: Studio.tabs, tabs: Studio.tabs,
rightClickMenu: Studio.rightClickMenu,
}))(StudioTree); }))(StudioTree);
...@@ -16,3 +16,41 @@ ...@@ -16,3 +16,41 @@
.card{ .card{
background-color: #ffffff; background-color: #ffffff;
} }
:global {
/* --- card 内偏移样式 --- start */
#studio_card > .ant-card-body {
padding: 0px;
}
/* --- card 内偏移样式 --- start */
}
/* --- tabs 垂直样式 --- start */
.vertical-tabs{
:global {
.ant-tabs-left>.ant-tabs-nav, .ant-tabs-right>.ant-tabs-nav, .ant-tabs-left>div>.ant-tabs-nav, .ant-tabs-right>div>.ant-tabs-nav {
min-width: 20px;
}
.ant-tabs-left>.ant-tabs-nav .ant-tabs-tab, .ant-tabs-right>.ant-tabs-nav .ant-tabs-tab, .ant-tabs-left>div>.ant-tabs-nav .ant-tabs-tab, .ant-tabs-right>div>.ant-tabs-nav .ant-tabs-tab {
padding: 5px 5px;
}
.ant-tabs-tab-btn {
writing-mode: vertical-lr;
}
.ant-tabs-tab .anticon {
margin-right: 0;
}
.anticon {
vertical-align: 0;
}
}
}
/* --- tabs 垂直样式 --- end */
import React, {useEffect, useState} from "react"; import React, {useEffect, useState} from "react";
import {connect} from "umi"; import {connect} from "umi";
import styles from './index.less'; import styles from './index.less';
import {BarsOutlined,SettingOutlined,AuditOutlined,ScheduleOutlined,AppstoreOutlined,ApiOutlined,DashboardOutlined, import {BarsOutlined,SettingOutlined,AuditOutlined,ScheduleOutlined,AppstoreOutlined,ApiOutlined,DashboardOutlined,
FireOutlined} from "@ant-design/icons"; FireOutlined,ClusterOutlined,DatabaseOutlined,FunctionOutlined} from "@ant-design/icons";
import StudioMenu from "./StudioMenu"; import StudioMenu from "./StudioMenu";
import {Row, Col, Card, Empty, Tabs, Form,BackTop} from "antd"; import {Row, Col, Card, Empty, Tabs, Form,BackTop} from "antd";
...@@ -17,29 +18,55 @@ import StudioConnector from "./StudioConnector"; ...@@ -17,29 +18,55 @@ import StudioConnector from "./StudioConnector";
const {TabPane} = Tabs; const {TabPane} = Tabs;
type StudioProps = { type StudioProps = {
sql: StateType['sql']; // sql: StateType['sql'];
rightClickMenu:StateType['rightClickMenu'];
dispatch:any;
}; };
const Studio: React.FC<StudioProps> = ({sql}) => {
const [console, setConsole] = useState<boolean>(false); const Studio: React.FC<StudioProps> = (props) => {
const [sqls, setSqls] = useState<String>();
const {rightClickMenu,dispatch} = props;
const [form] = Form.useForm(); const [form] = Form.useForm();
useEffect(() => { /*useEffect(() => {
setSqls(sql); setSqls(sql);
}, [sql]); }, [sql]);*/
const onClick=()=>{
if(rightClickMenu){
dispatch&&dispatch({
type: "Studio/showRightClickMenu",
payload: false,
});
}
};
return ( return (
<div> <div onClick={onClick}>
<StudioMenu form={form}/> <StudioMenu form={form}/>
<Card bordered={false} className={styles.card} size="small"> <Card bordered={false} className={styles.card} size="small" id="studio_card">
<Row> <Row>
<Col span={4}> <Col span={4} className={styles["vertical-tabs"]}>
<Tabs defaultActiveKey="1" size="small"> <Tabs defaultActiveKey="1" size="small" tabPosition="left" style={{ height: "100%",border: "1px solid #f0f0f0"}}>
<TabPane tab={<span><BarsOutlined/>目录</span>} key="1" > <TabPane tab={<span><BarsOutlined/> 目录</span>} key="StudioTree" >
<StudioTree/> <StudioTree/>
</TabPane> </TabPane>
<TabPane tab={<span><AppstoreOutlined />元数据</span>} key="2" > <TabPane tab={<span><DatabaseOutlined /> 数据源</span>} key="DataSource" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span><AppstoreOutlined /> 元数据</span>} key="MetaData" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span><ClusterOutlined /> 集群</span>} key="Cluster" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span><ApiOutlined /> 连接器</span>} key="Connectors" >
<StudioConnector />
</TabPane>
<TabPane tab={<span><FireOutlined /> 任务</span>} key="FlinkTask" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span><FunctionOutlined /> 函数</span>} key="FlinkTask" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane> </TabPane>
</Tabs> </Tabs>
...@@ -47,59 +74,32 @@ const Studio: React.FC<StudioProps> = ({sql}) => { ...@@ -47,59 +74,32 @@ const Studio: React.FC<StudioProps> = ({sql}) => {
<Col span={16}> <Col span={16}>
<StudioTabs/> <StudioTabs/>
<StudioEdit/> <StudioEdit/>
<StudioConsole/>
</Col> </Col>
<Col span={4}> <Col span={4} className={styles["vertical-tabs"]}>
<Tabs defaultActiveKey="1" size="small"> <Tabs defaultActiveKey="1" size="small" tabPosition="right" style={{ height: "100%",border: "1px solid #f0f0f0"}}>
<TabPane tab={<span><SettingOutlined />配置</span>} key="1" > <TabPane tab={<span><SettingOutlined /> 配置</span>} key="1" >
<StudioSetting form={form} /> <StudioSetting form={form} />
</TabPane> </TabPane>
<TabPane tab={<span><ScheduleOutlined />详情</span>} key="2" > <TabPane tab={<span><ScheduleOutlined /> 详情</span>} key="2" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane> </TabPane>
<TabPane tab={<span><AuditOutlined />审计</span>} key="3" > <TabPane tab={<span><AuditOutlined /> 审计</span>} key="3" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
</Tabs>
<Tabs defaultActiveKey="1" size="small">
<TabPane tab={<span>&nbsp;<ApiOutlined />连接器</span>} key="1" >
<StudioConnector />
</TabPane>
<TabPane tab={<span>&nbsp;<DashboardOutlined />总览</span>} key="2" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span>&nbsp;<FireOutlined />任务</span>} key="3" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane> </TabPane>
</Tabs> </Tabs>
</Col> </Col>
</Row> </Row>
<Row>
<Col span={24}>
<StudioConsole/>
</Col>
</Row>
</Card> </Card>
<BackTop /> <BackTop />
</div> </div>
) )
}; };
/*function mapStateToProps(state) {
// 这个state是所有model层的state,这里只用到其中一个,所以state.testPage把命名空间为testPage这个model层的state数据取出来
// es6语法解构赋值
debugger;
const { data } = state.Studio;
// 这里return出去的数据,会变成此组件的props,在组件可以通过props.num取到。props变化了,会重新触发render方法,界面也就更新了。
return {
data,
};
}*/
// export default connect(mapStateToProps)(Studio);
export default connect(({Studio}: { Studio: StateType }) => ({ export default connect(({Studio}: { Studio: StateType }) => ({
current: Studio.current, rightClickMenu: Studio.rightClickMenu,
catalogue: Studio.catalogue,
sql: Studio.sql,
cluster: Studio.cluster,
tabs: Studio.tabs,
}))(Studio); }))(Studio);
// export default Studio;
...@@ -47,6 +47,7 @@ export type TabsItemType = { ...@@ -47,6 +47,7 @@ export type TabsItemType = {
key: number , key: number ,
value:string; value:string;
closable: boolean; closable: boolean;
path: string[];
task?:TaskType; task?:TaskType;
console:ConsoleType; console:ConsoleType;
} }
...@@ -56,6 +57,12 @@ export type TabsType = { ...@@ -56,6 +57,12 @@ export type TabsType = {
panes?: TabsItemType[]; panes?: TabsItemType[];
} }
export type RightClickMenu = {
pageX: number,
pageY: number,
id: number,
name: string
};
export type StateType = { export type StateType = {
cluster?:ClusterType[]; cluster?:ClusterType[];
current: TabsItemType; current: TabsItemType;
...@@ -64,6 +71,7 @@ export type StateType = { ...@@ -64,6 +71,7 @@ export type StateType = {
currentPath?: string[]; currentPath?: string[];
tabs:TabsType; tabs:TabsType;
session:string[]; session:string[];
rightClickMenu?:boolean;
}; };
export type ModelType = { export type ModelType = {
...@@ -80,6 +88,7 @@ export type ModelType = { ...@@ -80,6 +88,7 @@ export type ModelType = {
changeActiveKey: Reducer<StateType>; changeActiveKey: Reducer<StateType>;
saveTaskData: Reducer<StateType>; saveTaskData: Reducer<StateType>;
saveSession: Reducer<StateType>; saveSession: Reducer<StateType>;
showRightClickMenu: Reducer<StateType>;
}; };
}; };
...@@ -103,6 +112,7 @@ const Model: ModelType = { ...@@ -103,6 +112,7 @@ const Model: ModelType = {
key: 0 , key: 0 ,
value:'', value:'',
closable: false, closable: false,
path: ['草稿'],
task:{ task:{
checkPoint: 0, checkPoint: 0,
savePointPath: '', savePointPath: '',
...@@ -127,6 +137,7 @@ const Model: ModelType = { ...@@ -127,6 +137,7 @@ const Model: ModelType = {
key: 0 , key: 0 ,
value:'', value:'',
closable: false, closable: false,
path: ['草稿'],
task:{ task:{
checkPoint: 0, checkPoint: 0,
savePointPath: '', savePointPath: '',
...@@ -143,6 +154,7 @@ const Model: ModelType = { ...@@ -143,6 +154,7 @@ const Model: ModelType = {
}], }],
}, },
session:['admin'], session:['admin'],
rightClickMenu:false
}, },
effects: { effects: {
...@@ -224,6 +236,7 @@ const Model: ModelType = { ...@@ -224,6 +236,7 @@ const Model: ModelType = {
tabs:{ tabs:{
...tabs, ...tabs,
}, },
currentPath:newCurrent.path,
}; };
}, },
saveTaskData(state, { payload }) { saveTaskData(state, { payload }) {
...@@ -253,6 +266,12 @@ const Model: ModelType = { ...@@ -253,6 +266,12 @@ const Model: ModelType = {
session:newSession, session:newSession,
}; };
}, },
showRightClickMenu(state, { payload }) {
return {
...state,
rightClickMenu:payload,
};
},
}, },
}; };
......
...@@ -143,6 +143,25 @@ export default (): React.ReactNode => { ...@@ -143,6 +143,25 @@ export default (): React.ReactNode => {
</ul> </ul>
</Paragraph> </Paragraph>
</Timeline.Item> </Timeline.Item>
<Timeline.Item><Text code>0.2.1</Text> <Text type="secondary">2021-06-11</Text>
<p> </p>
<Paragraph>
<ul>
<li>
<Link href="">FlinkSql Studio 页面仿IDE设计改进</Link>
</li>
<li>
<Link href="">解决了目录树右键菜单的不能任意点关闭问题</Link>
</li>
<li>
<Link href="">解决了选项卡关闭不能正确刷新编辑器的问题</Link>
</li>
<li>
<Link href="">解决了当前位置不根据选项卡刷新的问题</Link>
</li>
</ul>
</Paragraph>
</Timeline.Item>
</Timeline> </Timeline>
</Card> </Card>
</PageContainer> </PageContainer>
......
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