Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,19 @@ export function TabContextMenu({
}: TabContextMenuProps) {
const hasMultiplePanes = paneCount > 1;

const handleRenameSelect = (event: Event) => {
// Prevent default to stop Radix from restoring focus to the trigger
event.preventDefault();
onRename();
};

const contextMenuContent = (
<ContextMenu>
<ContextMenuTrigger asChild>{children}</ContextMenuTrigger>
<ContextMenuContent className="w-48">
<ContextMenuItem onSelect={onRename}>Rename Tab</ContextMenuItem>
<ContextMenuItem onSelect={handleRenameSelect}>
Rename Tab
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem onSelect={onClose} className="text-destructive">
Close Tab
Expand All @@ -47,7 +55,9 @@ export function TabContextMenu({
<ContextMenuTrigger asChild>{children}</ContextMenuTrigger>
</TooltipTrigger>
<ContextMenuContent className="w-48">
<ContextMenuItem onSelect={onRename}>Rename Tab</ContextMenuItem>
<ContextMenuItem onSelect={handleRenameSelect}>
Rename Tab
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem onSelect={onClose} className="text-destructive">
Close Tab
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Button } from "@superset/ui/button";
import { Input } from "@superset/ui/input";
import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip";
import { useMemo, useRef, useState } from "react";
import { useEffect, useMemo, useRef, useState } from "react";
import { useDrag, useDrop } from "react-dnd";
import { HiMiniCommandLine, HiMiniXMark } from "react-icons/hi2";
import { trpc } from "renderer/lib/trpc";
Expand Down Expand Up @@ -86,12 +86,16 @@ export function TabItem({ tab, index, isActive }: TabItemProps) {
const startRename = () => {
setRenameValue(tab.userTitle ?? tab.name ?? displayName);
setIsRenaming(true);
setTimeout(() => {
inputRef.current?.focus();
inputRef.current?.select();
}, 0);
};

// Focus input when entering rename mode
useEffect(() => {
if (isRenaming && inputRef.current) {
inputRef.current.focus();
inputRef.current.select();
}
}, [isRenaming]);
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const submitRename = () => {
const trimmedValue = renameValue.trim();
const currentUserTitle = tab.userTitle?.trim() ?? "";
Expand All @@ -110,11 +114,52 @@ export function TabItem({ tab, index, isActive }: TabItemProps) {
}
};

const attachRef = (el: HTMLButtonElement | null) => {
const attachRef = (el: HTMLElement | null) => {
drag(el);
drop(el);
};

// When renaming, render outside TabContextMenu to avoid Radix focus interference
if (isRenaming) {
return (
<div className="w-full">
<div className="relative group">
<div
ref={attachRef}
className={`
w-full text-start px-3 py-2 rounded-md flex items-center gap-2 justify-between pr-8
${isActive ? "bg-tertiary-active" : ""}
${isDragging ? "opacity-50" : ""}
${isDragOver ? "bg-tertiary-active/50" : ""}
`}
>
<HiMiniCommandLine className="size-4" />
<div className="flex items-center gap-1 flex-1 min-w-0">
<Input
ref={inputRef}
variant="ghost"
value={renameValue}
onChange={(e) => setRenameValue(e.target.value)}
onBlur={submitRename}
onKeyDown={handleKeyDown}
onClick={(e) => e.stopPropagation()}
className="flex-1"
/>
</div>
</div>
<button
type="button"
tabIndex={-1}
onClick={handleRemoveTab}
className="absolute right-2 top-1/2 -translate-y-1/2 cursor-pointer opacity-0 group-hover:opacity-100 text-xs"
>
<HiMiniXMark className="size-4" />
</button>
</div>
</div>
);
}

return (
<div className="w-full">
<TabContextMenu
Expand All @@ -129,49 +174,32 @@ export function TabItem({ tab, index, isActive }: TabItemProps) {
onClick={handleTabClick}
onDoubleClick={startRename}
onKeyDown={(e) => {
if (!isRenaming && (e.key === "Enter" || e.key === " ")) {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
handleTabClick();
}
}}
tabIndex={0}
className={`
w-full text-start px-3 py-2 rounded-md cursor-pointer flex items-center justify-between pr-8
${isActive ? "bg-tertiary-active" : ""}
${isDragging ? "opacity-50" : ""}
${isDragOver ? "bg-tertiary-active/50" : ""}
`}
w-full text-start px-3 py-2 rounded-md cursor-pointer flex items-center justify-between pr-8
${isActive ? "bg-tertiary-active" : ""}
${isDragging ? "opacity-50" : ""}
${isDragOver ? "bg-tertiary-active/50" : ""}
`}
>
<HiMiniCommandLine className="size-4" />
<div className="flex items-center gap-1 flex-1 min-w-0">
{isRenaming ? (
<Input
ref={inputRef}
variant="ghost"
value={renameValue}
onChange={(e) => setRenameValue(e.target.value)}
onBlur={submitRename}
onKeyDown={handleKeyDown}
onClick={(e) => e.stopPropagation()}
className="flex-1"
/>
) : (
<>
<span className="truncate flex-1">{displayName}</span>
{needsAttention && (
<Tooltip>
<TooltipTrigger asChild>
<span className="relative flex size-2 shrink-0 ml-1">
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-red-400 opacity-75" />
<span className="relative inline-flex size-2 rounded-full bg-red-500" />
</span>
</TooltipTrigger>
<TooltipContent side="right">
Agent completed
</TooltipContent>
</Tooltip>
)}
</>
<span className="truncate flex-1">{displayName}</span>
{needsAttention && (
<Tooltip>
<TooltipTrigger asChild>
<span className="relative flex size-2 shrink-0 ml-1">
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-red-400 opacity-75" />
<span className="relative inline-flex size-2 rounded-full bg-red-500" />
</span>
</TooltipTrigger>
<TooltipContent side="right">Agent completed</TooltipContent>
</Tooltip>
)}
</div>
</Button>
Expand Down
Loading