mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-15 00:29:52 +03:00
fix(webui): allow moving active group panes
This commit is contained in:
@@ -865,7 +865,12 @@ export const ChatList = memo(function ChatList({
|
|||||||
: updated.has(s.chatId) && !topicActive
|
: updated.has(s.chatId) && !topicActive
|
||||||
? "updated"
|
? "updated"
|
||||||
: null;
|
: null;
|
||||||
const canDragSession = !topicActive && !deleteSelectionMode;
|
const hasPaneMoveTarget = Boolean(onAttachPane)
|
||||||
|
&& paneGroupTargets.some((target) => (
|
||||||
|
target.key !== paneGroup?.tabKey && !target.atCapacity
|
||||||
|
));
|
||||||
|
const canDragSession = !deleteSelectionMode
|
||||||
|
&& (!topicActive || hasPaneMoveTarget);
|
||||||
const actionMenuId = `session:${s.key}`;
|
const actionMenuId = `session:${s.key}`;
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
@@ -1332,7 +1337,10 @@ function ActivePaneRows({
|
|||||||
const selected = selectedDeleteKeys.has(pane.key);
|
const selected = selectedDeleteKeys.has(pane.key);
|
||||||
const isPinned = pinned.has(pane.key);
|
const isPinned = pinned.has(pane.key);
|
||||||
const isArchived = archived.has(pane.key);
|
const isArchived = archived.has(pane.key);
|
||||||
const canDragSession = !active && !deleteSelectionMode;
|
const hasPaneMoveTarget = Boolean(onAttachPane)
|
||||||
|
&& moveTargets.some((target) => !target.atCapacity);
|
||||||
|
const canDragSession = !deleteSelectionMode
|
||||||
|
&& (!active || Boolean(onDetachPane) || hasPaneMoveTarget);
|
||||||
const actionMenuId = `pane:${pane.key}`;
|
const actionMenuId = `pane:${pane.key}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ describe("ChatList", () => {
|
|||||||
|
|
||||||
expect(screen.getByRole("button", { name: "Group: Root topic" }))
|
expect(screen.getByRole("button", { name: "Group: Root topic" }))
|
||||||
.toHaveAttribute("draggable", "false");
|
.toHaveAttribute("draggable", "false");
|
||||||
|
expect(screen.getByRole("button", { name: "Root topic" }))
|
||||||
|
.toHaveAttribute("draggable", "false");
|
||||||
const pane = screen.getByRole("button", { name: "Research pane" });
|
const pane = screen.getByRole("button", { name: "Research pane" });
|
||||||
expect(pane).toHaveAttribute("draggable", "true");
|
expect(pane).toHaveAttribute("draggable", "true");
|
||||||
const dataTransfer = {
|
const dataTransfer = {
|
||||||
@@ -145,7 +147,7 @@ describe("ChatList", () => {
|
|||||||
fireEvent.click(await screen.findByRole("menuitem", { name: "Rename" }));
|
fireEvent.click(await screen.findByRole("menuitem", { name: "Rename" }));
|
||||||
expect(onRequestRename).toHaveBeenCalledWith("websocket:child", "Research pane");
|
expect(onRequestRename).toHaveBeenCalledWith("websocket:child", "Research pane");
|
||||||
|
|
||||||
const tabRow = screen.getByRole("button", { name: "Tab: Root topic" })
|
const tabRow = screen.getByRole("button", { name: "Group: Root topic" })
|
||||||
.closest("[data-workbench-tab]")!;
|
.closest("[data-workbench-tab]")!;
|
||||||
fireEvent.contextMenu(tabRow);
|
fireEvent.contextMenu(tabRow);
|
||||||
fireEvent.click(await screen.findByRole("menuitem", { name: "Dissolve group" }));
|
fireEvent.click(await screen.findByRole("menuitem", { name: "Dissolve group" }));
|
||||||
@@ -247,7 +249,7 @@ describe("ChatList", () => {
|
|||||||
session({ chatId: "target", title: "Target group" }),
|
session({ chatId: "target", title: "Target group" }),
|
||||||
session({ chatId: "full", title: "Full group" }),
|
session({ chatId: "full", title: "Full group" }),
|
||||||
]}
|
]}
|
||||||
activeKey="websocket:target"
|
activeKey="websocket:solo"
|
||||||
paneGroups={{
|
paneGroups={{
|
||||||
"websocket:solo": {
|
"websocket:solo": {
|
||||||
tabKey: "tab:solo",
|
tabKey: "tab:solo",
|
||||||
@@ -293,6 +295,7 @@ describe("ChatList", () => {
|
|||||||
types: [SESSION_DRAG_TYPE],
|
types: [SESSION_DRAG_TYPE],
|
||||||
} as unknown as DataTransfer;
|
} as unknown as DataTransfer;
|
||||||
const source = screen.getByRole("button", { name: "Solo topic" });
|
const source = screen.getByRole("button", { name: "Solo topic" });
|
||||||
|
expect(source).toHaveAttribute("draggable", "true");
|
||||||
const targetGroup = screen.getByRole("button", { name: "Group: Target group" })
|
const targetGroup = screen.getByRole("button", { name: "Group: Target group" })
|
||||||
.closest("[data-sidebar-tab-group]")!;
|
.closest("[data-sidebar-tab-group]")!;
|
||||||
const targetSurface = targetGroup.querySelector("[data-workbench-tab-surface]")!;
|
const targetSurface = targetGroup.querySelector("[data-workbench-tab-surface]")!;
|
||||||
@@ -334,7 +337,7 @@ describe("ChatList", () => {
|
|||||||
"websocket:root": {
|
"websocket:root": {
|
||||||
tabKey: "tab:root",
|
tabKey: "tab:root",
|
||||||
title: "Root group",
|
title: "Root group",
|
||||||
activePaneKey: "websocket:root",
|
activePaneKey: "websocket:child",
|
||||||
visible: true,
|
visible: true,
|
||||||
panes: [
|
panes: [
|
||||||
{ key: "websocket:root", chatId: "root", title: "Root topic" },
|
{ key: "websocket:root", chatId: "root", title: "Root topic" },
|
||||||
@@ -367,6 +370,8 @@ describe("ChatList", () => {
|
|||||||
types: [SESSION_DRAG_TYPE],
|
types: [SESSION_DRAG_TYPE],
|
||||||
} as unknown as DataTransfer;
|
} as unknown as DataTransfer;
|
||||||
const source = screen.getByRole("button", { name: "Research pane" });
|
const source = screen.getByRole("button", { name: "Research pane" });
|
||||||
|
expect(source).toHaveAttribute("aria-current", "true");
|
||||||
|
expect(source).toHaveAttribute("draggable", "true");
|
||||||
const sourceSurface = screen.getByRole("button", { name: "Group: Root topic" })
|
const sourceSurface = screen.getByRole("button", { name: "Group: Root topic" })
|
||||||
.closest("[data-workbench-tab-surface]")!;
|
.closest("[data-workbench-tab-surface]")!;
|
||||||
const standaloneList = document.querySelector("[data-chat-list-content]")!;
|
const standaloneList = document.querySelector("[data-chat-list-content]")!;
|
||||||
@@ -509,7 +514,7 @@ describe("ChatList", () => {
|
|||||||
.toBeInTheDocument();
|
.toBeInTheDocument();
|
||||||
fireEvent.keyDown(document, { key: "Escape" });
|
fireEvent.keyDown(document, { key: "Escape" });
|
||||||
|
|
||||||
expect(child).toHaveAttribute("draggable", "false");
|
expect(child).toHaveAttribute("draggable", "true");
|
||||||
expect(screen.getByRole("button", { name: "Group: Target tab" }))
|
expect(screen.getByRole("button", { name: "Group: Target tab" }))
|
||||||
.toHaveAttribute("draggable", "false");
|
.toHaveAttribute("draggable", "false");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1807,7 +1807,7 @@ describe("ThreadComposer", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("rejects session drops that are unavailable to the composer", () => {
|
it("rejects self-session drops that are unavailable to the composer", () => {
|
||||||
render(
|
render(
|
||||||
<ThreadComposer
|
<ThreadComposer
|
||||||
onSend={vi.fn()}
|
onSend={vi.fn()}
|
||||||
|
|||||||
Reference in New Issue
Block a user