[fix](ui) fix database cannot be choosed bug (#32091)
This commit is contained in:
@ -6,9 +6,9 @@
|
||||
* 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
|
||||
@ -16,23 +16,23 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @file test cron
|
||||
* @author lpx
|
||||
* @since 2020/08/19
|
||||
*/
|
||||
import React, {useState} from 'react';
|
||||
import {Layout, Menu, Dropdown, notification, Button} from 'antd';
|
||||
import { CaretDownOutlined, LogoutOutlined} from '@ant-design/icons';
|
||||
import {renderRoutes} from 'react-router-config';
|
||||
import {useHistory} from 'react-router-dom';
|
||||
import {useTranslation} from 'react-i18next';
|
||||
import React, { useState } from 'react';
|
||||
import { Layout, Menu, Dropdown, notification, Button } from 'antd';
|
||||
import { CaretDownOutlined, LogoutOutlined } from '@ant-design/icons';
|
||||
import { renderRoutes } from 'react-router-config';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import routes from 'Src/router';
|
||||
import {logOut} from 'Src/api/api';
|
||||
import { logOut } from 'Src/api/api';
|
||||
import './index.css';
|
||||
import styles from './index.less';
|
||||
const {Header, Content, Footer} = Layout;
|
||||
const { Header, Content, Footer } = Layout;
|
||||
function Layouts(props: any) {
|
||||
let { t } = useTranslation();
|
||||
const [route, setRoute] = useState(props.route.routes);
|
||||
@ -48,7 +48,7 @@ function Layouts(props: any) {
|
||||
if (location.pathname === e.key) {
|
||||
location.reload();
|
||||
}
|
||||
if(location.pathname.includes('Playground')){
|
||||
if (location.pathname.includes('Playground')) {
|
||||
history.push(e.key);
|
||||
location.reload();
|
||||
}
|
||||
@ -59,52 +59,74 @@ function Layouts(props: any) {
|
||||
}
|
||||
function clearAllCookie() {
|
||||
var keys = document.cookie.match(/[^ =;]+(?=\=)/g);
|
||||
if(keys) {
|
||||
for(var i = keys.length; i--;)
|
||||
document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString()
|
||||
if (keys) {
|
||||
for (var i = keys.length; i--; )
|
||||
document.cookie =
|
||||
keys[i] + '=0;expires=' + new Date(0).toUTCString();
|
||||
}
|
||||
}
|
||||
function onLogout(){
|
||||
logOut().then((res)=>{
|
||||
localStorage.setItem('username','');
|
||||
function onLogout() {
|
||||
logOut().then((res) => {
|
||||
localStorage.removeItem('username');
|
||||
clearAllCookie();
|
||||
notification.success({message: t('exitSuccessfully')})
|
||||
notification.success({ message: t('exitSuccessfully') });
|
||||
history.push('/login');
|
||||
})
|
||||
});
|
||||
}
|
||||
function changeLanguage(){
|
||||
if (localStorage.getItem('I18N_LANGUAGE') === 'zh-CN'){
|
||||
localStorage.setItem('I18N_LANGUAGE','en');
|
||||
location.reload()
|
||||
function changeLanguage() {
|
||||
if (localStorage.getItem('I18N_LANGUAGE') === 'zh-CN') {
|
||||
localStorage.setItem('I18N_LANGUAGE', 'en');
|
||||
location.reload();
|
||||
} else {
|
||||
localStorage.setItem('I18N_LANGUAGE','zh-CN');
|
||||
location.reload()
|
||||
localStorage.setItem('I18N_LANGUAGE', 'zh-CN');
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item onClick={onLogout}>
|
||||
<LogoutOutlined style={{marginRight: 8}}/>
|
||||
<LogoutOutlined style={{ marginRight: 8 }} />
|
||||
{t('signOut')}
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
return (
|
||||
<Layout>
|
||||
<Header style={{position: 'fixed', zIndex: 99, width: '100%'}}>
|
||||
<div className={styles['logo']} onClick={()=>{history.replace('/home');setCurrent('')}}></div>
|
||||
<span className='userSet'>
|
||||
<Button style={{'color':'#000'}} type="text" size='small' onClick={changeLanguage}>{localStorage.getItem('I18N_LANGUAGE') === 'zh-CN' ? 'English' : '中文'}</Button>
|
||||
<Header style={{ position: 'fixed', zIndex: 99, width: '100%' }}>
|
||||
<div
|
||||
className={styles['logo']}
|
||||
onClick={() => {
|
||||
history.replace('/home');
|
||||
setCurrent('');
|
||||
}}
|
||||
></div>
|
||||
<span className="userSet">
|
||||
<Button
|
||||
style={{ color: '#000' }}
|
||||
type="text"
|
||||
size="small"
|
||||
onClick={changeLanguage}
|
||||
>
|
||||
{localStorage.getItem('I18N_LANGUAGE') === 'zh-CN'
|
||||
? 'English'
|
||||
: '中文'}
|
||||
</Button>
|
||||
<Dropdown overlay={menu}>
|
||||
<span className="ant-dropdown-link">
|
||||
{/* <img alt="" className='avatar' src=''/> */}
|
||||
{localStorage.getItem('username')} <CaretDownOutlined/>
|
||||
{localStorage.getItem('username')}{' '}
|
||||
<CaretDownOutlined />
|
||||
</span>
|
||||
</Dropdown>
|
||||
</span>
|
||||
<Menu theme="light" onClick={handleClick} selectedKeys={[current]} mode="horizontal">
|
||||
{routes?.routes[1]?.routes?.map(item => {
|
||||
if (item.title !== 'Login'&&item.title !== 'Home') {
|
||||
<Menu
|
||||
theme="light"
|
||||
onClick={handleClick}
|
||||
selectedKeys={[current]}
|
||||
mode="horizontal"
|
||||
>
|
||||
{routes?.routes[1]?.routes?.map((item) => {
|
||||
if (item.title !== 'Login' && item.title !== 'Home') {
|
||||
return (
|
||||
<Menu.Item key={item.path}>
|
||||
{item.title}
|
||||
@ -115,19 +137,22 @@ function Layouts(props: any) {
|
||||
</Menu>
|
||||
</Header>
|
||||
|
||||
<Content className="site-layout" style={{marginTop: 64}}>
|
||||
<div className="site-layout-background" style={{minHeight: 380}}>
|
||||
<Content className="site-layout" style={{ marginTop: 64 }}>
|
||||
<div
|
||||
className="site-layout-background"
|
||||
style={{ minHeight: 380 }}
|
||||
>
|
||||
{renderRoutes(route)}
|
||||
</div>
|
||||
</Content>
|
||||
|
||||
{/* <Footer style={{textAlign: 'center'}}>xxx</Footer> */}
|
||||
</Layout>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
export default Layouts;/**
|
||||
export default Layouts;
|
||||
/**
|
||||
* 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
|
||||
@ -135,9 +160,9 @@ export default Layouts;/**
|
||||
* 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
|
||||
@ -145,4 +170,3 @@ export default Layouts;/**
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
@ -16,15 +16,15 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {Input, Spin, Tree} from 'antd';
|
||||
import {HddOutlined, ReloadOutlined, TableOutlined} from '@ant-design/icons';
|
||||
import {AdHocAPI} from 'Src/api/api';
|
||||
import {useTranslation} from 'react-i18next';
|
||||
import {AdhocContentRouteKeyEnum,} from '../adhoc.data';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Input, Spin, Tree } from 'antd';
|
||||
import { HddOutlined, ReloadOutlined, TableOutlined } from '@ant-design/icons';
|
||||
import { AdHocAPI } from 'Src/api/api';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { AdhocContentRouteKeyEnum } from '../adhoc.data';
|
||||
import './index.css';
|
||||
|
||||
const {Search} = Input;
|
||||
const { Search } = Input;
|
||||
|
||||
interface DataNode {
|
||||
title: string;
|
||||
@ -36,7 +36,7 @@ interface DataNode {
|
||||
const initTreeDate: DataNode[] = [];
|
||||
|
||||
function updateTreeData(list: DataNode[], key, children) {
|
||||
return list.map(node => {
|
||||
return list.map((node) => {
|
||||
if (node.key === key) {
|
||||
return {
|
||||
...node,
|
||||
@ -48,7 +48,7 @@ function updateTreeData(list: DataNode[], key, children) {
|
||||
}
|
||||
|
||||
export function AdHocTree(props: any) {
|
||||
let {t} = useTranslation();
|
||||
let { t } = useTranslation();
|
||||
const [treeData, setTreeData] = useState(initTreeDate);
|
||||
const [realTree, setRealTree] = useState(initTreeDate);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@ -62,38 +62,41 @@ export function AdHocTree(props: any) {
|
||||
}, []);
|
||||
|
||||
function initTreeData(ac?: AbortController) {
|
||||
AdHocAPI.getDatabaseList({signal: ac?.signal}).then(res => {
|
||||
if (res.msg === 'success' && Array.isArray(res.data)) {
|
||||
const num = Math.random()
|
||||
const treeData = res.data.map((item, index) => {
|
||||
return {
|
||||
title: item,
|
||||
key: `${num}-1-${index}-${item}`,
|
||||
icon: <HddOutlined/>,
|
||||
};
|
||||
});
|
||||
setTreeData(treeData);
|
||||
getRealTree(treeData);
|
||||
}
|
||||
setLoading(false);
|
||||
}).catch(err => {
|
||||
});
|
||||
AdHocAPI.getDatabaseList({ signal: ac?.signal })
|
||||
.then((res) => {
|
||||
if (res.msg === 'success' && Array.isArray(res.data)) {
|
||||
const num = Math.random();
|
||||
const treeData = res.data.map((item, index) => {
|
||||
return {
|
||||
title: item,
|
||||
keys: [item],
|
||||
key: `${num}-1-${index}-${item}`,
|
||||
icon: <HddOutlined />,
|
||||
};
|
||||
});
|
||||
setTreeData(treeData);
|
||||
getRealTree(treeData);
|
||||
}
|
||||
setLoading(false);
|
||||
})
|
||||
.catch((err) => {});
|
||||
}
|
||||
|
||||
function onLoadData({key, children}) {
|
||||
function onLoadData({ key, children }) {
|
||||
const [, storey, , db_name] = key.split('-');
|
||||
const param = {
|
||||
db_name,
|
||||
// tbl_name,
|
||||
};
|
||||
return AdHocAPI.getDatabaseList(param).then(res => {
|
||||
return AdHocAPI.getDatabaseList(param).then((res) => {
|
||||
if (res.msg == 'success' && Array.isArray(res.data)) {
|
||||
const children = res.data.map((item, index) => {
|
||||
if (storey === '1') {
|
||||
return {
|
||||
title: item,
|
||||
keys: [param.db_name, item],
|
||||
key: `2-${index}-${param.db_name}-${item}`,
|
||||
icon: <TableOutlined/>,
|
||||
icon: <TableOutlined />,
|
||||
isLeaf: true,
|
||||
};
|
||||
}
|
||||
@ -108,23 +111,24 @@ export function AdHocTree(props: any) {
|
||||
function handleTreeSelect(
|
||||
keys: React.ReactText[],
|
||||
info: any,
|
||||
path: AdhocContentRouteKeyEnum = AdhocContentRouteKeyEnum.Result,
|
||||
path: AdhocContentRouteKeyEnum = AdhocContentRouteKeyEnum.Result
|
||||
) {
|
||||
if (keys.length > 0) {
|
||||
props.history.push(`/Playground/${path}/${keys[0].split(':')[1]}`);
|
||||
console.log(info);
|
||||
const tablePath = info.node.keys.join('-');
|
||||
if (info.node.keys.length > 0) {
|
||||
props.history.push(`/Playground/${path}/${tablePath}`);
|
||||
}
|
||||
}
|
||||
|
||||
function onSearch(e) {
|
||||
const {value} = e.target;
|
||||
const expandedKeys: any[] = treeData
|
||||
.map((item, index) => {
|
||||
if (getParentKey(value, treeData[index].children, index)) {
|
||||
return item.key
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
})
|
||||
const { value } = e.target;
|
||||
const expandedKeys: any[] = treeData.map((item, index) => {
|
||||
if (getParentKey(value, treeData[index].children, index)) {
|
||||
return item.key;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
setExpandedKeys(expandedKeys);
|
||||
setAutoExpandParent(true);
|
||||
getRealTree(treeData, value);
|
||||
@ -142,9 +146,11 @@ export function AdHocTree(props: any) {
|
||||
for (let i = 0; i < tree.length; i++) {
|
||||
const node = tree[i];
|
||||
if (node.title.includes(key)) {
|
||||
return true
|
||||
return true;
|
||||
} else {
|
||||
treeData[idx].children ? treeData[idx].children[i].title = node.title : ''
|
||||
treeData[idx].children
|
||||
? (treeData[idx].children[i].title = node.title)
|
||||
: '';
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -154,7 +160,7 @@ export function AdHocTree(props: any) {
|
||||
const realTree = inner(treeData);
|
||||
|
||||
function inner(treeData) {
|
||||
return treeData.map(item => {
|
||||
return treeData.map((item) => {
|
||||
const search = value || '';
|
||||
const index = item.title.indexOf(search);
|
||||
const beforeStr = item.title.substr(0, index);
|
||||
@ -162,19 +168,21 @@ export function AdHocTree(props: any) {
|
||||
const title =
|
||||
index > -1 ? (
|
||||
<span>
|
||||
{beforeStr}
|
||||
<span className="site-tree-search-value">{search}</span>
|
||||
{beforeStr}
|
||||
<span className="site-tree-search-value">
|
||||
{search}
|
||||
</span>
|
||||
{afterStr}
|
||||
</span>
|
||||
</span>
|
||||
) : (
|
||||
item.title
|
||||
);
|
||||
if (item.children) {
|
||||
return {...item, title, children: inner(item.children)};
|
||||
return { ...item, title, children: inner(item.children) };
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
title
|
||||
title,
|
||||
};
|
||||
});
|
||||
}
|
||||
@ -185,29 +193,35 @@ export function AdHocTree(props: any) {
|
||||
function debounce(fn, wait) {
|
||||
let timer = null;
|
||||
return function () {
|
||||
let context = this
|
||||
let args = arguments
|
||||
let context = this;
|
||||
let args = arguments;
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
timer = setTimeout(function () {
|
||||
fn.apply(context, args)
|
||||
}, wait)
|
||||
}
|
||||
fn.apply(context, args);
|
||||
}, wait);
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Spin spinning={loading} size="small"/>
|
||||
<Spin spinning={loading} size="small" />
|
||||
<div>
|
||||
<Search
|
||||
size="small"
|
||||
style={{padding: 5, position: 'fixed', zIndex: '99', width: '300px'}}
|
||||
style={{
|
||||
padding: 5,
|
||||
position: 'fixed',
|
||||
zIndex: '99',
|
||||
width: '300px',
|
||||
}}
|
||||
placeholder={t('search')}
|
||||
enterButton={<ReloadOutlined/>}
|
||||
enterButton={<ReloadOutlined />}
|
||||
onSearch={initTreeData}
|
||||
onChange={onSearch}/>
|
||||
onChange={onSearch}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Tree
|
||||
@ -217,16 +231,20 @@ export function AdHocTree(props: any) {
|
||||
onExpand={onExpand}
|
||||
expandedKeys={expandedKeys}
|
||||
autoExpandParent={autoExpandParent}
|
||||
style={{'width': '100%', height: '86vh', paddingTop: '35px', overflowY: 'scroll'}}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '86vh',
|
||||
paddingTop: '35px',
|
||||
overflowY: 'scroll',
|
||||
}}
|
||||
onSelect={(selectedKeys, info) =>
|
||||
handleTreeSelect(
|
||||
selectedKeys,
|
||||
info,
|
||||
AdhocContentRouteKeyEnum.Structure)
|
||||
AdhocContentRouteKeyEnum.Structure
|
||||
)
|
||||
}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -6,9 +6,9 @@
|
||||
* 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
|
||||
@ -16,15 +16,15 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
import React from 'react';
|
||||
import { Route, Redirect, Switch } from 'react-router-dom';
|
||||
import {getBasePath} from 'Src/utils/utils';
|
||||
import { checkLogin, getBasePath } from 'Src/utils/utils';
|
||||
|
||||
let isLogin = document.cookie;
|
||||
let isLogin = checkLogin();
|
||||
const renderRoutes = (routes, authPath = '/login') => {
|
||||
let basepath = getBasePath();
|
||||
if(routes){
|
||||
if (routes) {
|
||||
return (
|
||||
<Switch>
|
||||
{routes.map((route, i) => (
|
||||
@ -33,28 +33,27 @@ const renderRoutes = (routes, authPath = '/login') => {
|
||||
path={route.path}
|
||||
exact={route.exact}
|
||||
strict={route.strict}
|
||||
render= { props =>{
|
||||
if(props.location.pathname === basepath+'/'){
|
||||
return <Redirect to={"/home"} />;
|
||||
render={(props) => {
|
||||
if (props.location.pathname === basepath + '/') {
|
||||
return <Redirect to={'/home'} />;
|
||||
}
|
||||
if (isLogin) {
|
||||
return route.render ? (
|
||||
route.render({ ...props, route: route })
|
||||
) : (
|
||||
<route.component {...props} route={route} />
|
||||
)
|
||||
route.render({ ...props, route: route })
|
||||
) : (
|
||||
<route.component {...props} route={route} />
|
||||
);
|
||||
} else {
|
||||
isLogin = '1';
|
||||
return <Redirect to={authPath} />;
|
||||
}}
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Switch>
|
||||
)
|
||||
);
|
||||
}
|
||||
return null
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export default renderRoutes;
|
||||
|
||||
|
||||
@ -92,4 +92,12 @@ function replaceToTxt(str: string) {
|
||||
return strNoBr;
|
||||
}
|
||||
|
||||
export {isSuccess, getDbName, getTimeNow, getBasePath, replaceToTxt};
|
||||
function checkLogin() {
|
||||
const username = localStorage.getItem('username');
|
||||
if (username) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export {isSuccess, getDbName, getTimeNow, getBasePath, replaceToTxt, checkLogin};
|
||||
|
||||
Reference in New Issue
Block a user