mirror of
https://github.com/CodePhiliaX/Chat2DB.git
synced 2025-09-21 03:53:24 +08:00
style
This commit is contained in:
@ -2,6 +2,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 2px 20px;
|
||||
height: 42px;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1px solid var(--color-border-secondary);
|
||||
}
|
||||
|
@ -152,6 +152,17 @@ function MonacoEditor(props: IProps, ref: ForwardedRef<IExportRefFunction>) {
|
||||
}
|
||||
}, [editorRef.current, isActive]);
|
||||
|
||||
useEffect(() => {
|
||||
// 监听浏览器窗口大小变化,重新渲染编辑器
|
||||
const resize = () => {
|
||||
editorRef.current?.layout();
|
||||
};
|
||||
window.addEventListener('resize', resize);
|
||||
return () => {
|
||||
window.removeEventListener('resize', resize);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// 监听主题色变化切换编辑器主题色
|
||||
useEffect(() => {
|
||||
if (options?.theme) {
|
||||
|
@ -8,10 +8,9 @@
|
||||
}
|
||||
|
||||
.ant-spin-container {
|
||||
height: calc(100% - 48px);
|
||||
height: calc(100% - 40px);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.consoleEditor {
|
||||
@ -19,14 +18,17 @@
|
||||
}
|
||||
|
||||
.consoleEditorWithChat {
|
||||
height: calc(100% - 56px);
|
||||
height: calc(100% - 42px);
|
||||
}
|
||||
|
||||
.consoleOptionsWrapper {
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
bottom: 0px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
display: flex;
|
||||
margin: 0 12px;
|
||||
@ -59,4 +61,4 @@
|
||||
.saveButton {
|
||||
width: 70px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
|
@ -4,12 +4,29 @@
|
||||
url('../../assets/font/iconfont.ttf') format('truetype');
|
||||
}
|
||||
|
||||
.iconBox {
|
||||
height: var(--icon-box-size);
|
||||
width: var(--icon-box-size);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: var(--color-hover-bg);
|
||||
.iconfont {
|
||||
size: var(--icon-size);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: 'iconfont' !important;
|
||||
font-size: 14px;
|
||||
font-size: var(--icon-size);
|
||||
font-style: normal;
|
||||
user-select: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-webkit-text-stroke-width: 0.2px;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
}
|
||||
|
@ -20,16 +20,43 @@ if (__ENV__ === 'local') {
|
||||
style.appendChild(document.createTextNode(container));
|
||||
}
|
||||
|
||||
export default class Iconfont extends PureComponent<
|
||||
{
|
||||
code: string;
|
||||
} & React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>
|
||||
> {
|
||||
render() {
|
||||
return (
|
||||
<i {...this.props} className={classnames(this.props.className, styles.iconfont)}>
|
||||
{this.props.code}
|
||||
</i>
|
||||
);
|
||||
}
|
||||
interface IProps {
|
||||
code: string;
|
||||
box?: boolean;
|
||||
boxSize?: number;
|
||||
size?: number;
|
||||
className?: string;
|
||||
classNameBox?: string;
|
||||
}
|
||||
|
||||
const Iconfont = (props: IProps) => {
|
||||
const { box, boxSize = 32, size = 14, className, classNameBox, ...args } = props;
|
||||
return box ? (
|
||||
<div
|
||||
{...args}
|
||||
style={
|
||||
{
|
||||
'--icon-box-size': `${boxSize}px`,
|
||||
'--icon-size': `${size}px`,
|
||||
} as any
|
||||
}
|
||||
className={classnames(classNameBox, styles.iconBox)}
|
||||
>
|
||||
<i className={classnames(className, styles.iconfont)}>{props.code}</i>
|
||||
</div>
|
||||
) : (
|
||||
<i
|
||||
{...args}
|
||||
style={
|
||||
{
|
||||
'--icon-size': `${size}px`,
|
||||
} as any
|
||||
}
|
||||
className={classnames(className, styles.iconfont)}
|
||||
>
|
||||
{props.code}
|
||||
</i>
|
||||
);
|
||||
};
|
||||
|
||||
export default Iconfont;
|
||||
|
@ -2,19 +2,15 @@ import React, { memo, useEffect } from 'react';
|
||||
import styles from './index.less';
|
||||
import classnames from 'classnames';
|
||||
import { Table } from 'antd';
|
||||
import historyService, { IGetHistoryListParams } from '@/service/history';
|
||||
import { set } from 'lodash';
|
||||
|
||||
export interface IGetOutputParams extends IGetHistoryListParams {}
|
||||
import historyService, { IHistoryRecord } from '@/service/history';
|
||||
|
||||
interface IProps {
|
||||
className?: string;
|
||||
params: IGetOutputParams;
|
||||
}
|
||||
|
||||
export default memo<IProps>((props) => {
|
||||
const { className, params } = props;
|
||||
const [dataSource, setDataSource] = React.useState<any[]>([]);
|
||||
const { className } = props;
|
||||
const [dataSource, setDataSource] = React.useState<IHistoryRecord[]>([]);
|
||||
|
||||
const columns = [
|
||||
{
|
||||
@ -36,21 +32,32 @@ export default memo<IProps>((props) => {
|
||||
title: '数据库/schema',
|
||||
dataIndex: 'databaseName',
|
||||
key: 'databaseName',
|
||||
render: (value: string, record: IHistoryRecord) => {
|
||||
return <span>{`${record.dataSourceName}/${record.databaseName}`}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'ddl',
|
||||
dataIndex: 'ddl',
|
||||
key: 'ddl',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'state',
|
||||
key: 'state',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
render: (value: boolean) => {
|
||||
return <span style={{ color: value ? 'green' : 'red' }}>{value ? '成功' : '失败'}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'sql',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
title: '影响行数',
|
||||
dataIndex: 'operationRows',
|
||||
key: 'operationRows',
|
||||
},
|
||||
{
|
||||
title: '执行耗时',
|
||||
dataIndex: 'executionTime',
|
||||
key: 'executionTime',
|
||||
dataIndex: 'useTime',
|
||||
key: 'useTime',
|
||||
},
|
||||
];
|
||||
|
||||
@ -59,9 +66,14 @@ export default memo<IProps>((props) => {
|
||||
}, []);
|
||||
|
||||
const getHistoryList = () => {
|
||||
historyService.getHistoryList(params).then((res) => {
|
||||
setDataSource(res.data);
|
||||
});
|
||||
historyService
|
||||
.getHistoryList({
|
||||
pageNo: 1,
|
||||
pageSize: 100,
|
||||
})
|
||||
.then((res) => {
|
||||
setDataSource(res.data);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -26,6 +26,7 @@
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
height: 32px;
|
||||
flex-shrink: 0;
|
||||
background-color: var(--color-bg-base);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
&::-webkit-scrollbar {
|
||||
|
@ -22,10 +22,10 @@ export const editorDefaultOptions: IEditorOptions = {
|
||||
scrollbar: { // 滚动条
|
||||
alwaysConsumeMouseWheel: false, // 总是消耗鼠标滚轮
|
||||
},
|
||||
padding: {
|
||||
top: 2,
|
||||
bottom: 2,
|
||||
},
|
||||
// padding: {
|
||||
// top: 2,
|
||||
// bottom: 2,
|
||||
// },
|
||||
minimap: { // 缩略图
|
||||
enabled: false, // 启用
|
||||
},
|
||||
|
@ -115,7 +115,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
i {
|
||||
margin-right: 4px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ const TableList = dvaModel((props: any) => {
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = function (event) {
|
||||
const sqlContent = event.target?.result ?? '';
|
||||
const sqlContent = (event.target?.result ?? '') as string;
|
||||
addConsole(sqlContent);
|
||||
};
|
||||
|
||||
|
@ -14,17 +14,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
.workspaceRightMain {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.rightBar {
|
||||
flex-shrink: 0;
|
||||
width: 38px;
|
||||
border-left: 1px solid var(--color-border);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10px 0px;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tabBox {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.activeConsoleBox {
|
||||
|
@ -337,6 +337,7 @@ const WorkspaceRight = memo<IProps>((props: IProps) => {
|
||||
registerIntelliSenseTable(data, databaseType, dataSourceId, databaseName, schemaName);
|
||||
registerIntelliSenseField(tableList.current, dataSourceId, databaseName, schemaName);
|
||||
});
|
||||
console.log('getAllTable Before:', window._BaseURL);
|
||||
}
|
||||
}, [curWorkspaceParams.databaseType, curWorkspaceParams.databaseName, curWorkspaceParams.schemaName]);
|
||||
|
||||
@ -575,7 +576,7 @@ const WorkspaceRight = memo<IProps>((props: IProps) => {
|
||||
|
||||
return (
|
||||
<div className={classnames(styles.workspaceRight, className)}>
|
||||
<LoadingContent data={workspaceTabList} handleEmpty empty={renderEmpty()}>
|
||||
<LoadingContent className={styles.workspaceRightMain} data={workspaceTabList} handleEmpty empty={renderEmpty()}>
|
||||
<div className={styles.tabBox}>
|
||||
<TabsNew
|
||||
className={styles.tabs}
|
||||
@ -587,6 +588,14 @@ const WorkspaceRight = memo<IProps>((props: IProps) => {
|
||||
// lastTabCannotClosed
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.rightBar}>
|
||||
<div className={styles.rightBarFront}>
|
||||
<Iconfont code="" box size={16} />
|
||||
</div>
|
||||
<div className={styles.rightBarAfter}>
|
||||
<Iconfont code="" box size={20} />
|
||||
</div>
|
||||
</div>
|
||||
</LoadingContent>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { extend, ResponseError, type RequestOptionsInit } from 'umi-request';
|
||||
import { message } from 'antd';
|
||||
import { navigate } from '@/utils'
|
||||
import { navigate } from '@/utils';
|
||||
|
||||
export type IErrorLevel = 'toast' | 'prompt' | 'critical' | false;
|
||||
export interface IOptions {
|
||||
@ -10,7 +10,7 @@ export interface IOptions {
|
||||
delayTime?: number | true;
|
||||
outside?: boolean;
|
||||
isFullPath?: boolean;
|
||||
dynamicUrl?: boolean;
|
||||
dynamicUrl?: boolean;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
@ -127,11 +127,22 @@ request.interceptors.response.use(async (response) => {
|
||||
|
||||
export default function createRequest<P = void, R = {}>(url: string, options?: IOptions) {
|
||||
// 路由跳转
|
||||
const { method = 'get', mock = false, errorLevel = 'toast', delayTime, outside, isFullPath, dynamicUrl } = options || {};
|
||||
const {
|
||||
method = 'get',
|
||||
mock = false,
|
||||
errorLevel = 'toast',
|
||||
delayTime,
|
||||
outside,
|
||||
isFullPath,
|
||||
dynamicUrl,
|
||||
} = options || {};
|
||||
|
||||
// 是否需要mock
|
||||
const _baseURL = (mock ? mockUrl : baseURL) || '';
|
||||
return function (params: P, restParams?: RequestOptionsInit) {
|
||||
return function (params: P, restParams?: RequestOptionsInit) {
|
||||
// 是否需要mock
|
||||
const _baseURL = (mock ? mockUrl : baseURL) || '';
|
||||
// if (url === '/api/rdb/ddl/list') {
|
||||
// debugger;
|
||||
// }
|
||||
// 在url上按照定义规则拼接params
|
||||
const paramsInUrl: string[] = [];
|
||||
|
||||
@ -171,7 +182,7 @@ export default function createRequest<P = void, R = {}>(url: string, options?: I
|
||||
eventualUrl = isFullPath ? url : eventualUrl;
|
||||
|
||||
// 动态的url
|
||||
if(dynamicUrl){
|
||||
if (dynamicUrl) {
|
||||
eventualUrl = params as string;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,61 @@ export interface IUpdateConsoleParams {
|
||||
id: number;
|
||||
}
|
||||
|
||||
export interface IHistoryRecord {
|
||||
/**
|
||||
* 是否可连接
|
||||
*/
|
||||
connectable?: boolean | null;
|
||||
/**
|
||||
* DB名称
|
||||
*/
|
||||
databaseName?: null | string;
|
||||
/**
|
||||
* 数据源id
|
||||
*/
|
||||
dataSourceId?: number | null;
|
||||
/**
|
||||
* 数据源名称
|
||||
*/
|
||||
dataSourceName?: null | string;
|
||||
/**
|
||||
* ddl内容
|
||||
*/
|
||||
ddl?: null | string;
|
||||
/**
|
||||
* 扩展信息
|
||||
*/
|
||||
extendInfo?: null | string;
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
id?: number | null;
|
||||
/**
|
||||
* 文件别名
|
||||
*/
|
||||
name?: null | string;
|
||||
/**
|
||||
* 操作行数
|
||||
*/
|
||||
operationRows?: number | null;
|
||||
/**
|
||||
* schema名称
|
||||
*/
|
||||
schemaName?: null | string;
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
status?: null | string;
|
||||
/**
|
||||
* ddl语言类型
|
||||
*/
|
||||
type?: null | string;
|
||||
/**
|
||||
* 使用时长
|
||||
*/
|
||||
useTime?: number | null;
|
||||
}
|
||||
|
||||
const saveConsole = createRequest<ICreateConsole, number>('/api/operation/saved/create', { method: 'post' });
|
||||
|
||||
// orderByDesc true 降序
|
||||
|
@ -111,10 +111,19 @@ const updateTableExample = createRequest<{ dbType: DatabaseTypeCode }, string>('
|
||||
const exportCreateTableSql = createRequest<ITableParams, string>('/api/rdb/ddl/export', { method: 'get' });
|
||||
const executeTable = createRequest<IExecuteTableParams, string>('/api/rdb/ddl/execute', { method: 'post' });
|
||||
|
||||
const getColumnList = createRequest<ITableParams, IColumn[]>('/api/rdb/ddl/column_list', { method: 'get', delayTime: 200 });
|
||||
const getIndexList = createRequest<ITableParams, IColumn[]>('/api/rdb/ddl/index_list', { method: 'get', delayTime: 200 });
|
||||
const getColumnList = createRequest<ITableParams, IColumn[]>('/api/rdb/ddl/column_list', {
|
||||
method: 'get',
|
||||
delayTime: 200,
|
||||
});
|
||||
const getIndexList = createRequest<ITableParams, IColumn[]>('/api/rdb/ddl/index_list', {
|
||||
method: 'get',
|
||||
delayTime: 200,
|
||||
});
|
||||
const getKeyList = createRequest<ITableParams, IColumn[]>('/api/rdb/ddl/key_list', { method: 'get', delayTime: 200 });
|
||||
const getSchemaList = createRequest<ISchemaParams, ISchemaResponse[]>('/api/rdb/ddl/schema_list', { method: 'get', delayTime: 200 });
|
||||
const getSchemaList = createRequest<ISchemaParams, ISchemaResponse[]>('/api/rdb/ddl/schema_list', {
|
||||
method: 'get',
|
||||
delayTime: 200,
|
||||
});
|
||||
|
||||
const getDatabaseSchemaList = createRequest<{ dataSourceId: number }, MetaSchemaVO>(
|
||||
'/api/rdb/ddl/database_schema_list',
|
||||
@ -239,7 +248,7 @@ const getTableDetails = createRequest<
|
||||
|
||||
/** 获取库的所有表 */
|
||||
const getAllTableList = createRequest<
|
||||
{ dataSourceId: number; databaseName: string; schemaName?: string | null },
|
||||
{ dataSourceId: number; databaseName?: string | null; schemaName?: string | null },
|
||||
Array<{ name: string; comment: string }>
|
||||
>('/api/rdb/table/table_list', { method: 'get' });
|
||||
|
||||
|
@ -45,7 +45,7 @@ const registerIntelliSenseTable = (
|
||||
tableList: Array<{ name: string; comment: string }>,
|
||||
databaseCode?: DatabaseTypeCode,
|
||||
dataSourceId?: number,
|
||||
databaseName?: string,
|
||||
databaseName?: string | null,
|
||||
schemaName?: string | null,
|
||||
) => {
|
||||
monaco.editor.registerCommand('addFieldList', (_: any, ...args: any[]) => {
|
||||
@ -55,7 +55,7 @@ const registerIntelliSenseTable = (
|
||||
|
||||
intelliSenseTable.dispose();
|
||||
intelliSenseTable = monaco.languages.registerCompletionItemProvider('sql', {
|
||||
triggerCharacters: [' ', ],
|
||||
triggerCharacters: [' '],
|
||||
provideCompletionItems: (model, position) => {
|
||||
const lineContentUntilPosition = model.getValueInRange({
|
||||
startLineNumber: position.lineNumber,
|
||||
|
Reference in New Issue
Block a user