From 7612657ded7bcdc63c011ffc039e53ce75cd012e Mon Sep 17 00:00:00 2001 From: Syngnat Date: Tue, 2 Jun 2026 11:54:06 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=84=20style(query-editor):=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=20v2=20=E6=9F=A5=E8=AF=A2=E5=B7=A5=E5=85=B7=E6=A0=8F?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 为查询工具栏控件增加 v2 专用 class,移除 v2 下 inline 固定宽度依赖 - 使用内容宽度约束选择区,避免最大行数后出现多余空白 - 覆盖 Ant Design Button.Group 负 margin 和伪元素合并效果 - 增加 CSS 静态断言覆盖对齐、间距和响应式布局 --- .../QueryEditor.external-sql-save.test.tsx | 35 ++++ frontend/src/components/QueryEditor.tsx | 171 ++++++++++-------- frontend/src/v2-theme.css | 111 +++++++++++- 3 files changed, 237 insertions(+), 80 deletions(-) diff --git a/frontend/src/components/QueryEditor.external-sql-save.test.tsx b/frontend/src/components/QueryEditor.external-sql-save.test.tsx index bc05b48..7f5384c 100644 --- a/frontend/src/components/QueryEditor.external-sql-save.test.tsx +++ b/frontend/src/components/QueryEditor.external-sql-save.test.tsx @@ -2359,6 +2359,41 @@ describe('QueryEditor external SQL save', () => { expect(css).toContain('body[data-ui-version="v2"] .gn-v2-query-results .query-result-tab-text {'); }); + it('keeps the v2 query editor toolbar grouped and compact', () => { + const source = readFileSync(new URL('./QueryEditor.tsx', import.meta.url), 'utf8'); + const css = readFileSync(new URL('../v2-theme.css', import.meta.url), 'utf8'); + + expect(source).toContain('gn-v2-query-toolbar-selects'); + expect(source).toContain('gn-v2-query-toolbar-actions'); + expect(source).toContain('gn-v2-query-toolbar-connection-select'); + expect(source).toContain('gn-v2-query-toolbar-database-select'); + expect(source).toContain('gn-v2-query-toolbar-max-rows-select'); + expect(source).toContain('gn-v2-query-toolbar-action-group'); + expect(source).toContain('style={isV2Ui ? undefined : { width: 150 }}'); + expect(source).toContain('style={isV2Ui ? undefined : { width: 200 }}'); + expect(source).toContain('style={isV2Ui ? undefined : { width: 170 }}'); + + expect(css).toContain('body[data-ui-version="v2"] .gn-v2-query-toolbar-selects'); + expect(css).toContain('body[data-ui-version="v2"] .gn-v2-query-toolbar-actions'); + expect(css).toContain('flex: 0 1 auto !important;'); + expect(css).toContain('justify-content: flex-start;'); + expect(css).toContain('height: 32px !important;'); + expect(css).toContain('line-height: 30px !important;'); + expect(css).toContain('display: inline-flex !important;'); + expect(css).toContain('gap: 6px;'); + expect(css).toContain('margin-left: 0 !important;'); + expect(css).toContain('max-width: 520px;'); + expect(css).toContain('width: 140px !important;'); + expect(css).toContain('width: 166px !important;'); + expect(css).toContain('width: 132px !important;'); + expect(css).toContain('width: 34px !important;'); + expect(css).toContain('@media (max-width: 900px)'); + + const queryToolbarCss = css.slice(css.indexOf('body[data-ui-version="v2"] .gn-v2-query-toolbar {'), css.indexOf('body[data-ui-version="v2"] .gn-v2-query-monaco-shell {')); + expect(queryToolbarCss).not.toContain('margin-left: auto;'); + expect(queryToolbarCss).not.toContain('justify-content: flex-end;'); + }); + it('coalesces editor result splitter dragging through requestAnimationFrame', async () => { const moveListeners: Array<(event: MouseEvent) => void> = []; const upListeners: Array<() => void> = []; diff --git a/frontend/src/components/QueryEditor.tsx b/frontend/src/components/QueryEditor.tsx index 9f11d34..eaa1918 100644 --- a/frontend/src/components/QueryEditor.tsx +++ b/frontend/src/components/QueryEditor.tsx @@ -4875,92 +4875,105 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc `}
- ({ label: db, value: db }))} - showSearch - /> - - { + setCurrentConnectionId(val); + setCurrentDb(''); + }} + options={queryCapableConnections.map(c => ({ label: c.name, value: c.id }))} + showSearch + /> + setQueryOptions({ maxRows: Number(val) })} + options={[ + { label: '最大行数:500', value: 500 }, + { label: '最大行数:1000', value: 1000 }, + { label: '最大行数:5000', value: 5000 }, + { label: '最大行数:20000', value: 20000 }, + { label: '最大行数:不限', value: 0 }, + ]} + /> - {loading && ( - - )} - - +
+
+ - + + {loading && ( + - - - - - - - - - - - - + + + + + - , onClick: () => handleAIAction('generate') }, - { key: 'ai-explain', label: '解释 SQL', icon: , onClick: () => handleAIAction('explain') }, - { key: 'ai-optimize', label: '优化 SQL', icon: , onClick: () => handleAIAction('optimize') }, - { type: 'divider' as const }, - { key: 'ai-schema', label: 'Schema 分析', icon: , onClick: () => handleAIAction('schema') }, - ] }} placement="bottomRight"> - - + + + + + + + +
diff --git a/frontend/src/v2-theme.css b/frontend/src/v2-theme.css index 66ced90..774ffd5 100644 --- a/frontend/src/v2-theme.css +++ b/frontend/src/v2-theme.css @@ -4662,8 +4662,117 @@ body[data-ui-version="v2"] .gn-v2-designer-toolbar { border-radius: 0 !important; } +body[data-ui-version="v2"] .gn-v2-query-toolbar { + min-height: 48px; + padding: 8px 12px !important; + gap: 6px 10px !important; + align-items: center !important; + background: var(--gn-bg-panel) !important; + border-bottom: 0.5px solid var(--gn-br-1) !important; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar-selects, +body[data-ui-version="v2"] .gn-v2-query-toolbar-actions { + min-width: 0; + gap: 6px !important; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar-selects { + flex: 0 1 auto !important; + flex-wrap: nowrap; + max-width: 520px; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar-actions { + flex: 0 1 auto !important; + flex-wrap: wrap; + justify-content: flex-start; +} + body[data-ui-version="v2"] .gn-v2-query-toolbar .ant-select { - min-width: 132px; + min-width: 0; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar-connection-select { + width: 140px !important; + flex: 0 1 140px !important; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar-database-select { + width: 166px !important; + flex: 1 1 166px !important; + max-width: 220px; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar-max-rows-select { + width: 132px !important; + flex: 0 0 132px !important; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar .ant-select-selector { + height: 32px !important; + padding: 0 10px !important; + border-radius: 9px !important; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar .ant-select-selection-item, +body[data-ui-version="v2"] .gn-v2-query-toolbar .ant-select-selection-placeholder { + line-height: 30px !important; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar .ant-btn { + height: 32px !important; + padding: 0 11px !important; + border-radius: 9px !important; + font-size: 12.5px !important; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar-action-group.ant-btn-group { + display: inline-flex !important; + align-items: center; + flex: 0 0 auto; + gap: 6px; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar-action-group.ant-btn-group > .ant-btn { + flex: 0 0 auto; + border-radius: 9px !important; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar-action-group.ant-btn-group > .ant-btn:not(:first-child) { + margin-left: 0 !important; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar-action-group.ant-btn-group > .ant-btn::before { + display: none !important; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar-icon-action.ant-btn, +body[data-ui-version="v2"] .gn-v2-query-toolbar .ant-btn-icon-only { + width: 34px !important; + padding: 0 !important; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar-run-action.ant-btn { + min-width: 64px; + padding: 0 13px !important; + font-weight: 650 !important; +} + +body[data-ui-version="v2"] .gn-v2-query-toolbar-ai-action.ant-btn { + font-weight: 650 !important; +} + +@media (max-width: 900px) { + body[data-ui-version="v2"] .gn-v2-query-toolbar-selects { + flex: 1 1 100% !important; + max-width: none; + } + + body[data-ui-version="v2"] .gn-v2-query-toolbar-actions { + width: 100%; + justify-content: flex-start; + } } body[data-ui-version="v2"] .gn-v2-query-monaco-shell {