feat(FN-1665): merge fusion/fn-1665

This commit is contained in:
gsxdsm
2026-04-13 19:43:25 -07:00
parent 274f8bd8a4
commit 42c25a0fab
3 changed files with 65 additions and 13 deletions

View File

@@ -575,18 +575,23 @@ export function TaskForm({
rows={mode === "edit" ? 8 : 5}
disabled={disabled || isRefining}
/>
{!disabled && !isDescriptionExpanded && (
<button
type="button"
className="btn btn-sm description-expand-btn"
onClick={handleToggleDescriptionExpand}
aria-label="Expand description"
title="Expand description"
>
<Maximize2 size={14} />
</button>
)}
{description.trim() && !disabled && (
{/* Determine if refine button will be shown — controls expand button placement */}
{(() => {
const showRefineButton = Boolean(description.trim()) && !disabled;
return (
<>
{!isDescriptionExpanded && (
<button
type="button"
className={`btn btn-sm description-expand-btn${showRefineButton ? " description-expand-btn--offset" : " description-expand-btn--flush"}`}
onClick={handleToggleDescriptionExpand}
aria-label="Expand description"
title="Expand description"
>
<Maximize2 size={14} />
</button>
)}
{showRefineButton && (
<button
type="button"
className={`btn btn-sm refine-button ${isRefining ? "refine-button--loading" : ""}`}
@@ -598,7 +603,10 @@ export function TaskForm({
<Sparkles size={12} style={{ verticalAlign: "middle" }} />
{isRefining ? "Refining..." : "Refine"}
</button>
)}
)}
</>
);
})()}
{isRefineMenuOpen && (
<div
className="refine-menu refine-menu--modal"

View File

@@ -285,6 +285,40 @@ describe("TaskForm", () => {
expect(container.querySelector(".description-with-refine.description--fullscreen")).toBeNull();
});
it("expand button uses flush placement when description is empty (no refine button)", () => {
const { container } = renderTaskForm({
mode: "create",
description: "",
});
const expandButton = screen.getByRole("button", { name: "Expand description" });
expect(expandButton).toBeTruthy();
// Expand button should have flush placement when refine is absent
expect(container.querySelector(".description-expand-btn--flush")).toBeTruthy();
expect(container.querySelector(".description-expand-btn--offset")).toBeNull();
// Refine button should NOT be rendered when description is empty
expect(screen.queryByTestId("refine-button")).toBeNull();
});
it("expand button uses offset placement when description has content (refine visible)", () => {
const { container } = renderTaskForm({
mode: "create",
description: "Some task description",
});
const expandButton = screen.getByRole("button", { name: "Expand description" });
expect(expandButton).toBeTruthy();
// Expand button should have offset placement when refine is visible
expect(container.querySelector(".description-expand-btn--offset")).toBeTruthy();
expect(container.querySelector(".description-expand-btn--flush")).toBeNull();
// Refine button should be rendered when description is non-empty
expect(screen.getByTestId("refine-button")).toBeTruthy();
});
it("collapses fullscreen description editor on Escape in create mode", () => {
const { container } = renderTaskForm({
mode: "create",

View File

@@ -6086,9 +6086,19 @@ body {
position: relative;
}
/* Description expand button positioning.
The expand button sits in the top-right corner of the description textarea.
When the Refine button is visible (non-empty description), the expand button
is offset left (right: 40px) to avoid overlap. When Refine is absent (empty
description), the expand button sits flush in the corner (right: 8px). */
.description-expand-btn {
position: absolute;
top: 8px;
right: 8px; /* Default: flush placement when Refine is absent */
}
/* Offset placement when Refine button is visible (non-empty description) */
.description-expand-btn--offset {
right: 40px;
}