mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-03 08:53:36 +00:00
feat(ui): add Open in Terminal action to worktree dropdown
Add "Open in Terminal" option to the worktree actions dropdown menu. This opens the system terminal in the worktree directory. Changes: - Add openInTerminal method to http-api-client - Add Terminal icon and menu item to worktree-actions-dropdown - Add onOpenInTerminal prop to WorktreeTab component - Add handleOpenInTerminal handler to use-worktree-actions hook - Wire up handler in worktree-panel for both mobile and desktop views Extracted from PR #558.
This commit is contained in:
@@ -26,6 +26,7 @@ import {
|
|||||||
RefreshCw,
|
RefreshCw,
|
||||||
Copy,
|
Copy,
|
||||||
ScrollText,
|
ScrollText,
|
||||||
|
Terminal,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
@@ -51,6 +52,7 @@ interface WorktreeActionsDropdownProps {
|
|||||||
onPull: (worktree: WorktreeInfo) => void;
|
onPull: (worktree: WorktreeInfo) => void;
|
||||||
onPush: (worktree: WorktreeInfo) => void;
|
onPush: (worktree: WorktreeInfo) => void;
|
||||||
onOpenInEditor: (worktree: WorktreeInfo, editorCommand?: string) => void;
|
onOpenInEditor: (worktree: WorktreeInfo, editorCommand?: string) => void;
|
||||||
|
onOpenInTerminal: (worktree: WorktreeInfo) => void;
|
||||||
onCommit: (worktree: WorktreeInfo) => void;
|
onCommit: (worktree: WorktreeInfo) => void;
|
||||||
onCreatePR: (worktree: WorktreeInfo) => void;
|
onCreatePR: (worktree: WorktreeInfo) => void;
|
||||||
onAddressPRComments: (worktree: WorktreeInfo, prInfo: PRInfo) => void;
|
onAddressPRComments: (worktree: WorktreeInfo, prInfo: PRInfo) => void;
|
||||||
@@ -81,6 +83,7 @@ export function WorktreeActionsDropdown({
|
|||||||
onPull,
|
onPull,
|
||||||
onPush,
|
onPush,
|
||||||
onOpenInEditor,
|
onOpenInEditor,
|
||||||
|
onOpenInTerminal,
|
||||||
onCommit,
|
onCommit,
|
||||||
onCreatePR,
|
onCreatePR,
|
||||||
onAddressPRComments,
|
onAddressPRComments,
|
||||||
@@ -303,6 +306,10 @@ export function WorktreeActionsDropdown({
|
|||||||
</DropdownMenuSubContent>
|
</DropdownMenuSubContent>
|
||||||
</DropdownMenuSub>
|
</DropdownMenuSub>
|
||||||
)}
|
)}
|
||||||
|
<DropdownMenuItem onClick={() => onOpenInTerminal(worktree)} className="text-xs">
|
||||||
|
<Terminal className="w-3.5 h-3.5 mr-2" />
|
||||||
|
Open in Terminal
|
||||||
|
</DropdownMenuItem>
|
||||||
{!worktree.isMain && hasInitScript && (
|
{!worktree.isMain && hasInitScript && (
|
||||||
<DropdownMenuItem onClick={() => onRunInitScript(worktree)} className="text-xs">
|
<DropdownMenuItem onClick={() => onRunInitScript(worktree)} className="text-xs">
|
||||||
<RefreshCw className="w-3.5 h-3.5 mr-2" />
|
<RefreshCw className="w-3.5 h-3.5 mr-2" />
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ interface WorktreeTabProps {
|
|||||||
onPull: (worktree: WorktreeInfo) => void;
|
onPull: (worktree: WorktreeInfo) => void;
|
||||||
onPush: (worktree: WorktreeInfo) => void;
|
onPush: (worktree: WorktreeInfo) => void;
|
||||||
onOpenInEditor: (worktree: WorktreeInfo, editorCommand?: string) => void;
|
onOpenInEditor: (worktree: WorktreeInfo, editorCommand?: string) => void;
|
||||||
|
onOpenInTerminal: (worktree: WorktreeInfo) => void;
|
||||||
onCommit: (worktree: WorktreeInfo) => void;
|
onCommit: (worktree: WorktreeInfo) => void;
|
||||||
onCreatePR: (worktree: WorktreeInfo) => void;
|
onCreatePR: (worktree: WorktreeInfo) => void;
|
||||||
onAddressPRComments: (worktree: WorktreeInfo, prInfo: PRInfo) => void;
|
onAddressPRComments: (worktree: WorktreeInfo, prInfo: PRInfo) => void;
|
||||||
@@ -82,6 +83,7 @@ export function WorktreeTab({
|
|||||||
onPull,
|
onPull,
|
||||||
onPush,
|
onPush,
|
||||||
onOpenInEditor,
|
onOpenInEditor,
|
||||||
|
onOpenInTerminal,
|
||||||
onCommit,
|
onCommit,
|
||||||
onCreatePR,
|
onCreatePR,
|
||||||
onAddressPRComments,
|
onAddressPRComments,
|
||||||
@@ -343,6 +345,7 @@ export function WorktreeTab({
|
|||||||
onPull={onPull}
|
onPull={onPull}
|
||||||
onPush={onPush}
|
onPush={onPush}
|
||||||
onOpenInEditor={onOpenInEditor}
|
onOpenInEditor={onOpenInEditor}
|
||||||
|
onOpenInTerminal={onOpenInTerminal}
|
||||||
onCommit={onCommit}
|
onCommit={onCommit}
|
||||||
onCreatePR={onCreatePR}
|
onCreatePR={onCreatePR}
|
||||||
onAddressPRComments={onAddressPRComments}
|
onAddressPRComments={onAddressPRComments}
|
||||||
|
|||||||
@@ -143,6 +143,24 @@ export function useWorktreeActions({ fetchWorktrees, fetchBranches }: UseWorktre
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleOpenInTerminal = useCallback(async (worktree: WorktreeInfo) => {
|
||||||
|
try {
|
||||||
|
const api = getElectronAPI();
|
||||||
|
if (!api?.worktree?.openInTerminal) {
|
||||||
|
logger.warn('Open in terminal API not available');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const result = await api.worktree.openInTerminal(worktree.path);
|
||||||
|
if (result.success && result.result) {
|
||||||
|
toast.success(result.result.message);
|
||||||
|
} else if (result.error) {
|
||||||
|
toast.error(result.error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Open in terminal failed:', error);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isPulling,
|
isPulling,
|
||||||
isPushing,
|
isPushing,
|
||||||
@@ -153,5 +171,6 @@ export function useWorktreeActions({ fetchWorktrees, fetchBranches }: UseWorktre
|
|||||||
handlePull,
|
handlePull,
|
||||||
handlePush,
|
handlePush,
|
||||||
handleOpenInEditor,
|
handleOpenInEditor,
|
||||||
|
handleOpenInTerminal,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ export function WorktreePanel({
|
|||||||
handlePull,
|
handlePull,
|
||||||
handlePush,
|
handlePush,
|
||||||
handleOpenInEditor,
|
handleOpenInEditor,
|
||||||
|
handleOpenInTerminal,
|
||||||
} = useWorktreeActions({
|
} = useWorktreeActions({
|
||||||
fetchWorktrees,
|
fetchWorktrees,
|
||||||
fetchBranches,
|
fetchBranches,
|
||||||
@@ -246,6 +247,7 @@ export function WorktreePanel({
|
|||||||
onPull={handlePull}
|
onPull={handlePull}
|
||||||
onPush={handlePush}
|
onPush={handlePush}
|
||||||
onOpenInEditor={handleOpenInEditor}
|
onOpenInEditor={handleOpenInEditor}
|
||||||
|
onOpenInTerminal={handleOpenInTerminal}
|
||||||
onCommit={onCommit}
|
onCommit={onCommit}
|
||||||
onCreatePR={onCreatePR}
|
onCreatePR={onCreatePR}
|
||||||
onAddressPRComments={onAddressPRComments}
|
onAddressPRComments={onAddressPRComments}
|
||||||
@@ -333,6 +335,7 @@ export function WorktreePanel({
|
|||||||
onPull={handlePull}
|
onPull={handlePull}
|
||||||
onPush={handlePush}
|
onPush={handlePush}
|
||||||
onOpenInEditor={handleOpenInEditor}
|
onOpenInEditor={handleOpenInEditor}
|
||||||
|
onOpenInTerminal={handleOpenInTerminal}
|
||||||
onCommit={onCommit}
|
onCommit={onCommit}
|
||||||
onCreatePR={onCreatePR}
|
onCreatePR={onCreatePR}
|
||||||
onAddressPRComments={onAddressPRComments}
|
onAddressPRComments={onAddressPRComments}
|
||||||
@@ -391,6 +394,7 @@ export function WorktreePanel({
|
|||||||
onPull={handlePull}
|
onPull={handlePull}
|
||||||
onPush={handlePush}
|
onPush={handlePush}
|
||||||
onOpenInEditor={handleOpenInEditor}
|
onOpenInEditor={handleOpenInEditor}
|
||||||
|
onOpenInTerminal={handleOpenInTerminal}
|
||||||
onCommit={onCommit}
|
onCommit={onCommit}
|
||||||
onCreatePR={onCreatePR}
|
onCreatePR={onCreatePR}
|
||||||
onAddressPRComments={onAddressPRComments}
|
onAddressPRComments={onAddressPRComments}
|
||||||
|
|||||||
@@ -1805,6 +1805,8 @@ export class HttpApiClient implements ElectronAPI {
|
|||||||
this.post('/api/worktree/switch-branch', { worktreePath, branchName }),
|
this.post('/api/worktree/switch-branch', { worktreePath, branchName }),
|
||||||
openInEditor: (worktreePath: string, editorCommand?: string) =>
|
openInEditor: (worktreePath: string, editorCommand?: string) =>
|
||||||
this.post('/api/worktree/open-in-editor', { worktreePath, editorCommand }),
|
this.post('/api/worktree/open-in-editor', { worktreePath, editorCommand }),
|
||||||
|
openInTerminal: (worktreePath: string) =>
|
||||||
|
this.post('/api/worktree/open-in-terminal', { worktreePath }),
|
||||||
getDefaultEditor: () => this.get('/api/worktree/default-editor'),
|
getDefaultEditor: () => this.get('/api/worktree/default-editor'),
|
||||||
getAvailableEditors: () => this.get('/api/worktree/available-editors'),
|
getAvailableEditors: () => this.get('/api/worktree/available-editors'),
|
||||||
refreshEditors: () => this.post('/api/worktree/refresh-editors', {}),
|
refreshEditors: () => this.post('/api/worktree/refresh-editors', {}),
|
||||||
|
|||||||
Reference in New Issue
Block a user