Files
kandev/apps/web/components/task/editors-menu.tsx
T
Carlos Florêncio 3a95a43990 fix: vscode (#279)
2026-02-24 23:01:41 +00:00

104 lines
3.4 KiB
TypeScript

"use client";
import { useMemo } from "react";
import { IconChevronDown, IconCode, IconLoader2 } from "@tabler/icons-react";
import { Button } from "@kandev/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@kandev/ui/dropdown-menu";
import { Tooltip, TooltipContent, TooltipTrigger } from "@kandev/ui/tooltip";
import { useEditors } from "@/hooks/domains/settings/use-editors";
import { useOpenSessionInEditor } from "@/hooks/use-open-session-in-editor";
import { useAppStore } from "@/components/state-provider";
import type { EditorOption } from "@/lib/types/http";
type EditorsMenuProps = {
activeSessionId: string | null;
};
export function EditorsMenu({ activeSessionId }: EditorsMenuProps) {
const openEditor = useOpenSessionInEditor(activeSessionId ?? null);
const { editors } = useEditors();
const defaultEditorId = useAppStore((state) => state.userSettings.defaultEditorId);
const enabledEditors = useMemo(
() =>
editors.filter((editor: EditorOption) => {
if (!editor.enabled) return false;
if (editor.kind === "built_in") return editor.installed;
return true;
}),
[editors],
);
const resolvedEditorId = useMemo(() => {
if (
defaultEditorId &&
enabledEditors.some((editor: EditorOption) => editor.id === defaultEditorId)
) {
return defaultEditorId;
}
return enabledEditors[0]?.id ?? "";
}, [defaultEditorId, enabledEditors]);
return (
<div className="inline-flex rounded-md border border-border overflow-hidden">
<Tooltip>
<TooltipTrigger asChild>
<Button
size="sm"
variant="outline"
className="rounded-none border-0 cursor-pointer px-2"
onClick={() => {
if (!resolvedEditorId) return;
void openEditor.open({ editorId: resolvedEditorId });
}}
disabled={!activeSessionId || openEditor.isLoading || enabledEditors.length === 0}
>
{openEditor.isLoading ? (
<IconLoader2 className="h-4 w-4 animate-spin" />
) : (
<IconCode className="h-4 w-4" />
)}
</Button>
</TooltipTrigger>
<TooltipContent>
{activeSessionId ? "Open editor" : "Select a session to open its worktree"}
</TooltipContent>
</Tooltip>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="sm"
variant="outline"
className="rounded-none border-0 border-l px-2 cursor-pointer"
disabled={!activeSessionId || enabledEditors.length === 0}
>
<IconChevronDown className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{enabledEditors.length === 0 ? (
<DropdownMenuItem disabled>No editors available</DropdownMenuItem>
) : (
enabledEditors.map((editor: EditorOption) => (
<DropdownMenuItem
key={editor.id}
className="cursor-pointer"
onClick={() => {
void openEditor.open({ editorId: editor.id });
}}
>
{editor.name}
</DropdownMenuItem>
))
)}
</DropdownMenuContent>
</DropdownMenu>
</div>
);
}