mirror of
https://github.com/CodePhiliaX/Chat2DB.git
synced 2026-03-13 09:02:05 +08:00
fix:some bug
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
@import '../../styles/var.less';
|
||||
|
||||
.appTitleBar {
|
||||
background-color: var(--color-primary-bg);
|
||||
-webkit-app-region: drag;
|
||||
-webkit-user-select: none;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -12,11 +15,18 @@
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0px 10px;
|
||||
height: 100%;
|
||||
.appName {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
.rightSlot,.leftSlot{
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
}
|
||||
.spacer {
|
||||
width: 126px;
|
||||
@@ -27,6 +37,7 @@
|
||||
height: 100%;
|
||||
flex-shrink: 0;
|
||||
width: 126px;
|
||||
-webkit-app-region: no-drag;
|
||||
.windowsCloseBarItem {
|
||||
width: 42px;
|
||||
height: 100%;
|
||||
|
||||
@@ -3,6 +3,7 @@ import styles from './index.less';
|
||||
import classnames from 'classnames';
|
||||
import { useCommonStore } from '@/store/common';
|
||||
import Iconfont from '@/components/Iconfont';
|
||||
import BrandLogo from '@/components/BrandLogo';
|
||||
|
||||
interface IProps {
|
||||
className?: string;
|
||||
@@ -18,8 +19,8 @@ export default memo<IProps>((props) => {
|
||||
};
|
||||
});
|
||||
|
||||
const isWin = useMemo(() => {
|
||||
return window.electronApi?.getPlatform().isWin;
|
||||
const isMac = useMemo(() => {
|
||||
return window.electronApi?.getPlatform().isMac;
|
||||
}, []);
|
||||
|
||||
// const isWin = true;
|
||||
@@ -48,14 +49,16 @@ export default memo<IProps>((props) => {
|
||||
return (
|
||||
<div className={classnames(styles.appTitleBar, className)} onDoubleClick={handleDoubleClick}>
|
||||
<div className={styles.appTitleBarGlobal}>
|
||||
<div className={classnames({ [styles.windowsSpacer]: isWin })} />
|
||||
<div className={classnames({ [styles.windowsSpacer]: (!isMac && isMac !== void 0) }, styles.leftSlot)}>
|
||||
{(!isMac && isMac !== void 0) && <BrandLogo size={20} className={styles.brandLogo} />}
|
||||
</div>
|
||||
<div className={styles.appName}>Chat2DB Community</div>
|
||||
<div>{appTitleBarRightComponent}</div>
|
||||
<div className={styles.rightSlot}>{appTitleBarRightComponent}</div>
|
||||
</div>
|
||||
{isWin && (
|
||||
{(!isMac && isMac !== void 0) && (
|
||||
<div className={styles.windowsCloseBar}>
|
||||
<div className={styles.windowsCloseBarItem} onClick={handelMinimizeWindow}>
|
||||
<Iconfont code="" />
|
||||
<Iconfont size={16} code="" />
|
||||
</div>
|
||||
<div className={styles.windowsCloseBarItem} onClick={handelMaximize}>
|
||||
{isMaximized ? <Iconfont code="" /> : <Iconfont code="" />}
|
||||
|
||||
@@ -91,9 +91,6 @@ const SelectBoundInfo = memo((props: IProps) => {
|
||||
setSchemaList([]);
|
||||
setDatabaseNameList([]);
|
||||
getDatabaseList();
|
||||
} else {
|
||||
setSchemaList([]);
|
||||
getSchemaList();
|
||||
}
|
||||
}, [boundInfo.dataSourceId, isActive]);
|
||||
|
||||
@@ -103,6 +100,7 @@ const SelectBoundInfo = memo((props: IProps) => {
|
||||
return;
|
||||
}
|
||||
if (supportSchema) {
|
||||
setSchemaList([]);
|
||||
getSchemaList();
|
||||
}
|
||||
if (!supportSchema && boundInfo.databaseName) {
|
||||
|
||||
@@ -9,9 +9,9 @@ if (__ENV__ === 'local') {
|
||||
/* 在线链接服务仅供平台体验和调试使用,平台不承诺服务的稳定性,企业客户需下载字体包自行发布使用并做好备份。 */
|
||||
@font-face {
|
||||
font-family: 'iconfont'; /* Project id 3633546 */
|
||||
src: url('//at.alicdn.com/t/c/font_3633546_ahqjb5vaa0m.woff2?t=1704776615855') format('woff2'),
|
||||
url('//at.alicdn.com/t/c/font_3633546_ahqjb5vaa0m.woff?t=1704776615855') format('woff'),
|
||||
url('//at.alicdn.com/t/c/font_3633546_ahqjb5vaa0m.ttf?t=1704776615855') format('truetype');
|
||||
src: url('//at.alicdn.com/t/c/font_3633546_wtvchggsz6n.woff2?t=1704785517485') format('woff2'),
|
||||
url('//at.alicdn.com/t/c/font_3633546_wtvchggsz6n.woff?t=1704785517485') format('woff'),
|
||||
url('//at.alicdn.com/t/c/font_3633546_wtvchggsz6n.ttf?t=1704785517485') format('truetype');
|
||||
}
|
||||
`;
|
||||
const style = document.createElement('style');
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
|
||||
interface IProps {
|
||||
/** 最大请求次数 */
|
||||
/** Maximum number of requests */
|
||||
maxAttempts?: number;
|
||||
/** 请求间隔时间ms */
|
||||
/** Request interval ms */
|
||||
interval?: number;
|
||||
/** 请求服务 */
|
||||
/** demand service */
|
||||
loopService: (...rest) => Promise<boolean>;
|
||||
}
|
||||
|
||||
@@ -15,10 +15,8 @@ export enum ServiceStatus {
|
||||
FAILURE = 'FAILURE',
|
||||
}
|
||||
|
||||
let intervalId: NodeJS.Timeout;
|
||||
|
||||
/**
|
||||
* 轮询请求后端服务
|
||||
* Polling request back-end service
|
||||
*/
|
||||
const usePollRequestService = ({ maxAttempts = 200, interval = 200, loopService }: IProps) => {
|
||||
const [serviceStatus, setServiceStatus] = useState<ServiceStatus>(ServiceStatus.PENDING);
|
||||
@@ -26,34 +24,31 @@ const usePollRequestService = ({ maxAttempts = 200, interval = 200, loopService
|
||||
const attempts = useRef(0);
|
||||
|
||||
const serviceFn = async () => {
|
||||
// 第一次请求失败,启动服务
|
||||
// The first request fails. Start the service
|
||||
if (attempts.current === 1 && ServiceStatus.SUCCESS !== serviceStatus) {
|
||||
window.electronApi?.startServerForSpawn();
|
||||
}
|
||||
if (attempts.current >= maxAttempts) {
|
||||
setServiceStatus(ServiceStatus.FAILURE);
|
||||
clearInterval(intervalId);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
attempts.current = attempts.current + 1;
|
||||
await loopService();
|
||||
setServiceStatus(ServiceStatus.SUCCESS);
|
||||
clearInterval(intervalId);
|
||||
} catch (error) {
|
||||
// setAttempts(attempts + 1);
|
||||
}
|
||||
attempts.current = attempts.current + 1;
|
||||
loopService().then((res) => {
|
||||
if (res) {
|
||||
setServiceStatus(ServiceStatus.SUCCESS);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
setTimeout(serviceFn, interval);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
serviceFn();
|
||||
if (serviceStatus !== ServiceStatus.SUCCESS) {
|
||||
intervalId = setInterval(serviceFn, interval);
|
||||
}
|
||||
return () => clearInterval(intervalId);
|
||||
}, [maxAttempts, interval, restart]);
|
||||
|
||||
// 新增加的重置函数
|
||||
// Newly added reset function
|
||||
const restartPolling = () => {
|
||||
setServiceStatus(ServiceStatus.PENDING);
|
||||
attempts.current = 0;
|
||||
|
||||
@@ -28,14 +28,6 @@
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.appTitleBar {
|
||||
height: 30px;
|
||||
background-color: var(--color-primary-bg);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
-webkit-app-region: drag;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.appBody {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
|
||||
@@ -24,6 +24,7 @@ import useClickAndDoubleClick from '@/hooks/useClickAndDoubleClick';
|
||||
import { useConnectionStore, getConnectionList } from '@/pages/main/store/connection';
|
||||
import { setMainPageActiveTab } from '@/pages/main/store/main';
|
||||
import { setCurrentConnectionDetails } from '@/pages/main/workspace/store/common';
|
||||
import { getOpenConsoleList } from '@/pages/main/workspace/store/console';
|
||||
|
||||
import styles from './index.less';
|
||||
|
||||
@@ -75,7 +76,10 @@ const ConnectionsPage = () => {
|
||||
// 禁止冒泡到menuItem
|
||||
e.domEvent?.stopPropagation?.();
|
||||
connectionService.remove({ id: t.id }).then(() => {
|
||||
getConnectionList();
|
||||
getConnectionList().then(() => {
|
||||
// 连接删除后需要更新下 consoleList
|
||||
getOpenConsoleList();
|
||||
});
|
||||
if (connectionActiveId === t.id) {
|
||||
setConnectionActiveId(null);
|
||||
setConnectionDetail(null);
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 68px;
|
||||
width: 52px;
|
||||
padding-top: 20px;
|
||||
background-color: var(--color-bg-subtle);
|
||||
border-right: 1px solid var(--color-border-secondary);
|
||||
user-select: none;
|
||||
@@ -35,7 +36,7 @@
|
||||
.brandLogo {
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
margin: 20px auto;
|
||||
margin-bottom: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Dropdown, Tooltip } from 'antd';
|
||||
import classnames from 'classnames';
|
||||
@@ -33,6 +33,7 @@ import Setting from '@/blocks/Setting';
|
||||
import styles from './index.less';
|
||||
import { useUpdateEffect } from '@/hooks';
|
||||
|
||||
|
||||
const initNavConfig: INavItem[] = [
|
||||
{
|
||||
key: 'workspace',
|
||||
@@ -70,10 +71,10 @@ const initNavConfig: INavItem[] = [
|
||||
|
||||
function MainPage() {
|
||||
const navigate = useNavigate();
|
||||
const { userInfo } = useUserStore(state => {
|
||||
const { userInfo } = useUserStore((state) => {
|
||||
return {
|
||||
userInfo: state.curUser
|
||||
}
|
||||
userInfo: state.curUser,
|
||||
};
|
||||
});
|
||||
const [navConfig, setNavConfig] = useState<INavItem[]>(initNavConfig);
|
||||
const mainPageActiveTab = useMainStore((state) => state.mainPageActiveTab);
|
||||
@@ -81,16 +82,20 @@ function MainPage() {
|
||||
__ENV__ === 'desktop' ? mainPageActiveTab : window.location.pathname.split('/')[1] || mainPageActiveTab,
|
||||
);
|
||||
|
||||
const isMac = useMemo(() => {
|
||||
return window.electronApi?.getPlatform().isMac;
|
||||
}, []);
|
||||
|
||||
// 当页面在workspace时,显示自定义布局
|
||||
useEffect(() => {
|
||||
if(mainPageActiveTab === 'workspace'){
|
||||
if (mainPageActiveTab === 'workspace') {
|
||||
setAppTitleBarRightComponent(<CustomLayout />);
|
||||
}else{
|
||||
} else {
|
||||
setAppTitleBarRightComponent(false);
|
||||
}
|
||||
return () => {
|
||||
setAppTitleBarRightComponent(false);
|
||||
}
|
||||
};
|
||||
}, [mainPageActiveTab]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -183,7 +188,7 @@ function MainPage() {
|
||||
return (
|
||||
<div className={styles.page}>
|
||||
<div className={styles.layoutLeft}>
|
||||
<BrandLogo size={40} onClick={() => {}} className={styles.brandLogo} />
|
||||
{(isMac || isMac === void 0) && <BrandLogo size={40} className={styles.brandLogo} />}
|
||||
<ul className={styles.navList}>
|
||||
{navConfig.map((item) => {
|
||||
return (
|
||||
|
||||
@@ -8,7 +8,6 @@ import connectionService from '@/service/connection';
|
||||
|
||||
import { setCurrentConnectionDetails } from '@/pages/main/workspace/store/common';
|
||||
import { useWorkspaceStore } from '@/pages/main/workspace/store';
|
||||
import { getOpenConsoleList } from '@/pages/main/workspace/store/console';
|
||||
|
||||
export interface IConnectionStore {
|
||||
connectionList: IConnectionListItem[] | null;
|
||||
@@ -46,8 +45,6 @@ export const getConnectionList: () => Promise<IConnectionListItem[]> = () => {
|
||||
const connectionList = res?.data || [];
|
||||
useConnectionStore.setState({ connectionList });
|
||||
resolve(connectionList);
|
||||
// 连接删除后需要更新下 consoleList
|
||||
getOpenConsoleList();
|
||||
|
||||
// 如果连接列表为空,则设置当前连接为空
|
||||
if (connectionList.length === 0) {
|
||||
|
||||
@@ -35,7 +35,7 @@ const Team = () => {
|
||||
<Tabs
|
||||
className={styles.teamTabsBox}
|
||||
activeKey={activeKey}
|
||||
onChange={(activeKey) => setActiveKey(activeKey)}
|
||||
onChange={(_activeKey) => setActiveKey(_activeKey)}
|
||||
items={tabList.map((tab, index) => {
|
||||
return {
|
||||
key: String(index),
|
||||
|
||||
@@ -103,8 +103,16 @@ const WorkspaceTabs = memo(() => {
|
||||
);
|
||||
data.forEach((item) => {
|
||||
const editData = workspaceTabList?.find((t) => t.id === item.key);
|
||||
// table 和 !editData?.type 为了兼容老数据
|
||||
if (editData?.type === WorkspaceTabType.CONSOLE || editData?.type === 'table' as any || !editData?.type) {
|
||||
if (
|
||||
editData?.type === WorkspaceTabType.CONSOLE ||
|
||||
editData?.type === WorkspaceTabType.FUNCTION ||
|
||||
editData?.type === WorkspaceTabType.PROCEDURE ||
|
||||
editData?.type === WorkspaceTabType.TRIGGER ||
|
||||
editData?.type === WorkspaceTabType.VIEW ||
|
||||
// table 和 !editData?.type 为了兼容老数据
|
||||
editData?.type === ('table' as any) ||
|
||||
!editData?.type
|
||||
) {
|
||||
closeWindowTab(item.key as number);
|
||||
}
|
||||
});
|
||||
@@ -126,17 +134,18 @@ const WorkspaceTabs = memo(() => {
|
||||
name: t.label,
|
||||
};
|
||||
historyService.updateSavedConsole(_params);
|
||||
|
||||
const _workspaceTabList:any = workspaceTabList?.map((item) => {
|
||||
if (item.id === t.key) {
|
||||
return {
|
||||
...item,
|
||||
title: t.label,
|
||||
};
|
||||
}
|
||||
return item;
|
||||
}) || []
|
||||
setWorkspaceTabList(_workspaceTabList)
|
||||
|
||||
const _workspaceTabList: any =
|
||||
workspaceTabList?.map((item) => {
|
||||
if (item.id === t.key) {
|
||||
return {
|
||||
...item,
|
||||
title: t.label,
|
||||
};
|
||||
}
|
||||
return item;
|
||||
}) || [];
|
||||
setWorkspaceTabList(_workspaceTabList);
|
||||
};
|
||||
|
||||
// 修改tab详情
|
||||
|
||||
2
chat2db-client/typings.d.ts
vendored
2
chat2db-client/typings.d.ts
vendored
@@ -32,7 +32,7 @@ declare global {
|
||||
getPlatform: () => {
|
||||
isLinux: boolean,
|
||||
isWin: boolean,
|
||||
isLinux: boolean,
|
||||
isMac: boolean,
|
||||
};
|
||||
minimizeWindow: () => void;
|
||||
closeWindow: () => void;
|
||||
|
||||
Reference in New Issue
Block a user