Commit a6ad2058 authored by godkaikai's avatar godkaikai

执行历史

parent a3f5b303
...@@ -28,14 +28,14 @@ public class StudioExecuteDTO { ...@@ -28,14 +28,14 @@ public class StudioExecuteDTO {
private String savePointPath; private String savePointPath;
public JobConfig getJobConfig() { public JobConfig getJobConfig() {
return new JobConfig(useResult, useSession, getSession(), useRemote, clusterId, taskId, jobName, fragment, maxRowNum, checkPoint, parallelism, savePointPath); return new JobConfig(useResult, useSession, session, useRemote, clusterId, taskId, jobName, fragment, maxRowNum, checkPoint, parallelism, savePointPath);
} }
public String getSession() { /*public String getSession() {
if(useRemote) { if(useRemote) {
return clusterId + "_" + session; return clusterId + "_" + session;
}else{ }else{
return "0_" + session; return "0_" + session;
} }
} }*/
} }
...@@ -28,7 +28,7 @@ public class Job2MysqlHandler implements JobHandler { ...@@ -28,7 +28,7 @@ public class Job2MysqlHandler implements JobHandler {
history.setClusterId(job.getJobConfig().getClusterId()); history.setClusterId(job.getJobConfig().getClusterId());
history.setJobManagerAddress(job.getJobManagerAddress()); history.setJobManagerAddress(job.getJobManagerAddress());
history.setJobName(job.getJobConfig().getJobName()); history.setJobName(job.getJobConfig().getJobName());
history.setSession(job.getJobConfig().getSessionKey()); history.setSession(job.getJobConfig().getSession());
history.setStatus(job.getStatus().ordinal()); history.setStatus(job.getStatus().ordinal());
history.setStartTime(job.getStartTime()); history.setStartTime(job.getStartTime());
history.setTaskId(job.getJobConfig().getTaskId()); history.setTaskId(job.getJobConfig().getTaskId());
...@@ -54,9 +54,10 @@ public class Job2MysqlHandler implements JobHandler { ...@@ -54,9 +54,10 @@ public class Job2MysqlHandler implements JobHandler {
History history = new History(); History history = new History();
history.setId(job.getId()); history.setId(job.getId());
history.setJobId(job.getJobId()); history.setJobId(job.getJobId());
history.setStatement(job.getStatement());
history.setStatus(job.getStatus().ordinal()); history.setStatus(job.getStatus().ordinal());
history.setEndTime(job.getEndTime()); history.setEndTime(job.getEndTime());
history.setResult(JSONUtil.toJsonStr(job.getResult())); // history.setResult(JSONUtil.toJsonStr(job.getResult()));
historyService.updateById(history); historyService.updateById(history);
return true; return true;
} }
......
...@@ -38,4 +38,8 @@ public class History implements Serializable { ...@@ -38,4 +38,8 @@ public class History implements Serializable {
@TableField(exist = false) @TableField(exist = false)
private String statusText; private String statusText;
@TableField(exist = false)
private String clusterAlias;
@TableField(exist = false)
private String taskAlias;
} }
...@@ -30,9 +30,11 @@ ...@@ -30,9 +30,11 @@
<select id="selectForProTable" resultType="com.dlink.model.History"> <select id="selectForProTable" resultType="com.dlink.model.History">
select select
a.* a.*,
(select b.alias FROM dlink_cluster b where b.id=a.cluster_id) as clusterAlias,
(select c.alias FROM dlink_task c where c.id=a.task_id) as taskAlias
from from
dlink_cluster a dlink_history a
<where> <where>
1=1 1=1
<if test='param.name!=null and param.name!=""'> <if test='param.name!=null and param.name!=""'>
......
...@@ -17,7 +17,7 @@ public class JobConfig { ...@@ -17,7 +17,7 @@ public class JobConfig {
private boolean useResult; private boolean useResult;
private boolean useSession; private boolean useSession;
private String sessionKey; private String session;
private boolean useRemote; private boolean useRemote;
private Integer clusterId; private Integer clusterId;
private String host; private String host;
...@@ -29,12 +29,12 @@ public class JobConfig { ...@@ -29,12 +29,12 @@ public class JobConfig {
private Integer parallelism; private Integer parallelism;
private String savePointPath; private String savePointPath;
public JobConfig(boolean useResult, boolean useSession, String sessionKey, boolean useRemote, Integer clusterId, public JobConfig(boolean useResult, boolean useSession, String session, boolean useRemote, Integer clusterId,
Integer taskId, String jobName, boolean useSqlFragment, Integer maxRowNum, Integer checkpoint, Integer taskId, String jobName, boolean useSqlFragment, Integer maxRowNum, Integer checkpoint,
Integer parallelism, String savePointPath) { Integer parallelism, String savePointPath) {
this.useResult = useResult; this.useResult = useResult;
this.useSession = useSession; this.useSession = useSession;
this.sessionKey = sessionKey; this.session = session;
this.useRemote = useRemote; this.useRemote = useRemote;
this.clusterId = clusterId; this.clusterId = clusterId;
this.taskId = taskId; this.taskId = taskId;
...@@ -46,10 +46,10 @@ public class JobConfig { ...@@ -46,10 +46,10 @@ public class JobConfig {
this.savePointPath = savePointPath; this.savePointPath = savePointPath;
} }
public JobConfig(boolean useResult, boolean useSession, String sessionKey, boolean useRemote, Integer clusterId) { public JobConfig(boolean useResult, boolean useSession, String session, boolean useRemote, Integer clusterId) {
this.useResult = useResult; this.useResult = useResult;
this.useSession = useSession; this.useSession = useSession;
this.sessionKey = sessionKey; this.session = session;
this.useRemote = useRemote; this.useRemote = useRemote;
this.clusterId = clusterId; this.clusterId = clusterId;
} }
......
...@@ -117,12 +117,12 @@ public class JobManager extends RunTime { ...@@ -117,12 +117,12 @@ public class JobManager extends RunTime {
private Executor createExecutorWithSession() { private Executor createExecutorWithSession() {
if(config.isUseSession()) { if(config.isUseSession()) {
ExecutorEntity executorEntity = SessionPool.get(config.getSessionKey()); ExecutorEntity executorEntity = SessionPool.get(config.getSession());
if (executorEntity != null) { if (executorEntity != null) {
executor = executorEntity.getExecutor(); executor = executorEntity.getExecutor();
} else { } else {
createExecutor(); createExecutor();
SessionPool.push(new ExecutorEntity(config.getSessionKey(), executor)); SessionPool.push(new ExecutorEntity(config.getSession(), executor));
} }
}else { }else {
createExecutor(); createExecutor();
...@@ -134,7 +134,7 @@ public class JobManager extends RunTime { ...@@ -134,7 +134,7 @@ public class JobManager extends RunTime {
public boolean init() { public boolean init() {
handler = JobHandler.build(); handler = JobHandler.build();
String host = config.getHost(); String host = config.getHost();
if (config.isUseRemote() && host != null && !("").equals(host)) { if (host != null && !("").equals(host)) {
String[] strs = host.split(NetConstant.COLON); String[] strs = host.split(NetConstant.COLON);
if (strs.length >= 2) { if (strs.length >= 2) {
jobManagerHost = strs[0]; jobManagerHost = strs[0];
......
.code{
width: 100%;
max-height: 500px;
display: block;
padding: 16px;
overflow: auto;
font-size: 85%;
line-height: 1.45;
background-color: rgb(246, 248, 250);
border-radius: 3px;
}
import {StateType} from "@/pages/FlinkSqlStudio/model"; import {StateType} from "@/pages/FlinkSqlStudio/model";
import {connect} from "umi"; import {connect} from "umi";
import {Button, Tag, Space} from 'antd'; import {Button, Tag, Space,Typography, Divider, Badge,Drawer,} from 'antd';
import {MessageOutlined,ClusterOutlined,FireOutlined,ReloadOutlined} from "@ant-design/icons";
import { LightFilter, ProFormDatePicker } from '@ant-design/pro-form';
import ProList from '@ant-design/pro-list'; import ProList from '@ant-design/pro-list';
import request from 'umi-request'; import request from 'umi-request';
import {handleRemove, queryData} from "@/components/Common/crud";
import ProDescriptions from '@ant-design/pro-descriptions';
import {useRef, useState} from "react";
import {DocumentTableListItem} from "@/pages/Document/data";
import ProForm, {
ModalForm,
ProFormText,
ProFormDateRangePicker,
ProFormSelect,
} from '@ant-design/pro-form';
import styles from "./index.less";
import {ActionType} from "@ant-design/pro-table";
import {showJobData} from "@/components/Studio/StudioEvent/DQL";
type GithubIssueItem = { const { Title, Paragraph, Text, Link } = Typography;
url: string;
type HistoryItem = {
id: number; id: number;
number: number; clusterId: number;
title: string; clusterAlias: string;
labels: { session: string;
name: string; jobId: string;
color: string; jobName: string;
}[]; jobManagerAddress: string;
state: string; statusText: string;
comments: number; status: number;
created_at: string; statement: string;
updated_at: string; error: string;
closed_at?: string; result: string;
config: string;
startTime: string;
endTime: string;
taskId: number;
taskAlias: string;
}; };
type HistoryConfig={
useSession:boolean;
session:string;
useRemote:boolean;
clusterId:number;
host:string;
useResult:boolean;
maxRowNum:number;
taskId:number;
jobName:string;
useSqlFragment:boolean;
checkpoint:number;
parallelism:number;
savePointPath:string;
};
const url = '/api/history';
const StudioHistory = (props: any) => { const StudioHistory = (props: any) => {
const {current} = props; const {current,refs,dispatch} = props;
const [modalVisit, setModalVisit] = useState(false);
const [row, setRow] = useState<HistoryItem>();
const [config,setConfig] = useState<HistoryConfig>();
const [type,setType] = useState<number>();
const showDetail=(row:HistoryItem,type:number)=>{
setRow(row);
setModalVisit(true);
setType(type);
setConfig(JSON.parse(row.config));
};
const removeHistory=async (row:HistoryItem)=>{
await handleRemove(url,[row]);
// refs.current?.reloadAndRest?.();
refs.history?.current?.reload();
};
return ( return (
<><ProList<GithubIssueItem> <>
<ProList<HistoryItem>
actionRef={refs.history}
toolBarRender={() => { toolBarRender={() => {
return [ return [
<Button key="3" type="primary"> // <Button key="3" type="primary" icon={<ReloadOutlined />}/>,
新建
</Button>,
]; ];
}} }}
search={{ search={{
filterType: 'light', filterType: 'light',
}} }}
rowKey="name" rowKey="id"
headerTitle="基础列表" headerTitle="执行历史"
request={async (params = {}) => request={(params, sorter, filter) => queryData(url,{...params, sorter:{id:'descend'}, filter})}
request<{
data: GithubIssueItem[];
}>('https://proapi.azurewebsites.net/github/issues', {
params,
})
}
pagination={{ pagination={{
pageSize: 5, pageSize: 5,
}} }}
showActions="hover" showActions="hover"
metas={{ metas={{
title: { title: {
dataIndex: 'user', dataIndex: 'jobId',
title: '用户', title: 'JobId',
}, render: (_, row) => {
avatar: { return (
dataIndex: 'avatar', <Space size={0}>
search: false, <Tag color="blue" key={row.jobId}>
<FireOutlined /> {row.jobId}
</Tag>
</Space>
);
},
}, },
description: { description: {
dataIndex: 'title',
search: false, search: false,
}, render:(_, row)=>{
let jobConfig = JSON.parse(row.config);
return (<Paragraph>
<blockquote>
<Link href={`http://${jobConfig.host}`} target="_blank">
[{jobConfig.session}:{row.jobManagerAddress}]
</Link>
<Divider type="vertical"/>开始于:{row.startTime}
<Divider type="vertical"/>完成于:{row.endTime}
</blockquote>
</Paragraph>)
}
},
subTitle: { subTitle: {
dataIndex: 'labels',
render: (_, row) => { render: (_, row) => {
return ( return (
<Space size={0}> <Space size={0}>
{row.labels?.map((label: { name: string }) => ( {row.jobName?(
<Tag color="blue" key={label.name}> <Tag color="gray" key={row.jobName}>
{label.name} {row.jobName}
</Tag>
):''}
{row.session?(
<Tag color="orange" key={row.session}>
<MessageOutlined /> {row.session}
</Tag> </Tag>
))} ):''}
{row.clusterAlias?(
<Tag color="green" key={row.clusterAlias}>
<ClusterOutlined /> {row.clusterAlias}
</Tag>
):(<Tag color="blue" key={row.clusterAlias}>
<ClusterOutlined /> 本地环境
</Tag>)}
{(row.status==2) ?
(<><Badge status="success"/><Text type="success">SUCCESS</Text></>):
(row.status==1) ?
<><Badge status="error"/><Text type="secondary">RUNNING</Text></> :
(row.status==3) ?
<><Badge status="error"/><Text type="danger">FAILED</Text></> :
(row.status==4) ?
<><Badge status="error"/><Text type="warning">CANCEL</Text></> :
(row.status==0) ?
<><Badge status="error"/><Text type="warning">INITIALIZE</Text></> :
<><Badge status="success"/><Text type="danger">UNKNOWEN</Text></>}
</Space> </Space>
); );
}, },
...@@ -80,44 +166,178 @@ const StudioHistory = (props: any) => { ...@@ -80,44 +166,178 @@ const StudioHistory = (props: any) => {
}, },
actions: { actions: {
render: (text, row) => [ render: (text, row) => [
<a href={row.url} target="_blank" rel="noopener noreferrer" key="link"> <a key="config" onClick={()=>{showDetail(row,1)}}>
链路 执行配置
</a>,
<a key="statement" onClick={()=>{showDetail(row,2)}}>
FlinkSql语句
</a>, </a>,
<a href={row.url} target="_blank" rel="noopener noreferrer" key="warning"> <a key="result" onClick={()=>{showJobData(row.jobId,dispatch)}}>
报警 预览数据
</a>, </a>,
<a href={row.url} target="_blank" rel="noopener noreferrer" key="view"> <a key="error" onClick={()=>{showDetail(row,4)}}>
查看 异常信息
</a>,
<a key="delete" onClick={()=>{removeHistory(row)}}>
删除
</a>, </a>,
], ],
search: false, search: false,
}, },
jobName: {
dataIndex: 'jobName',
title: '作业名',
},
clusterId: {
dataIndex: 'clusterId',
title: '执行方式',
},
session: {
dataIndex: 'session',
title: '共享会话',
},
status: { status: {
// 自己扩展的字段,主要用于筛选,不在列表中显示 // 自己扩展的字段,主要用于筛选,不在列表中显示
title: '状态', title: '状态',
valueType: 'select', valueType: 'select',
valueEnum: { valueEnum: {
all: {text: '全部', status: 'Default'}, ALL: {text: '全部', status: 'ALL'},
open: { INITIALIZE: {
text: '未解决', text: '初始化',
status: 'Error', status: 'INITIALIZE',
},
RUNNING: {
text: '运行中',
status: 'RUNNING',
},
SUCCESS: {
text: '成功',
status: 'SUCCESS',
}, },
closed: { FAILED: {
text: '已解决', text: '失败',
status: 'Success', status: 'FAILED',
}, },
processing: { CANCEL: {
text: '解决中', text: '停止',
status: 'Processing', status: 'CANCEL',
}, },
}, },
}, },
startTime: {
dataIndex: 'startTime',
title: '开始时间',
valueType: 'dateTimeRange',
},
endTime: {
dataIndex: 'endTime',
title: '完成时间',
valueType: 'dateTimeRange',
},
}}
options={{
search: false,
setting:false
}} }}
/> />
<ModalForm
// title="新建表单"
visible={modalVisit}
onFinish={async () => {
setRow(undefined);
setType(undefined);
setConfig(undefined);
}}
onVisibleChange={setModalVisit}
submitter={{
submitButtonProps: {
style: {
display: 'none',
},
},
}}
>
{type==1 && (
<ProDescriptions
column={2}
title='执行配置'
>
<ProDescriptions.Item span={2} label="JobId" >
{row.jobId}
</ProDescriptions.Item>
<ProDescriptions.Item label="共享会话" >
{config.useSession?'启用':'禁用'}
</ProDescriptions.Item>
<ProDescriptions.Item label="会话 Key">
{config.session}
</ProDescriptions.Item>
<ProDescriptions.Item label="执行方式" >
{config.useRemote?'远程':'本地'}
</ProDescriptions.Item>
<ProDescriptions.Item label="集群ID">
{config.clusterId}
</ProDescriptions.Item>
<ProDescriptions.Item label="预览结果" >
{config.useResult?'启用':'禁用'}
</ProDescriptions.Item>
<ProDescriptions.Item label="最大行数">
{config.maxRowNum}
</ProDescriptions.Item>
<ProDescriptions.Item span={2} label="JobManagerAddress">
{row.jobManagerAddress}
</ProDescriptions.Item>
<ProDescriptions.Item label="作业ID">
{config.taskId}
</ProDescriptions.Item>
<ProDescriptions.Item label="作业名">
{config.jobName}
</ProDescriptions.Item>
<ProDescriptions.Item label="片段机制">
{config.useSqlFragment?'启用':'禁用'}
</ProDescriptions.Item>
<ProDescriptions.Item label="并行度">
{config.parallelism}
</ProDescriptions.Item>
<ProDescriptions.Item label="CheckPoint">
{config.checkpoint}
</ProDescriptions.Item>
<ProDescriptions.Item label="SavePointPath">
{config.savePointPath}
</ProDescriptions.Item>
</ProDescriptions>
)}
{type==2 && (
<ProDescriptions
column={1}
title='FlinkSql 语句'
>
<ProDescriptions.Item label="JobId" >
{row.jobId}
</ProDescriptions.Item>
<ProDescriptions.Item>
<pre className={styles.code}>{row.statement}</pre>
</ProDescriptions.Item>
</ProDescriptions>
)}
{type==4 && (
<ProDescriptions
column={1}
title='异常信息'
>
<ProDescriptions.Item label="JobId" >
{row.jobId}
</ProDescriptions.Item>
<ProDescriptions.Item >
<pre className={styles.code}>{row.error}</pre>
</ProDescriptions.Item>
</ProDescriptions>
)}
</ModalForm>
</> </>
); );
}; };
export default connect(({Studio}: {Studio: StateType}) => ({ export default connect(({Studio}: {Studio: StateType}) => ({
current: Studio.current, current: Studio.current,
refs: Studio.refs,
}))(StudioHistory); }))(StudioHistory);
import {Typography, Divider, Badge, Empty} from "antd";
import {StateType} from "@/pages/FlinkSqlStudio/model";
import {connect} from "umi";
const { Title, Paragraph, Text, Link } = Typography;
const StudioHistory2 = (props:any) => {
const {current} = props;
return (
<Typography>
{current.console.result.map((item)=> {
return (<Paragraph>
<blockquote><Link href={`http://${item.flinkHost}:${item.flinkPort}`} target="_blank">
[{item.sessionId}:{item.flinkHost}:{item.flinkPort}]
</Link> <Divider type="vertical" />{item.finishDate}
<Divider type="vertical" />
{!item.success ? <><Badge status="error"/><Text type="danger">Error</Text></> :
<><Badge status="success"/><Text type="success">Success</Text></>}
<Divider type="vertical" />
{item.jobName&&<Text code>{item.jobName}</Text>}
{item.jobId&&<Text code>{item.jobId}</Text>}
<Text keyboard>{item.time}ms</Text></blockquote>
{item.statement && (<pre style={{height:'40px'}}>{item.statement}</pre>)}
{item.msg ? item.msg : ''}
{item.error && (<pre style={{height:'100px'}}>{item.error}</pre>)}
</Paragraph>)
})}
{current.console.result.length==0?<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />:''}
</Typography>
);
};
export default connect(({ Studio }: { Studio: StateType }) => ({
current: Studio.current,
}))(StudioHistory2);
...@@ -5,6 +5,7 @@ import {useState} from "react"; ...@@ -5,6 +5,7 @@ import {useState} from "react";
// import Highlighter from 'react-highlight-words'; // import Highlighter from 'react-highlight-words';
import { SearchOutlined } from '@ant-design/icons'; import { SearchOutlined } from '@ant-design/icons';
import {showJobData} from "@/components/Studio/StudioEvent/DQL"; import {showJobData} from "@/components/Studio/StudioEvent/DQL";
import ProTable from '@ant-design/pro-table';
const { Option } = Select; const { Option } = Select;
const { Title, Paragraph, Text, Link } = Typography; const { Title, Paragraph, Text, Link } = Typography;
...@@ -96,36 +97,11 @@ const StudioTable = (props:any) => { ...@@ -96,36 +97,11 @@ const StudioTable = (props:any) => {
return datas; return datas;
}; };
const onChange=(val:string)=>{
showJobData(val,dispatch);
};
return ( return (
<Typography> <Typography>
<Form.Item label="当前执行记录" tooltip="选择最近的执行记录,仅包含成功的记录"> {result&&result.jobId&&!result.isDestroyed?
<Select (<ProTable dataSource={result.rowData} columns={getColumns(result.columns)} search={false}
style={{ width: '100%' }} />):(<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />)}
placeholder="选择最近的执行记录"
optionLabelProp="label"
onChange={onChange}
>
{current.console.result.map((item,index)=> {
if(item.status=='SUCCESS'&&item.jobId) {
let tag = (<> <Tooltip placement="topLeft" title={item.statement}>
<Tag color="processing">{item.startTime}</Tag>
<Tag color="processing">{item.endTime}</Tag>
<Text underline>[{item.jobConfig.sessionKey}:{item.jobConfig.host}]</Text>
{item.jobConfig.jobName&&<Text code>{item.jobConfig.jobName}</Text>}
{item.jobId&&<Text code>{item.jobId}</Text>}
{item.statement}</Tooltip></>);
return (<Option value={item.jobId} label={tag}>
{tag}
</Option>)
}
})}
</Select>
</Form.Item>
{result&&result.jobId&&!result.isDestroyed?(<Table dataSource={result.rowData} columns={getColumns(result.columns)} />):(<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />)}
</Typography> </Typography>
); );
}; };
......
import {Tabs, Empty} from "antd"; import {Tabs, Empty} from "antd";
import {BarsOutlined,DatabaseOutlined,AppstoreOutlined,ClusterOutlined,ApiOutlined,FireOutlined,FunctionOutlined} from "@ant-design/icons"; import {BarsOutlined,DatabaseOutlined,AppstoreOutlined,ClusterOutlined,MessageOutlined,FireOutlined,FunctionOutlined} from "@ant-design/icons";
import {StateType} from "@/pages/FlinkSqlStudio/model"; import {StateType} from "@/pages/FlinkSqlStudio/model";
import {connect} from "umi"; import {connect} from "umi";
import styles from "./index.less"; import styles from "./index.less";
...@@ -27,7 +27,7 @@ const StudioLeftTool = (props:any) => { ...@@ -27,7 +27,7 @@ const StudioLeftTool = (props:any) => {
<TabPane tab={<span><ClusterOutlined /> 集群</span>} key="Cluster" > <TabPane tab={<span><ClusterOutlined /> 集群</span>} key="Cluster" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane> </TabPane>
<TabPane tab={<span><ApiOutlined /> 连接器</span>} key="Connectors" > <TabPane tab={<span><MessageOutlined /> 会话</span>} key="Connectors" >
<StudioConnector /> <StudioConnector />
</TabPane> </TabPane>
<TabPane tab={<span><FireOutlined /> 任务</span>} key="FlinkTask" > <TabPane tab={<span><FireOutlined /> 任务</span>} key="FlinkTask" >
......
...@@ -13,6 +13,7 @@ import { postDataArray} from "@/components/Common/crud"; ...@@ -13,6 +13,7 @@ import { postDataArray} from "@/components/Common/crud";
import {executeSql} from "@/pages/FlinkSqlStudio/service"; import {executeSql} from "@/pages/FlinkSqlStudio/service";
import StudioHelp from "./StudioHelp"; import StudioHelp from "./StudioHelp";
import {showTables} from "@/components/Studio/StudioEvent/DDL"; import {showTables} from "@/components/Studio/StudioEvent/DDL";
import {timeout} from "d3-timer";
const menu = ( const menu = (
<Menu> <Menu>
...@@ -23,7 +24,7 @@ const menu = ( ...@@ -23,7 +24,7 @@ const menu = (
const StudioMenu = (props: any) => { const StudioMenu = (props: any) => {
const {tabs,current,currentPath,form,dispatch} = props; const {tabs,current,currentPath,form,refs,dispatch} = props;
const execute = () => { const execute = () => {
let selectsql =null; let selectsql =null;
...@@ -57,6 +58,9 @@ const StudioMenu = (props: any) => { ...@@ -57,6 +58,9 @@ const StudioMenu = (props: any) => {
key:taskKey, key:taskKey,
icon: <SmileOutlined style={{ color: '#108ee9' }} />, icon: <SmileOutlined style={{ color: '#108ee9' }} />,
}); });
setTimeout(()=>{
refs?.history?.current?.reload();
},2000);
const result = executeSql(param); const result = executeSql(param);
result.then(res=>{ result.then(res=>{
notification.close(taskKey); notification.close(taskKey);
...@@ -284,5 +288,6 @@ export default connect(({Studio}: { Studio: StateType }) => ({ ...@@ -284,5 +288,6 @@ export default connect(({Studio}: { Studio: StateType }) => ({
current: Studio.current, current: Studio.current,
currentPath: Studio.currentPath, currentPath: Studio.currentPath,
tabs: Studio.tabs, tabs: Studio.tabs,
refs: Studio.refs,
// monaco: Studio.monaco, // monaco: Studio.monaco,
}))(StudioMenu); }))(StudioMenu);
...@@ -71,6 +71,51 @@ const StudioConfig = (props: any) => { ...@@ -71,6 +71,51 @@ const StudioConfig = (props: any) => {
> >
<Input placeholder="自定义作业名" /> <Input placeholder="自定义作业名" />
</Form.Item> </Form.Item>
<Row>
<Col span={10}>
<Form.Item
label="共享会话" className={styles.form_item} name="useSession" valuePropName="checked"
tooltip={{ title: '开启共享会话,将进行 Flink Catalog 的共享', icon: <InfoCircleOutlined /> }}
>
<Switch checkedChildren="启用" unCheckedChildren="禁用"
/>
</Form.Item>
</Col>
<Col span={14}>
<Form.Item
label="会话 Key" tooltip="设置共享会话的 Key" name="session"
className={styles.form_item}>
<Select
placeholder="选择会话"
allowClear
onChange={onChangeClusterSession}
dropdownRender={menu => (
<div>
{menu}
<Divider style={{ margin: '4px 0' }} />
<div style={{ display: 'flex', flexWrap: 'nowrap', padding: 8 }}>
<Input style={{ flex: 'auto' }} value={newSesstion}
onChange={(e)=>{
setNewSesstion(e.target.value);
}}
/>
<a
style={{ flex: 'none', padding: '8px', display: 'block', cursor: 'pointer' }}
onClick={addSession}
>
<PlusOutlined />
</a>
</div>
</div>
)}
>
{session.map(item => (
<Option key={item}>{item}</Option>
))}
</Select>
</Form.Item>
</Col>
</Row>
<Row> <Row>
<Col span={12}> <Col span={12}>
<Form.Item <Form.Item
...@@ -97,51 +142,6 @@ const StudioConfig = (props: any) => { ...@@ -97,51 +142,6 @@ const StudioConfig = (props: any) => {
<Switch checkedChildren="启用" unCheckedChildren="禁用" <Switch checkedChildren="启用" unCheckedChildren="禁用"
/> />
</Form.Item> </Form.Item>
<Row>
<Col span={10}>
<Form.Item
label="共享会话" className={styles.form_item} name="useSession" valuePropName="checked"
tooltip={{ title: '开启共享会话,将进行 Flink Catalog 的共享', icon: <InfoCircleOutlined /> }}
>
<Switch checkedChildren="启用" unCheckedChildren="禁用"
/>
</Form.Item>
</Col>
<Col span={14}>
<Form.Item
label="会话 Key" tooltip="设置共享会话的 Key" name="session"
className={styles.form_item}>
<Select
placeholder="选择会话"
allowClear
onChange={onChangeClusterSession}
dropdownRender={menu => (
<div>
{menu}
<Divider style={{ margin: '4px 0' }} />
<div style={{ display: 'flex', flexWrap: 'nowrap', padding: 8 }}>
<Input style={{ flex: 'auto' }} value={newSesstion}
onChange={(e)=>{
setNewSesstion(e.target.value);
}}
/>
<a
style={{ flex: 'none', padding: '8px', display: 'block', cursor: 'pointer' }}
onClick={addSession}
>
<PlusOutlined />
</a>
</div>
</div>
)}
>
{session.map(item => (
<Option key={item}>{item}</Option>
))}
</Select>
</Form.Item>
</Col>
</Row>
</Form> </Form>
</> </>
); );
......
...@@ -24,8 +24,23 @@ ...@@ -24,8 +24,23 @@
padding: 0px; padding: 0px;
} }
/* --- card 内偏移样式 --- start */ /* --- card 内偏移样式 --- start */
/* --- list toolbar隐藏滚动条 --- start */
.ant-pro-table-list-toolbar {
overflow-x: hidden;
overflow-y: hidden;
line-height: 1;
}
/* --- list toolbar隐藏滚动条 --- start */
/* --- list toolbar修改内偏移 --- start */
.ant-pro-table-list-toolbar-container {
padding: 0;
}
/* --- list toolbar修改内偏移 --- start */
/* --- prodescription item宽度 --- start */
.ant-descriptions-item-content {
width: 100%;
}
/* --- prodescription item宽度 --- start */
} }
/* --- tabs 垂直样式 --- start */ /* --- tabs 垂直样式 --- start */
......
...@@ -93,6 +93,9 @@ export type StateType = { ...@@ -93,6 +93,9 @@ export type StateType = {
session: string[]; session: string[];
result:{}; result:{};
rightClickMenu?: boolean; rightClickMenu?: boolean;
refs:{
history:any;
};
}; };
export type ModelType = { export type ModelType = {
...@@ -196,7 +199,10 @@ const Model: ModelType = { ...@@ -196,7 +199,10 @@ const Model: ModelType = {
}, },
session: [], session: [],
result:{}, result:{},
rightClickMenu: false rightClickMenu: false,
refs:{
history:{},
}
}, },
effects: { effects: {
......
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