|
275 | 275 | </n-tooltip> |
276 | 276 | <template v-if="enabledQuickActions.length"> |
277 | 277 | <n-dropdown |
278 | | - v-if="terminalQuickActionsCollapsed" |
| 278 | + v-if="stackedQuickActions.length" |
279 | 279 | trigger="manual" |
280 | 280 | :show="showQuickActionsMenu" |
281 | 281 | :options="quickActionDropdownOptions" |
|
290 | 290 | <PlayOutline /> |
291 | 291 | </n-icon> |
292 | 292 | </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> |
319 | 316 | </template> |
320 | | - {{ formatQuickActionLabel(action) }} |
321 | | - </n-tooltip> |
| 317 | + </n-button> |
322 | 318 | </template> |
| 319 | + {{ formatQuickActionLabel(action) }} |
| 320 | + </n-tooltip> |
323 | 321 | </template> |
324 | 322 | <n-tooltip v-if="projectIdRef" trigger="hover" placement="bottom" :delay="100"> |
325 | 323 | <template #trigger> |
|
342 | 340 | > |
343 | 341 | <template #trigger> |
344 | 342 | <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> |
353 | 346 | </div> |
354 | 347 | </template> |
355 | 348 | {{ t('terminal.dragPanel') }} |
|
377 | 370 | <n-button text size="small" @click="toggleDockedMode"> |
378 | 371 | <template #icon> |
379 | 372 | <n-icon> |
380 | | - <component :is="isDocked ? MoveOutline : PinOutline" /> |
| 373 | + <component :is="isDocked ? OpenOutline : AlbumsOutline" /> |
381 | 374 | </n-icon> |
382 | 375 | </template> |
383 | 376 | </n-button> |
@@ -665,8 +658,9 @@ import { |
665 | 658 | SparklesOutline, |
666 | 659 | ContractOutline, |
667 | 660 | ExpandOutline, |
668 | | - PinOutline, |
669 | 661 | MoveOutline, |
| 662 | + OpenOutline, |
| 663 | + AlbumsOutline, |
670 | 664 | } from '@vicons/ionicons5'; |
671 | 665 | import TerminalViewport from './TerminalViewport.vue'; |
672 | 666 | import AISessionHistoryDialog from './AISessionHistoryDialog.vue'; |
@@ -1216,7 +1210,6 @@ const { |
1216 | 1210 | activeTheme, |
1217 | 1211 | currentPresetId, |
1218 | 1212 | terminalQuickActions, |
1219 | | - terminalQuickActionsCollapsed, |
1220 | 1213 | } = storeToRefs(settingsStore); |
1221 | 1214 |
|
1222 | 1215 | // Tabs 主题覆盖 - 用于控制标签背景色 |
@@ -2450,9 +2443,23 @@ const enabledQuickActions = computed(() => |
2450 | 2443 | terminalQuickActions.value.filter(action => action.enabled && action.command.trim()) |
2451 | 2444 | ); |
2452 | 2445 |
|
| 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 | +
|
2453 | 2454 | const showQuickActionsMenu = ref(false); |
2454 | 2455 | const QUICK_ACTION_SETTINGS_KEY = '__settings__'; |
2455 | 2456 |
|
| 2457 | +watch(stackedQuickActions, actions => { |
| 2458 | + if (actions.length === 0) { |
| 2459 | + showQuickActionsMenu.value = false; |
| 2460 | + } |
| 2461 | +}); |
| 2462 | +
|
2456 | 2463 | function formatQuickActionLabel(action: TerminalQuickAction) { |
2457 | 2464 | const name = (action.name || '').trim() || action.id; |
2458 | 2465 | return `${name}: ${t('terminal.quickActionStart')}`; |
@@ -2509,7 +2516,7 @@ function getQuickActionSvg(icon: TerminalQuickActionIcon): string { |
2509 | 2516 | } |
2510 | 2517 |
|
2511 | 2518 | const quickActionDropdownOptions = computed<DropdownOption[]>(() => [ |
2512 | | - ...enabledQuickActions.value.map(action => ({ |
| 2519 | + ...stackedQuickActions.value.map(action => ({ |
2513 | 2520 | label: formatQuickActionLabel(action), |
2514 | 2521 | key: action.id, |
2515 | 2522 | icon: () => { |
@@ -2539,7 +2546,7 @@ function handleQuickActionSelect(key: string) { |
2539 | 2546 | void router.push({ name: 'settings' }); |
2540 | 2547 | return; |
2541 | 2548 | } |
2542 | | - const action = enabledQuickActions.value.find(item => item.id === key); |
| 2549 | + const action = stackedQuickActions.value.find(item => item.id === key); |
2543 | 2550 | if (!action) { |
2544 | 2551 | return; |
2545 | 2552 | } |
@@ -3611,20 +3618,6 @@ defineExpose({ |
3611 | 3618 | opacity: 1; |
3612 | 3619 | } |
3613 | 3620 |
|
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 | | -
|
3628 | 3621 | .panel-header { |
3629 | 3622 | display: flex; |
3630 | 3623 | justify-content: flex-start; |
|
0 commit comments