Compare commits

...

1 Commits

Author SHA1 Message Date
Jiang Bohan
c4f183a797 feat(modals): add expand button to agent create dialog
Mirrors the manual create panel's expand affordance so the agent panel
can grow to the same wider footprint when the user wants more room for
a long prompt or pasted screenshots. Expand state is shared across
modes via the shell, so the user's preference persists when toggling
between agent and manual.

Co-authored-by: multica-agent <github@multica.ai>
2026-05-09 15:31:54 +08:00
3 changed files with 41 additions and 17 deletions

View File

@@ -57,13 +57,17 @@ export function CreateIssueDialog({
? cn(
"p-0 gap-0 flex flex-col overflow-hidden",
"!top-1/2 !left-1/2 !-translate-x-1/2 !-translate-y-1/2",
// Width is capped; height is content-driven up to 80vh so a
// pasted screenshot can't push the dialog past the viewport
// (the inner editor area scrolls instead).
"!max-w-xl !w-full !max-h-[80vh]",
// Smooth size transition when switching modes — the manual mode
// uses the same easing.
"!transition-all !duration-300 !ease-out",
// Expanded matches manual's expanded footprint so toggling expand
// mid-flow (or after a mode switch) lands the user on the same
// visual size. Collapsed keeps the slim, content-driven default
// — pasted screenshots still scroll inside instead of pushing the
// dialog past the viewport.
isExpanded
? "!max-w-4xl !w-full !h-5/6"
: "!max-w-xl !w-full !max-h-[80vh]",
)
: manualDialogContentClass(isExpanded, backlogHintIssueId);
@@ -79,6 +83,8 @@ export function CreateIssueDialog({
onClose={onClose}
onSwitchMode={switchTo("manual")}
data={panelData}
isExpanded={isExpanded}
setIsExpanded={setIsExpanded}
/>
) : (
<ManualCreatePanel

View File

@@ -220,7 +220,7 @@ describe("AgentCreatePanel", () => {
});
it("loads the persisted prompt draft when no transient prompt is provided", () => {
renderPanel({ onClose: vi.fn() });
renderPanel({ onClose: vi.fn(), isExpanded: false, setIsExpanded: vi.fn() });
expect(
screen.getByPlaceholderText(
@@ -233,7 +233,7 @@ describe("AgentCreatePanel", () => {
const user = userEvent.setup();
const onClose = vi.fn();
renderPanel({ onClose });
renderPanel({ onClose, isExpanded: false, setIsExpanded: vi.fn() });
const editor = screen.getByPlaceholderText(
'Tell the agent what to do, e.g. "let Bohan fix the inbox loading slowness in the Web project"',

View File

@@ -1,7 +1,7 @@
"use client";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { ArrowLeftRight, Check, ChevronRight, X as XIcon } from "lucide-react";
import { ArrowLeftRight, Check, ChevronRight, Maximize2, Minimize2, X as XIcon } from "lucide-react";
import { useQuery } from "@tanstack/react-query";
import { toast } from "sonner";
import { DialogTitle } from "@multica/ui/components/ui/dialog";
@@ -55,10 +55,17 @@ export function AgentCreatePanel({
onClose,
onSwitchMode,
data,
isExpanded,
setIsExpanded,
}: {
onClose: () => void;
onSwitchMode?: () => void;
data?: Record<string, unknown> | null;
/** Lifted to the shell so DialogContent's mode-aware className can react —
* same pattern as ManualCreatePanel. Shared across modes so the user's
* expand preference persists when switching between agent and manual. */
isExpanded: boolean;
setIsExpanded: (v: boolean) => void;
}) {
const { t } = useT("modals");
const workspaceName = useCurrentWorkspace()?.name;
@@ -263,16 +270,27 @@ export function AgentCreatePanel({
{/* Native `title` instead of Base UI Tooltip — Tooltip opens on
keyboard focus, and the dialog's focus trap briefly lands focus
on the first focusable element on mount, causing the tooltip to
auto-pop every open. */}
<button
type="button"
onClick={onClose}
title={t(($) => $.common.close)}
aria-label={t(($) => $.common.close)}
className="rounded-sm p-1.5 opacity-70 hover:opacity-100 hover:bg-accent/60 transition-all cursor-pointer"
>
<XIcon className="size-4" />
</button>
auto-pop every open. Same workaround applies to expand. */}
<div className="flex items-center gap-1">
<button
type="button"
onClick={() => setIsExpanded(!isExpanded)}
title={isExpanded ? t(($) => $.common.collapse_tooltip) : t(($) => $.common.expand_tooltip)}
aria-label={isExpanded ? t(($) => $.common.collapse_tooltip) : t(($) => $.common.expand_tooltip)}
className="rounded-sm p-1.5 opacity-70 hover:opacity-100 hover:bg-accent/60 transition-all cursor-pointer"
>
{isExpanded ? <Minimize2 className="size-4" /> : <Maximize2 className="size-4" />}
</button>
<button
type="button"
onClick={onClose}
title={t(($) => $.common.close)}
aria-label={t(($) => $.common.close)}
className="rounded-sm p-1.5 opacity-70 hover:opacity-100 hover:bg-accent/60 transition-all cursor-pointer"
>
<XIcon className="size-4" />
</button>
</div>
</div>
{/* Agent picker */}