Skip to content

Commit 91eb0de

Browse files
committed
feat: 快捷启动按钮优化
1 parent 6dd4002 commit 91eb0de

File tree

8 files changed

+162
-195
lines changed

8 files changed

+162
-195
lines changed

ui/components.d.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,13 @@ declare module 'vue' {
3232
KanbanColumn: typeof import('./src/components/kanban/KanbanColumn.vue')['default']
3333
LanguageSwitcher: typeof import('./src/components/common/LanguageSwitcher.vue')['default']
3434
NAlert: typeof import('naive-ui')['NAlert']
35-
NAvatar: typeof import('naive-ui')['NAvatar']
3635
NBadge: typeof import('naive-ui')['NBadge']
3736
NBreadcrumb: typeof import('naive-ui')['NBreadcrumb']
3837
NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem']
3938
NButton: typeof import('naive-ui')['NButton']
4039
NButtonGroup: typeof import('naive-ui')['NButtonGroup']
4140
NCard: typeof import('naive-ui')['NCard']
4241
NCheckbox: typeof import('naive-ui')['NCheckbox']
43-
NCollapse: typeof import('naive-ui')['NCollapse']
44-
NCollapseItem: typeof import('naive-ui')['NCollapseItem']
4542
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
4643
NColorPicker: typeof import('naive-ui')['NColorPicker']
4744
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
@@ -57,26 +54,20 @@ declare module 'vue' {
5754
NEmpty: typeof import('naive-ui')['NEmpty']
5855
NForm: typeof import('naive-ui')['NForm']
5956
NFormItem: typeof import('naive-ui')['NFormItem']
60-
NGi: typeof import('naive-ui')['NGi']
6157
NGlobalStyle: typeof import('naive-ui')['NGlobalStyle']
62-
NGrid: typeof import('naive-ui')['NGrid']
63-
NH3: typeof import('naive-ui')['NH3']
6458
NIcon: typeof import('naive-ui')['NIcon']
6559
NInput: typeof import('naive-ui')['NInput']
66-
NInputGroup: typeof import('naive-ui')['NInputGroup']
6760
NInputNumber: typeof import('naive-ui')['NInputNumber']
6861
NLayout: typeof import('naive-ui')['NLayout']
6962
NLayoutContent: typeof import('naive-ui')['NLayoutContent']
7063
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
71-
NLi: typeof import('naive-ui')['NLi']
7264
NList: typeof import('naive-ui')['NList']
7365
NListItem: typeof import('naive-ui')['NListItem']
7466
NLoadingBarProvider: typeof import('naive-ui')['NLoadingBarProvider']
7567
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
7668
NModal: typeof import('naive-ui')['NModal']
7769
NModalProvider: typeof import('naive-ui')['NModalProvider']
7870
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
79-
NOl: typeof import('naive-ui')['NOl']
8071
NotePad: typeof import('./src/components/notepad/NotePad.vue')['default']
8172
NPageHeader: typeof import('naive-ui')['NPageHeader']
8273
NPopover: typeof import('naive-ui')['NPopover']
@@ -88,17 +79,12 @@ declare module 'vue' {
8879
NSlider: typeof import('naive-ui')['NSlider']
8980
NSpace: typeof import('naive-ui')['NSpace']
9081
NSpin: typeof import('naive-ui')['NSpin']
91-
NStatistic: typeof import('naive-ui')['NStatistic']
92-
NStep: typeof import('naive-ui')['NStep']
93-
NSteps: typeof import('naive-ui')['NSteps']
9482
NSwitch: typeof import('naive-ui')['NSwitch']
9583
NTabPane: typeof import('naive-ui')['NTabPane']
9684
NTabs: typeof import('naive-ui')['NTabs']
9785
NTag: typeof import('naive-ui')['NTag']
9886
NText: typeof import('naive-ui')['NText']
9987
NTooltip: typeof import('naive-ui')['NTooltip']
100-
NUl: typeof import('naive-ui')['NUl']
101-
NVirtualList: typeof import('naive-ui')['NVirtualList']
10288
ProjectCreateDialog: typeof import('./src/components/project/ProjectCreateDialog.vue')['default']
10389
ProjectEditDialog: typeof import('./src/components/project/ProjectEditDialog.vue')['default']
10490
RecentProjects: typeof import('./src/components/project/RecentProjects.vue')['default']

ui/src/components/terminal/TerminalPanel.vue

Lines changed: 49 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@
275275
</n-tooltip>
276276
<template v-if="enabledQuickActions.length">
277277
<n-dropdown
278-
v-if="terminalQuickActionsCollapsed"
278+
v-if="stackedQuickActions.length"
279279
trigger="manual"
280280
:show="showQuickActionsMenu"
281281
:options="quickActionDropdownOptions"
@@ -290,36 +290,34 @@
290290
<PlayOutline />
291291
</n-icon>
292292
</template>
293-
</n-button>
294-
</template>
295-
{{ t('terminal.quickActions') }}
296-
</n-tooltip>
297-
</n-dropdown>
298-
<template v-else>
299-
<n-tooltip
300-
v-for="action in enabledQuickActions"
301-
:key="action.id"
302-
trigger="hover"
303-
placement="bottom"
304-
:delay="100"
305-
>
306-
<template #trigger>
307-
<n-button text size="small" @click="handleRunQuickAction(action)">
308-
<template #icon>
309-
<span
310-
v-if="getQuickActionSvg(action.icon)"
311-
class="terminal-quick-action-button-svg"
312-
v-html="getQuickActionSvg(action.icon)"
313-
></span>
314-
<n-icon v-else>
315-
<component :is="resolveQuickActionIcon(action.icon)" />
316-
</n-icon>
317-
</template>
318-
</n-button>
293+
</n-button>
294+
</template>
295+
{{ t('terminal.quickActions') }}
296+
</n-tooltip>
297+
</n-dropdown>
298+
<n-tooltip
299+
v-for="action in standaloneQuickActions"
300+
:key="action.id"
301+
trigger="hover"
302+
placement="bottom"
303+
:delay="100"
304+
>
305+
<template #trigger>
306+
<n-button text size="small" @click="handleRunQuickAction(action)">
307+
<template #icon>
308+
<span
309+
v-if="getQuickActionSvg(action.icon)"
310+
class="terminal-quick-action-button-svg"
311+
v-html="getQuickActionSvg(action.icon)"
312+
></span>
313+
<n-icon v-else>
314+
<component :is="resolveQuickActionIcon(action.icon)" />
315+
</n-icon>
319316
</template>
320-
{{ formatQuickActionLabel(action) }}
321-
</n-tooltip>
317+
</n-button>
322318
</template>
319+
{{ formatQuickActionLabel(action) }}
320+
</n-tooltip>
323321
</template>
324322
<n-tooltip v-if="projectIdRef" trigger="hover" placement="bottom" :delay="100">
325323
<template #trigger>
@@ -342,14 +340,9 @@
342340
>
343341
<template #trigger>
344342
<div class="panel-drag-handle" @mousedown="startPanelDrag">
345-
<div class="drag-dots">
346-
<div class="drag-dot"></div>
347-
<div class="drag-dot"></div>
348-
<div class="drag-dot"></div>
349-
<div class="drag-dot"></div>
350-
<div class="drag-dot"></div>
351-
<div class="drag-dot"></div>
352-
</div>
343+
<n-icon size="18">
344+
<MoveOutline />
345+
</n-icon>
353346
</div>
354347
</template>
355348
{{ t('terminal.dragPanel') }}
@@ -377,7 +370,7 @@
377370
<n-button text size="small" @click="toggleDockedMode">
378371
<template #icon>
379372
<n-icon>
380-
<component :is="isDocked ? MoveOutline : PinOutline" />
373+
<component :is="isDocked ? OpenOutline : AlbumsOutline" />
381374
</n-icon>
382375
</template>
383376
</n-button>
@@ -665,8 +658,9 @@ import {
665658
SparklesOutline,
666659
ContractOutline,
667660
ExpandOutline,
668-
PinOutline,
669661
MoveOutline,
662+
OpenOutline,
663+
AlbumsOutline,
670664
} from '@vicons/ionicons5';
671665
import TerminalViewport from './TerminalViewport.vue';
672666
import AISessionHistoryDialog from './AISessionHistoryDialog.vue';
@@ -1216,7 +1210,6 @@ const {
12161210
activeTheme,
12171211
currentPresetId,
12181212
terminalQuickActions,
1219-
terminalQuickActionsCollapsed,
12201213
} = storeToRefs(settingsStore);
12211214
12221215
// Tabs 主题覆盖 - 用于控制标签背景色
@@ -2450,9 +2443,23 @@ const enabledQuickActions = computed(() =>
24502443
terminalQuickActions.value.filter(action => action.enabled && action.command.trim())
24512444
);
24522445
2446+
const stackedQuickActions = computed(() =>
2447+
enabledQuickActions.value.filter(action => action.stacked)
2448+
);
2449+
2450+
const standaloneQuickActions = computed(() =>
2451+
enabledQuickActions.value.filter(action => !action.stacked)
2452+
);
2453+
24532454
const showQuickActionsMenu = ref(false);
24542455
const QUICK_ACTION_SETTINGS_KEY = '__settings__';
24552456
2457+
watch(stackedQuickActions, actions => {
2458+
if (actions.length === 0) {
2459+
showQuickActionsMenu.value = false;
2460+
}
2461+
});
2462+
24562463
function formatQuickActionLabel(action: TerminalQuickAction) {
24572464
const name = (action.name || '').trim() || action.id;
24582465
return `${name}: ${t('terminal.quickActionStart')}`;
@@ -2509,7 +2516,7 @@ function getQuickActionSvg(icon: TerminalQuickActionIcon): string {
25092516
}
25102517
25112518
const quickActionDropdownOptions = computed<DropdownOption[]>(() => [
2512-
...enabledQuickActions.value.map(action => ({
2519+
...stackedQuickActions.value.map(action => ({
25132520
label: formatQuickActionLabel(action),
25142521
key: action.id,
25152522
icon: () => {
@@ -2539,7 +2546,7 @@ function handleQuickActionSelect(key: string) {
25392546
void router.push({ name: 'settings' });
25402547
return;
25412548
}
2542-
const action = enabledQuickActions.value.find(item => item.id === key);
2549+
const action = stackedQuickActions.value.find(item => item.id === key);
25432550
if (!action) {
25442551
return;
25452552
}
@@ -3611,20 +3618,6 @@ defineExpose({
36113618
opacity: 1;
36123619
}
36133620
3614-
.drag-dots {
3615-
display: grid;
3616-
grid-template-columns: repeat(2, 4px);
3617-
grid-template-rows: repeat(3, 4px);
3618-
gap: 2px;
3619-
}
3620-
3621-
.drag-dot {
3622-
width: 3px;
3623-
height: 3px;
3624-
border-radius: 50%;
3625-
background-color: currentColor;
3626-
}
3627-
36283621
.panel-header {
36293622
display: flex;
36303623
justify-content: flex-start;

ui/src/components/workspace/WorkspaceTabView.vue

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,6 @@
2727
<span v-if="terminalCount > 0" class="terminal-badge">{{ terminalCount }}</span>
2828
</button>
2929
</div>
30-
<div class="tab-actions">
31-
<n-tooltip>
32-
<template #trigger>
33-
<n-button text size="small" @click="switchToFloating">
34-
<template #icon>
35-
<n-icon size="18">
36-
<OpenOutline />
37-
</n-icon>
38-
</template>
39-
</n-button>
40-
</template>
41-
{{ t('terminal.switchToFloating') }}
42-
</n-tooltip>
43-
</div>
4430
</div>
4531

4632
<!-- Tab内容 -->
@@ -63,8 +49,8 @@
6349
<script setup lang="ts">
6450
import { computed, onBeforeUnmount, watch } from 'vue';
6551
import { useEventListener, useStorage } from '@vueuse/core';
66-
import { NIcon, NButton, NTooltip } from 'naive-ui';
67-
import { GridOutline, TerminalOutline, OpenOutline } from '@vicons/ionicons5';
52+
import { NIcon } from 'naive-ui';
53+
import { GridOutline, TerminalOutline } from '@vicons/ionicons5';
6854
import { storeToRefs } from 'pinia';
6955
import { useLocale } from '@/composables/useLocale';
7056
import { useSettingsStore } from '@/stores/settings';
@@ -90,11 +76,6 @@ const terminalCount = computed(() => {
9076
return terminalStore.getTabs(props.projectId).length;
9177
});
9278
93-
// 切换到浮动模式
94-
function switchToFloating() {
95-
settingsStore.updateTerminalDisplayMode('floating');
96-
}
97-
9879
// 监听终端事件,如果有新终端创建或需要关注的事件,自动切换到终端Tab
9980
watch(
10081
() => terminalStore.getTabs(props.projectId),
@@ -183,8 +164,8 @@ if (typeof window !== 'undefined') {
183164
justify-content: space-between;
184165
padding: 0 12px;
185166
height: 40px;
186-
border-bottom: 1px solid var(--n-border-color);
187-
background-color: var(--n-card-color);
167+
border-bottom: 1px solid var(--n-border-color, var(--app-input-border-color, rgba(0, 0, 0, 0.12)));
168+
background-color: var(--app-surface-color, var(--n-card-color, #ffffff));
188169
flex-shrink: 0;
189170
}
190171
@@ -236,12 +217,6 @@ if (typeof window !== 'undefined') {
236217
font-weight: 500;
237218
}
238219
239-
.tab-actions {
240-
display: flex;
241-
align-items: center;
242-
gap: 4px;
243-
}
244-
245220
.tab-content {
246221
flex: 1;
247222
overflow: hidden;

ui/src/i18n/locales/en-US.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -569,9 +569,10 @@ export default {
569569
sendResizeOnSwitch: 'Send resize on terminal switch',
570570
sendResizeOnSwitchTip: 'Send resize command when switching to a terminal, helps retrieve more complete terminal history',
571571
terminalQuickActions: 'Terminal Quick Actions',
572-
terminalQuickActionsCollapsed: 'Single-button mode',
573-
terminalQuickActionsCollapsedTip: 'When enabled, show a single button in the terminal header and pick actions from the dropdown',
574572
terminalQuickActionsList: 'Actions',
573+
terminalQuickActionStackLabel: 'Stack into unified button',
574+
terminalQuickActionStackTip: 'Stack into unified quick button; unchecked actions stay outside',
575+
terminalQuickActionRemoveConfirm: 'Remove this quick action?',
575576
terminalQuickActionsTip: 'Clicking an action creates a new terminal on the current branch and runs the command',
576577
terminalQuickActionNamePlaceholder: 'Name',
577578
terminalQuickActionCommandPlaceholder: 'Command (e.g. codex)',

ui/src/i18n/locales/zh-CN.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -569,9 +569,10 @@ export default {
569569
sendResizeOnSwitch: '切换终端时发送 resize',
570570
sendResizeOnSwitchTip: '每次切换至终端时发送 resize 指令,可获取更完整的终端历史记录',
571571
terminalQuickActions: '终端快捷按钮',
572-
terminalQuickActionsCollapsed: '单按钮模式',
573-
terminalQuickActionsCollapsedTip: '开启后在终端标题栏只显示一个按钮,点击后从下拉列表选择要执行的命令',
574572
terminalQuickActionsList: '按钮列表',
573+
terminalQuickActionStackLabel: '叠入统一快捷按钮',
574+
terminalQuickActionStackTip: '叠入统一快捷按钮(选中后进入下拉,未选中则单独显示)',
575+
terminalQuickActionRemoveConfirm: '确认删除该快捷按钮吗?',
575576
terminalQuickActionsTip: '点击按钮会在当前终端分支创建新终端并运行对应命令',
576577
terminalQuickActionNamePlaceholder: '名称',
577578
terminalQuickActionCommandPlaceholder: '命令(例如:codex)',

0 commit comments

Comments
 (0)