Unverified Commit 39e61435 authored by aiwenmo's avatar aiwenmo Committed by GitHub

[Fix-1020][core,web] Fix error in saving task after modifying task name (#1023)

Co-authored-by: 's avatarwenmo <32723967+wenmo@users.noreply.github.com>
parent 0e2b9c92
......@@ -49,19 +49,19 @@ public final class FlinkRestAPIConstant {
public static final String EXCEPTIONS = "/exceptions?maxExceptions=10";
public static final String JOB_MANAGER = "/jobmanager/";
public static final String JOB_MANAGER = "/jobmanager";
public static final String TASK_MANAGER = "/taskmanagers/";
public static final String METRICS = "/metrics/";
public static final String METRICS = "/metrics";
public static final String LOG = "/log/";
public static final String LOG = "/log";
public static final String LOGS = "/logs/";
public static final String STDOUT = "/stdout/";
public static final String STDOUT = "/stdout";
public static final String THREAD_DUMP = "/thread-dump/";
public static final String THREAD_DUMP = "/thread-dump";
public static final String GET = "?get=";
......
......@@ -26,50 +26,51 @@ import {Button, Input, Space} from "antd";
const DTable = (props: any) => {
const {dataSource,columns} = props;
const {dataSource, columns, scroll} = props;
const [data,setData] = useState<[]>([]);
const [data, setData] = useState<[]>([]);
const refreshData = async () =>{
const refreshData = async () => {
const msg = await getData(dataSource.url, dataSource.params);
setData(msg.datas);
};
const buildColumn = () =>{
const columnList: any=[];
const buildColumn = () => {
const columnList: any = [];
columns.map((item) => {
const openSorter = item.openSorter==null?true:item.openSorter;
const isString = item.isString==null?true:item.isString;
const openSearch = item.openSearch==null?'like':item.openSearch;
const openSorter = item.openSorter == null ? true : item.openSorter;
const isString = item.isString == null ? true : item.isString;
const openSearch = item.openSearch == null ? 'like' : item.openSearch;
let column = {
title: item.title?item.title:item.field,
dataIndex: item.dataIndex?item.dataIndex:item.field,
key: item.dataIndex?item.dataIndex:item.field,
title: item.title ? item.title : item.field,
dataIndex: item.dataIndex ? item.dataIndex : item.field,
key: item.dataIndex ? item.dataIndex : item.field,
};
if(openSorter){
if(isString){
if (openSorter) {
if (isString) {
column = {
sorter: (a, b) => {
const value1 = a[column.dataIndex]!=null?a[column.dataIndex].toString():'';
const value2 = b[column.dataIndex]!=null?b[column.dataIndex].toString():'';
const value1 = a[column.dataIndex] != null ? a[column.dataIndex].toString() : '';
const value2 = b[column.dataIndex] != null ? b[column.dataIndex].toString() : '';
return value1.localeCompare(value2);
},
...column,
}
}else{
} else {
column = {
sorter: (a, b) => a[column.dataIndex] - b[column.dataIndex],
...column,
}
}
}
if(openSearch==='like'){
column = {...column,...getColumnSearchProps(column.dataIndex),}
}else if(openSearch==='dict'){
if (openSearch === 'like') {
column = {...column, ...getColumnSearchProps(column.dataIndex),}
} else if (openSearch === 'dict') {
column = {
onFilter: (value, record) => record[column.dataIndex] === value,
...column,}
...column,
}
}
columnList.push({
...column,
......@@ -80,7 +81,7 @@ const DTable = (props: any) => {
}
useEffect(() => {
if(dataSource&&dataSource.url){
if (dataSource && dataSource.url) {
refreshData();
}
}, [dataSource]);
......@@ -89,7 +90,8 @@ const DTable = (props: any) => {
<ProTable
columns={buildColumn()}
style={{width: '100%'}}
dataSource={dataSource?(dataSource.url?data:dataSource):[]}
scroll={scroll}
dataSource={dataSource ? (dataSource.url ? data : dataSource) : []}
rowKey="name"
pagination={{
pageSize: 10,
......
......@@ -30,25 +30,25 @@ import Tables from "@/pages/DataBase/Tables";
import {TreeDataNode} from "@/components/Studio/StudioTree/Function";
import Generation from "@/pages/DataBase/Generation";
const { DirectoryTree } = Tree;
const {DirectoryTree} = Tree;
const {Option} = Select;
const { TabPane } = Tabs;
const {TabPane} = Tabs;
const StudioMetaData = (props: any) => {
const {database,toolHeight, dispatch} = props;
const {database, toolHeight, dispatch} = props;
const [databaseId, setDatabaseId] = useState<number>();
const [treeData, setTreeData] = useState<[]>([]);
const [modalVisit, setModalVisit] = useState(false);
const [row, setRow] = useState<TreeDataNode>();
const onRefreshTreeData = (databaseId: number)=>{
if(!databaseId)return;
const onRefreshTreeData = (databaseId: number) => {
if (!databaseId) return;
setDatabaseId(databaseId);
const res = showMetaDataTable(databaseId);
res.then((result) => {
let tables = result.datas;
if(tables) {
if (tables) {
for (let i = 0; i < tables.length; i++) {
tables[i].title = tables[i].name;
tables[i].key = tables[i].name;
......@@ -64,26 +64,27 @@ const StudioMetaData = (props: any) => {
}
}
setTreeData(tables);
}else{
} else {
setTreeData([]);
}
});
};
const onChangeDataBase = (value: number)=>{
const onChangeDataBase = (value: number) => {
onRefreshTreeData(value);
};
const getDataBaseOptions = ()=>{
return <>{database.map(({ id, name, alias, type, enabled }) => (
<Option value={id} label={<><Tag color={enabled ? "processing" : "error"}>{type}</Tag>{ alias === "" ? name:alias}</>}>
<Tag color={enabled ? "processing" : "error"}>{type}</Tag>{ alias === "" ? name:alias}
const getDataBaseOptions = () => {
return <>{database.map(({id, name, alias, type, enabled}) => (
<Option value={id}
label={<><Tag color={enabled ? "processing" : "error"}>{type}</Tag>{alias === "" ? name : alias}</>}>
<Tag color={enabled ? "processing" : "error"}>{type}</Tag>{alias === "" ? name : alias}
</Option>
))}</>
};
const openColumnInfo = (e: React.MouseEvent, node: TreeDataNode) => {
if(node.isLeaf){
if (node.isLeaf) {
setRow(node);
setModalVisit(true);
}
......@@ -105,21 +106,21 @@ const StudioMetaData = (props: any) => {
{getDataBaseOptions()}
</Select>
<Scrollbars style={{height: (toolHeight - 32)}}>
{treeData.length>0?(
{treeData.length > 0 ? (
<DirectoryTree
showIcon
switcherIcon={<DownOutlined/>}
treeData={treeData}
onRightClick={({event, node}: any) => {
openColumnInfo(event, node)
}}
/>):(<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />)}
showIcon
switcherIcon={<DownOutlined/>}
treeData={treeData}
onRightClick={({event, node}: any) => {
openColumnInfo(event, node)
}}
/>) : (<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>)}
</Scrollbars>
<Modal
title={row?.key}
visible={modalVisit}
width={1000}
onCancel={()=>{
onCancel={() => {
cancelHandle();
}}
footer={[
......@@ -134,38 +135,40 @@ const StudioMetaData = (props: any) => {
<TabPane
tab={
<span>
<TableOutlined />
<TableOutlined/>
表信息
</span>
}
key="tableInfo"
>
{row?<Tables table={row}/>:<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
{row ? <Tables table={row}/> : <Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>}
</TabPane>
<TabPane
tab={
<span>
<CodepenOutlined />
<CodepenOutlined/>
字段信息
</span>
}
key="columnInfo"
>
{row? <Columns dbId={databaseId} schema={row.schema} table={row.table}/> : <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
{row ? <Columns dbId={databaseId} schema={row.schema} table={row.table} scroll={{x: 1000}}/> :
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>}
</TabPane>
<TabPane
tab={
<span>
<OrderedListOutlined />
<OrderedListOutlined/>
SQL 生成
</span>
}
key="sqlGeneration"
>
{row? <Generation dbId={databaseId} schema={row.schema} table={row.table}/> : <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
{row ? <Generation dbId={databaseId} schema={row.schema} table={row.table}/> :
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>}
</TabPane>
</Tabs>
</Modal>
</Modal>
</>
);
};
......
......@@ -18,8 +18,8 @@
*/
import {message, Tabs, Menu, Dropdown} from 'antd';
import React, {useState} from 'react';
import {Dropdown, Menu, message, Tabs} from 'antd';
import React from 'react';
import {connect} from 'umi';
import {StateType} from '@/pages/DataStudio/model';
import styles from './index.less';
......@@ -31,7 +31,7 @@ import {Dispatch} from "@@/plugin-dva/connect";
const {TabPane} = Tabs;
const EditorTabs = (props: any) => {
const {tabs, current, toolHeight, width,height} = props;
const {tabs, current, toolHeight, width, height} = props;
const onChange = (activeKey: any) => {
props.saveToolHeight(toolHeight);
......@@ -42,7 +42,7 @@ const EditorTabs = (props: any) => {
if (action === 'add') {
add();
} else if (action === 'remove') {
props.saveToolHeight(toolHeight-0.0001);
props.saveToolHeight(toolHeight - 0.0001);
// if (current.isModified) {
// saveTask(current, dispatch);
// }
......@@ -71,11 +71,11 @@ const EditorTabs = (props: any) => {
newActiveKey = newPanes[0].key;
}
}
props.saveTabs(newPanes,newActiveKey);
props.saveTabs(newPanes, newActiveKey);
};
const handleClickMenu = (e: any, current) => {
props.closeTabs(current,e.key);
props.closeTabs(current, e.key);
};
const menu = (pane) => (
......@@ -92,11 +92,11 @@ const EditorTabs = (props: any) => {
const Tab = (pane: any) => (
<span>
{pane.key === 0 ? (
pane.title
<>{pane.icon} {pane.title}</>
) : (
<Dropdown overlay={menu(pane)} trigger={['contextMenu']}>
<span className="ant-dropdown-link">
{pane.title}
<>{pane.icon} {pane.title}</>
</span>
</Dropdown>
)}
......@@ -105,52 +105,52 @@ const EditorTabs = (props: any) => {
return (
<>
{tabs.panes.length === 0?<StudioHome width={width} />:
<Tabs
hideAdd
type="editable-card"
size="small"
onChange={onChange}
activeKey={tabs.activeKey + ''}
onEdit={onEdit}
className={styles['edit-tabs']}
style={{height: height?height:toolHeight}}
>
{tabs.panes.map((pane,i) => (
<TabPane tab={Tab(pane)} key={pane.key} closable={pane.closable}>
<StudioEdit
tabsKey={pane.key}
sql={pane.value}
monaco={pane.monaco}
// sqlMetaData={pane.sqlMetaData}
height={height?height:(toolHeight - 32)}
width={width}
language={current.task.dialect === DIALECT.JAVA ? 'java' : 'sql'}
/>
</TabPane>
))}
</Tabs>}
</>
{tabs.panes.length === 0 ? <StudioHome width={width}/> :
<Tabs
hideAdd
type="editable-card"
size="small"
onChange={onChange}
activeKey={tabs.activeKey + ''}
onEdit={onEdit}
className={styles['edit-tabs']}
style={{height: height ? height : toolHeight}}
>
{tabs.panes.map((pane, i) => (
<TabPane tab={Tab(pane)} key={pane.key} closable={pane.closable}>
<StudioEdit
tabsKey={pane.key}
sql={pane.value}
monaco={pane.monaco}
// sqlMetaData={pane.sqlMetaData}
height={height ? height : (toolHeight - 32)}
width={width}
language={current.task.dialect === DIALECT.JAVA ? 'java' : 'sql'}
/>
</TabPane>
))}
</Tabs>}
</>
);
};
const mapDispatchToProps = (dispatch: Dispatch)=>({
closeTabs:(current: any,key: string)=>dispatch({
const mapDispatchToProps = (dispatch: Dispatch) => ({
closeTabs: (current: any, key: string) => dispatch({
type: 'Studio/closeTabs',
payload: {
deleteType: key,
current
},
}),saveTabs:(newPanes: any,newActiveKey: number)=>dispatch({
}), saveTabs: (newPanes: any, newActiveKey: number) => dispatch({
type: 'Studio/saveTabs',
payload: {
activeKey: newActiveKey,
panes: newPanes,
},
}),saveToolHeight:(toolHeight: number)=>dispatch({
}), saveToolHeight: (toolHeight: number) => dispatch({
type: 'Studio/saveToolHeight',
payload: toolHeight - 0.0001,
}),changeActiveKey:(activeKey: number)=>dispatch({
}), changeActiveKey: (activeKey: number) => dispatch({
type: 'Studio/changeActiveKey',
payload: activeKey,
}),
......@@ -161,4 +161,4 @@ export default connect(({Studio}: { Studio: StateType }) => ({
sql: Studio.sql,
tabs: Studio.tabs,
toolHeight: Studio.toolHeight,
}),mapDispatchToProps)(EditorTabs);
}), mapDispatchToProps)(EditorTabs);
......@@ -18,8 +18,8 @@
*/
import React, {useEffect, useState} from 'react';
import {Form, Button, Input, Modal} from 'antd';
import React, {useState} from 'react';
import {Button, Form, Input, Modal} from 'antd';
import type {CatalogueTableListItem} from '../data.d';
......@@ -40,6 +40,7 @@ const formLayout = {
const UpdateCatalogueForm: React.FC<UpdateFormProps> = (props) => {
const [formVals, setFormVals] = useState<Partial<CatalogueTableListItem>>({
id: props.values.id,
taskId: props.values.taskId,
name: props.values.name,
isLeaf: props.values.isLeaf,
parentId: props.values.parentId,
......@@ -100,6 +101,7 @@ const UpdateCatalogueForm: React.FC<UpdateFormProps> = (props) => {
form={form}
initialValues={{
id: formVals.id,
taskId: formVals.taskId,
name: formVals.name,
isLeaf: formVals.isLeaf,
parentId: formVals.parentId,
......
......@@ -20,6 +20,7 @@
export type CatalogueTableListItem = {
id: number,
taskId: number,
name: string,
isLeaf: string,
parentId: number,
......
......@@ -230,9 +230,10 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
result.then(result => {
let newTabs = tabs;
let newPane: any = {
title: <>{node!.icon} {node!.name}</>,
title: node!.name,
key: node!.taskId,
value: (result.datas.statement ? result.datas.statement : ''),
icon: node!.icon,
closable: true,
path: node!.path,
task: {
......@@ -310,6 +311,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
setActiveNode(node);
setCatalogueFormValues({
id: node?.id,
taskId: node?.taskId,
name: node?.name,
});
};
......@@ -656,13 +658,16 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
handleUpdateCatalogueModalVisible(false);
setCatalogueFormValues({});
getTreeData();
dispatch({
type: "Studio/renameTab",
payload: {
key: value.id,
name: <>{activeNode.icon} {value.name}</>
},
});
if (value.taskId) {
dispatch({
type: "Studio/renameTab",
payload: {
key: value.taskId,
title: value.name,
icon: activeNode.icon
},
});
}
}
}}
onCancel={() => {
......
......@@ -19,12 +19,12 @@
import React from "react";
import {KeyOutlined, CheckSquareOutlined} from '@ant-design/icons';
import {CheckSquareOutlined, KeyOutlined} from '@ant-design/icons';
import DTable from "@/components/Common/DTable";
const Columns = (props: any) => {
const {dbId,table,schema} = props;
const {dbId, table, schema, scroll} = props;
const cols = [{
title: '序号',
......@@ -50,7 +50,7 @@ const Columns = (props: any) => {
dataIndex: 'keyFlag',
render: (_, record) => (
<>
{record.keyFlag?<KeyOutlined style={{ color:'#FAA100'}} />:undefined}
{record.keyFlag ? <KeyOutlined style={{color: '#FAA100'}}/> : undefined}
</>
),
filters: [
......@@ -64,12 +64,12 @@ const Columns = (props: any) => {
},
],
openSearch: 'dict',
},{
}, {
title: '自增',
dataIndex: 'autoIncrement',
render: (_, record) => (
<>
{record.autoIncrement?<CheckSquareOutlined style={{ color:'#1296db'}} />:undefined}
{record.autoIncrement ? <CheckSquareOutlined style={{color: '#1296db'}}/> : undefined}
</>
),
filters: [
......@@ -83,12 +83,12 @@ const Columns = (props: any) => {
},
],
openSearch: 'dict',
},{
}, {
title: '非空',
dataIndex: 'nullable',
render: (_, record) => (
<>
{!record.nullable?<CheckSquareOutlined style={{ color:'#1296db'}} />:undefined}
{!record.nullable ? <CheckSquareOutlined style={{color: '#1296db'}}/> : undefined}
</>
),
filters: [
......@@ -102,30 +102,31 @@ const Columns = (props: any) => {
},
],
openSearch: 'dict',
},{
}, {
title: '默认值',
dataIndex: 'defaultValue',
},{
}, {
title: '精度',
dataIndex: 'precision',
isString: false,
},{
}, {
title: '小数范围',
dataIndex: 'scale',
isString: false,
},{
}, {
title: '字符集',
dataIndex: 'characterSet',
},{
}, {
title: '排序规则',
dataIndex: 'collation',
},{
}, {
title: 'Java 类型',
dataIndex: 'javaType',
},]
return (
<DTable columns={cols}
dataSource={{url:'api/database/listColumns',params:{id:dbId,schemaName:schema,tableName:table}}}/>
scroll={scroll}
dataSource={{url: 'api/database/listColumns', params: {id: dbId, schemaName: schema, tableName: table}}}/>
)
};
......
......@@ -19,9 +19,7 @@
import type {Effect, Reducer} from "umi";
import {
handleAddOrUpdate
} from "@/components/Common/crud";
import {handleAddOrUpdate} from "@/components/Common/crud";
import type {SqlMetaData} from "@/components/Studio/StudioEvent/data";
export type ClusterType = {
......@@ -124,6 +122,7 @@ export type TabsItemType = {
title: string;
key: number,
value: string;
icon: any;
closable: boolean;
path: string[];
task?: TaskType;
......@@ -629,19 +628,23 @@ const Model: ModelType = {
let newCurrent = state.current;
for (let i = 0; i < newTabs.panes.length; i++) {
if (newTabs.panes[i].key == payload.key) {
newTabs.panes[i].title = payload.name;
newTabs.panes[i].task.alias = payload.name;
newTabs.panes[i].title = payload.title;
newTabs.panes[i].icon = payload.icon;
newTabs.panes[i].task.alias = payload.title;
newTabs.panes[i].path[newTabs.panes[i].path.length - 1] = payload.title;
}
if (newTabs.panes[i].key == newCurrent.key) {
newCurrent.title = payload.name;
newCurrent.task.alias = payload.name;
newCurrent.title = payload.title;
newCurrent.icon = payload.icon;
newCurrent.task.alias = payload.title;
newCurrent.path[newCurrent.path.length - 1] = payload.title;
}
}
if (newTabs.panes.length == 0) {
return {
...state,
current: undefined,
tabs: newTabs,
tabs: {...newTabs},
currentPath: ['引导页'],
};
}
......
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