Skip to content

Commit cbaba0d

Browse files
committed
【New Features】Added history panel
1 parent 41f9483 commit cbaba0d

26 files changed

Lines changed: 314 additions & 225 deletions

File tree

.vscode/settings.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"favicons",
3030
"fulltext",
3131
"ghostoy",
32+
"hljs",
3233
"iconfont",
3334
"jdbc",
3435
"macos",
@@ -41,6 +42,7 @@
4142
"nsis",
4243
"OPENAI",
4344
"ossutil",
45+
"partialize",
4446
"pgsql",
4547
"pnpm",
4648
"Popconfirm",
@@ -49,6 +51,7 @@
4951
"remaininguses",
5052
"RESTAI",
5153
"samuelmeuli",
54+
"scroller",
5255
"Sercurity",
5356
"sortablejs",
5457
"temurin",
@@ -66,6 +69,7 @@
6669
"Wppk",
6770
"xcrun",
6871
"yapi",
69-
"yizhoumo"
72+
"yizhoumo",
73+
"zustand"
7074
]
7175
}

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
# 3.0.9
22
`2023-11-01`
3-
43
**Changelog**
54
- ⭐【New Features】Query results can be refreshed
5+
- ⭐【New Features】Added history panel
66
- ⚡️【Optimize】Console Tabs adaptive width
77
- 🐞【Fixed】console save bug
88
- 🐞【Fixed】sqlite can only retrieve one piece of data
99

1010
**更新日志**
1111
- ⭐【新功能】查询结果支持刷新
12+
- ⭐【新功能】增加历史记录面板
1213
- ⚡️【优化】控制台Tabs自适应宽度
1314
- 🐞【修复】console保存bug
1415
- 🐞【修复】sqlite只能查到一条数据问题

chat2db-client/src/components/Console/MonacoEditor/index.tsx

Lines changed: 27 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -82,51 +82,11 @@ function MonacoEditor(props: IProps, ref: ForwardedRef<IExportRefFunction>) {
8282
func(quickInputService);
8383
});
8484

85-
const { colorPrimary } = window._AppThemePack;
86-
const colors = {
87-
'editor.lineHighlightBackground': colorPrimary + '14', // 当前行背景色
88-
'editor.selectionBackground': colorPrimary + '20', // 选中文本的背景色
89-
// 'editorLineNumber.foreground': colorPrimary, // 行号颜色
90-
'editorLineNumber.activeForeground': colorPrimary, // 当前行号颜色
91-
// 'editorCursor.foreground': colorPrimary, // 光标颜色
92-
'editorRuler.foreground': colorPrimary + '15',
93-
};
94-
monaco.editor.defineTheme(ThemeType.Light, {
95-
base: 'vs',
96-
inherit: true,
97-
rules: [{ background: '#15161a' }] as any,
98-
colors: {
99-
...colors,
100-
'editor.foreground': '#000000',
101-
'editor.background': '#fff', //背景色
102-
},
103-
});
104-
105-
monaco.editor.defineTheme(ThemeType.Dark, {
106-
base: 'vs-dark',
107-
inherit: true,
108-
rules: [{ background: '#15161a' }] as any,
109-
colors: {
110-
'editor.foreground': '#ffffff',
111-
'editor.background': '#0A0B0C', //背景色
112-
},
113-
});
114-
monaco.editor.defineTheme(ThemeType.DarkDimmed, {
115-
base: 'vs-dark',
116-
inherit: true,
117-
rules: [{ background: '#15161a' }] as any,
118-
colors: {
119-
'editor.foreground': '#ffffff',
120-
'editor.background': '#1c2128', //背景色
121-
},
122-
});
123-
12485
monaco.editor.defineTheme(EditorThemeType.DashboardLightTheme, {
12586
base: 'vs',
12687
inherit: true,
12788
rules: [{ background: '#15161a' }] as any,
12889
colors: {
129-
...colors,
13090
'editor.foreground': '#000000',
13191
'editor.background': '#f8f9fa', //背景色
13292
},
@@ -193,6 +153,30 @@ function MonacoEditor(props: IProps, ref: ForwardedRef<IExportRefFunction>) {
193153
monaco.editor.setTheme(options.theme);
194154
return;
195155
}
156+
157+
// TODO: 因为在appTheme变化以后_AppThemePack并没有变化,所以这里需要延迟一下,但是这里要去掉
158+
159+
const { colorPrimary, colorBgBase, colorTextBase } = window._AppThemePack;
160+
161+
const colors = {
162+
'editor.lineHighlightBackground': colorPrimary + '14', // 当前行背景色
163+
'editor.selectionBackground': colorPrimary + '20', // 选中文本的背景色
164+
// 'editorLineNumber.foreground': colorPrimary, // 行号颜色
165+
'editorLineNumber.activeForeground': colorPrimary, // 当前行号颜色
166+
// 'editorCursor.foreground': colorPrimary, // 光标颜色
167+
'editorRuler.foreground': colorPrimary + '15', // 右侧竖线颜色
168+
'editor.foreground': colorTextBase, // 文本颜色
169+
'editor.background': colorBgBase, //背景色
170+
};
171+
172+
monaco.editor.defineTheme(appTheme.backgroundColor, {
173+
// base 如果appTheme.backgroundColor包含dark则为vs-dark,否则为vs
174+
base: appTheme.backgroundColor.includes(ThemeType.Dark) ? 'vs-dark' : 'vs',
175+
inherit: true, // 是否继承vscode默认主题
176+
rules: [{ background: '#15161a' }] as any,
177+
colors,
178+
});
179+
196180
monaco.editor.setTheme(appTheme.backgroundColor);
197181
}, [appTheme.backgroundColor, options?.theme]);
198182

@@ -213,9 +197,9 @@ function MonacoEditor(props: IProps, ref: ForwardedRef<IExportRefFunction>) {
213197
appendMonacoValue(editorRef.current, text, range);
214198
};
215199

216-
const toFocus = () => {
217-
editorRef.current?.focus();
218-
};
200+
// const toFocus = () => {
201+
// editorRef.current?.focus();
202+
// };
219203

220204
/**
221205
* 获取当前选中的内容

chat2db-client/src/components/CustomLayout/index.less

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,15 @@
3939
&::after {
4040
top: 0;
4141
bottom: 0;
42-
right: 5px;
43-
width: 1px;
42+
right: 0;
43+
width: 6px;
4444
}
4545
}
4646

4747
.iconPanelRightHidden {
4848
&::after {
49-
width: 6px;
49+
right: 5px;
50+
width: 1px;
5051
}
5152
}
5253
}

chat2db-client/src/components/CustomLayout/index.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ interface IProps {
99

1010
export default memo<IProps>((props) => {
1111
const { className } = props;
12-
const { panelLeft, togglePanelLeft } = useWorkspaceStore((state) => {
12+
const { panelLeft, panelRight, togglePanelLeft, togglePanelRight } = useWorkspaceStore((state) => {
1313
return {
1414
togglePanelLeft: state.togglePanelLeft,
15+
togglePanelRight: state.togglePanelRight,
1516
panelLeft: state.layout.panelLeft,
17+
panelRight: state.layout.panelRight,
1618
};
1719
});
1820

@@ -22,7 +24,10 @@ export default memo<IProps>((props) => {
2224
className={classnames(styles.iconPanelLeft, styles.iconPanel, { [styles.iconPanelLeftHidden]: !panelLeft })}
2325
onClick={togglePanelLeft}
2426
/>
25-
{/* <div className={classnames(styles.iconPanelRight, styles.iconPanel, { [styles.iconPanelRightHidden]: false })} /> */}
27+
<div
28+
className={classnames(styles.iconPanelRight, styles.iconPanel, { [styles.iconPanelRightHidden]: !panelRight })}
29+
onClick={togglePanelRight}
30+
/>
2631
</div>
2732
);
2833
});

chat2db-client/src/components/Loading/Loading/index.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
.load-container .container .dot {
1818
width: 8px;
1919
height: 8px;
20-
background-color: var(--custom-primary-color);
20+
background-color: var(--primary-color);
2121
border-radius: 100%;
2222
position: absolute;
2323
-webkit-animation: bouncedelay 1.2s infinite ease-in-out;

chat2db-client/src/components/Output/index.less

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
.output {
44
width: 100%;
55
height: 100%;
6-
overflow-y: auto;
76
position: relative;
7+
display: flex;
8+
flex-direction: column;
89
.outputTitle {
910
position: sticky;
1011
top: 0;
1112
z-index: 1;
12-
background-color: var(--color-bg-base);
13+
background-color: var(--color-bg-subtle);
1314
border-bottom: 1px solid var(--color-border);
1415
line-height: 32px;
1516
display: flex;
@@ -21,22 +22,38 @@
2122
}
2223
}
2324
.outputContent {
24-
padding: 0px 10px 10px;
25-
box-sizing: border-box;
25+
padding: 10px;
26+
overflow-y: auto;
27+
flex: 1;
28+
height: 0px;
2629
.outputItem {
2730
.timeBox {
2831
display: flex;
2932
align-items: center;
3033
}
34+
.timeSpan{
35+
margin-right: 4px;
36+
}
3137
.iconBox {
3238
transform: rotate(90deg);
3339
margin-right: 4px;
3440
i {
3541
color: var(--color-success);
3642
}
3743
}
44+
.failureIconBox{
45+
i {
46+
color: var(--color-error);
47+
}
48+
}
3849
> div {
39-
line-height: 20px;
50+
line-height: 22px;
51+
}
52+
.sqlPlace{
53+
color: var(--color-warning-text);
54+
}
55+
.sqlPlace,.sqlBox{
56+
padding-left: 18px;
4057
}
4158
padding: 2px 0px;
4259
}

chat2db-client/src/components/Output/index.tsx

Lines changed: 62 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,88 @@
1-
import React, { memo, useEffect } from 'react';
1+
import React, { memo } from 'react';
22
import styles from './index.less';
33
import classnames from 'classnames';
44
import Iconfont from '@/components/Iconfont';
5+
import ScrollLoading from '@/components/ScrollLoading';
56
import historyService, { IHistoryRecord } from '@/service/history';
6-
import MonacoEditor from '@/components/Console/MonacoEditor';
7+
import * as monaco from 'monaco-editor';
8+
import i18n from '@/i18n';
9+
710
interface IProps {
811
className?: string;
12+
curWorkspaceParams: any;
13+
}
14+
15+
interface IDatasource extends IHistoryRecord {
16+
highlightedCode: string; // sql处理过的高亮代码
917
}
1018

1119
export default memo<IProps>((props) => {
1220
const { className } = props;
13-
const [dataSource, setDataSource] = React.useState<IHistoryRecord[]>([]);
14-
15-
useEffect(() => {
16-
getHistoryList();
17-
}, []);
18-
21+
const [dataSource, setDataSource] = React.useState<IDatasource[]>([]);
22+
const outputContentRef = React.useRef<HTMLDivElement>(null);
23+
const curPageRef = React.useRef(1);
24+
const finishedRef = React.useRef(false);
25+
1926
const getHistoryList = () => {
20-
historyService
27+
return historyService
2128
.getHistoryList({
22-
pageNo: 3,
23-
pageSize: 100,
29+
dataSourceId:props.curWorkspaceParams.dataSourceId,
30+
pageNo: curPageRef.current++,
31+
pageSize: 40,
2432
})
2533
.then((res) => {
26-
setDataSource(res.data);
34+
finishedRef.current = !res.hasNextPage;
35+
const promiseList = res.data.map((item) => {
36+
return new Promise((resolve) => {
37+
// 不换行
38+
const ddl = (item.ddl || '')?.replace(/\n/g, ' ');
39+
monaco.editor.colorize(ddl, 'sql', {}).then((_res) => {
40+
resolve({
41+
...item,
42+
highlightedCode: _res,
43+
});
44+
});
45+
});
46+
});
47+
Promise.all(promiseList).then((_res) => {
48+
setDataSource([...dataSource, ..._res] as any);
49+
});
2750
});
2851
};
2952

3053
return (
3154
<div className={classnames(styles.output, className)}>
3255
<div className={styles.outputTitle}>
3356
<Iconfont code="&#xe8ad;" />
34-
执行记录
57+
{i18n('common.title.executiveLogging')}
3558
</div>
36-
<div className={styles.outputContent}>
37-
{dataSource.map((item, index) => {
38-
const nameList = [item.dataSourceName, item.databaseName, item.schemaName];
39-
return (
40-
<div key={index} className={styles.outputItem}>
41-
<div className={styles.timeBox}>
42-
<div className={styles.iconBox}>
43-
<Iconfont code="&#xe650;" />
59+
<div className={styles.outputContent} ref={outputContentRef}>
60+
<ScrollLoading
61+
onReachBottom={getHistoryList}
62+
scrollerElement={outputContentRef}
63+
threshold={300}
64+
finished={finishedRef.current}
65+
>
66+
<>
67+
{dataSource.map((item, index) => {
68+
const nameList = [item.databaseName, item.schemaName];
69+
return (
70+
<div key={index} className={styles.outputItem}>
71+
<div className={styles.timeBox}>
72+
<div className={classnames(styles.iconBox, { [styles.failureIconBox]: item.status !== 'success' })}>
73+
<Iconfont code="&#xe650;" />
74+
</div>
75+
<span className={styles.timeSpan}>[2023-10-15 14:50:29]</span>
76+
{!!item.operationRows && <span>{item.operationRows} rows</span>}
77+
{!!item.useTime && <span>affected in {item.useTime} ms</span>}
78+
</div>
79+
<div className={styles.sqlPlace}>{nameList.filter((name) => name).join(' > ')}</div>
80+
<div className={styles.sqlBox} dangerouslySetInnerHTML={{ __html: item.highlightedCode }} />
4481
</div>
45-
<span>[2023-10-15 14:50:29]</span>
46-
{item.operationRows && <span>{item.operationRows} rows</span>}
47-
{item.useTime && <span>affected in{item.useTime} ms</span>}
48-
</div>
49-
<div>{nameList.filter((name) => name).join(' > ')}</div>
50-
<div className={styles.sqlBox}>
51-
{item.ddl}
52-
{/* <MonacoEditor
53-
options={{
54-
// 不需要行号
55-
lineNumbers: 'off',
56-
readOnly: true,
57-
minimap: {
58-
enabled: false,
59-
},
60-
}}
61-
id={`output-content-${index}`}
62-
defaultValue={item.ddl || ''}
63-
/> */}
64-
</div>
65-
</div>
66-
);
67-
})}
82+
);
83+
})}
84+
</>
85+
</ScrollLoading>
6886
</div>
6987
</div>
7088
);

0 commit comments

Comments
 (0)