Adds a text-selection comment flow that opens New Task with source context. - Add a reusable selection comment hook and popover for editor/document text selections. - Thread selected-file and line-range context into the New Task modal. - Enable comment-on-selection entry points in file editor, browser, documents, and memory surfaces. - Cover the selection flow with focused component and hook tests, plus docs and copy updates. Files changed: docs/dashboard-guide.md | 6 +- packages/dashboard/app/App.tsx | 7 +- packages/dashboard/app/components/AppModals.tsx | 2 + .../dashboard/app/components/DocumentsView.tsx | 25 ++- .../dashboard/app/components/FileBrowserModal.tsx | 3 + packages/dashboard/app/components/FileEditor.tsx | 35 +++- packages/dashboard/app/components/MemoryView.tsx | 5 +- packages/dashboard/app/components/NewTaskModal.tsx | 15 +- .../app/components/SelectionCommentPopover.css | 73 +++++++++ .../app/components/SelectionCommentPopover.tsx | 181 +++++++++++++++++++++ .../components/__tests__/DocumentsView.test.tsx | 59 +++++++ .../components/__tests__/FileBrowserModal.test.tsx | 79 +++++++++ .../app/components/__tests__/FileEditor.test.tsx | 60 +++++++ .../app/components/__tests__/MemoryView.test.tsx | 48 +++++- .../app/components/__tests__/NewTaskModal.test.tsx | 17 ++ .../__tests__/SelectionCommentPopover.test.tsx | 75 +++++++++ .../app/hooks/__tests__/useModalManager.test.ts | 29 ++++ .../hooks/__tests__/useSelectionComment.test.ts | 140 ++++++++++++++++ packages/dashboard/app/hooks/useModalManager.ts | 19 ++- .../dashboard/app/hooks/useSelectionComment.ts | 95 +++++++++++ packages/i18n/locales/en/app.json | 11 ++ 21 files changed, 973 insertions(+), 11 deletions(-) Fusion-Task-Id: FN-6528 Fusion-Task-Lineage: ef79e450-e69f-497b-97cd-f82d3c832fdf
76 lines
2.5 KiB
TypeScript
76 lines
2.5 KiB
TypeScript
import { fireEvent, render, screen } from "@testing-library/react";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import { SelectionCommentPopover, composeSelectionCommentDescription } from "../SelectionCommentPopover";
|
|
|
|
vi.mock("lucide-react", () => ({
|
|
MessageSquarePlus: () => null,
|
|
}));
|
|
|
|
describe("SelectionCommentPopover", () => {
|
|
it("renders a trigger for a selection and submits a composed task description", () => {
|
|
const onSubmit = vi.fn();
|
|
render(
|
|
<SelectionCommentPopover
|
|
selectedText="const answer = 42;"
|
|
anchorRect={new DOMRect(20, 30, 100, 16)}
|
|
filePath="src/example.ts"
|
|
lineRange={{ start: 4, end: 4 }}
|
|
onSubmit={onSubmit}
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: /add a comment/i }));
|
|
fireEvent.change(screen.getByLabelText(/comment for the new task/i), {
|
|
target: { value: "Turn this into a configurable value." },
|
|
});
|
|
fireEvent.click(screen.getByRole("button", { name: /send to new task/i }));
|
|
|
|
expect(onSubmit).toHaveBeenCalledWith([
|
|
"File: src/example.ts",
|
|
"Lines: 4",
|
|
"",
|
|
"Selected snippet:",
|
|
"```text",
|
|
"const answer = 42;",
|
|
"```",
|
|
"",
|
|
"Comment:",
|
|
"Turn this into a configurable value.",
|
|
].join("\n"));
|
|
});
|
|
|
|
it("cancels cleanly without submitting", () => {
|
|
const onSubmit = vi.fn();
|
|
const onCancel = vi.fn();
|
|
const onOpenChange = vi.fn();
|
|
render(
|
|
<SelectionCommentPopover
|
|
selectedText="snippet"
|
|
anchorRect={new DOMRect(20, 30, 100, 16)}
|
|
filePath="README.md"
|
|
onSubmit={onSubmit}
|
|
onCancel={onCancel}
|
|
onOpenChange={onOpenChange}
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: /add a comment/i }));
|
|
fireEvent.change(screen.getByLabelText(/comment for the new task/i), { target: { value: "A note" } });
|
|
fireEvent.click(screen.getByRole("button", { name: /cancel/i }));
|
|
|
|
expect(onSubmit).not.toHaveBeenCalled();
|
|
expect(onCancel).toHaveBeenCalledTimes(1);
|
|
expect(onOpenChange).toHaveBeenCalledWith(true);
|
|
expect(onOpenChange).toHaveBeenLastCalledWith(false);
|
|
expect(screen.getByRole("button", { name: /add a comment/i })).toBeInTheDocument();
|
|
});
|
|
|
|
it("uses a longer markdown fence when the snippet contains backticks", () => {
|
|
expect(composeSelectionCommentDescription({
|
|
filePath: "README.md",
|
|
selectedText: "```js\ncode\n```",
|
|
comment: "Move this example.",
|
|
})).toContain("````text\n```js\ncode\n```\n````");
|
|
});
|
|
});
|