FN-5801: add markdown preview toggle for planning description

Add a markdown/plain toggle to the planning summary description so users can preview formatted content before creating a task.

- add a Description header toggle that switches between editable plain textarea and rendered markdown preview
- render description preview with react-markdown and remark-gfm while preserving expand/collapse layout behavior
- add preview container styles and spacing adjustments for summary form
- add UI interaction test coverage for markdown toggle behavior and rendered heading/bold content
- document the new markdown/plain description toggle in dashboard guide

Files changed:
 docs/dashboard-guide.md                            |  1 +
 packages/dashboard/app/components/PlanningModeModal.css | 18 +++++++-
 packages/dashboard/app/components/PlanningModeModal.tsx | 32 ++++++++++---
 packages/dashboard/app/components/__tests__/PlanningModeModal.ui-interactions.test.tsx | 54 ++++++++++++++++++++++
 4 files changed, 98 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-5801

Fusion-Task-Lineage: 34972830-7d51-4fcd-bf00-3de8f5aff028
This commit is contained in:
gsxdsm
2026-05-31 21:59:06 -07:00
parent 0a16fc690a
commit 4ea43c0c87
4 changed files with 98 additions and 7 deletions

View File

@@ -1,5 +1,7 @@
import "./PlanningModeModal.css";
import { useState, useCallback, useEffect, useRef, useMemo } from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import type { Task, PlanningQuestion, PlanningSummary, TaskPriority } from "@fusion/core";
import { DEFAULT_TASK_PRIORITY, TASK_PRIORITIES, getErrorMessage } from "@fusion/core";
import {
@@ -2422,6 +2424,7 @@ function SummaryView({
isLoading,
}: SummaryViewProps) {
const [isExpanded, setIsExpanded] = useState(false);
const [renderMarkdown, setRenderMarkdown] = useState(false);
const [selectedDependencies, setSelectedDependencies] = useState<string[]>(
summary.suggestedDependencies
);
@@ -2463,6 +2466,17 @@ function SummaryView({
<div className="form-group">
<label>
Description
<button
type="button"
className="planning-expand-btn"
aria-pressed={renderMarkdown}
aria-label={renderMarkdown ? "Show raw text" : "Show formatted markdown"}
title={renderMarkdown ? "Show raw text" : "Show formatted markdown"}
data-testid="planning-description-markdown-toggle"
onClick={() => setRenderMarkdown(!renderMarkdown)}
>
{renderMarkdown ? "Plain" : "Markdown"}
</button>
<button
type="button"
className="planning-expand-btn"
@@ -2471,12 +2485,18 @@ function SummaryView({
{isExpanded ? "Collapse" : "Expand"}
</button>
</label>
<textarea
ref={descriptionAutosizeRef}
className={`planning-textarea ${isExpanded ? "expanded" : ""}`}
value={summary.description}
onChange={(e) => onSummaryChange({ ...summary, description: e.target.value })}
/>
{renderMarkdown ? (
<div className={`planning-description-preview markdown-body ${isExpanded ? "expanded" : ""}`}>
<ReactMarkdown remarkPlugins={[remarkGfm]}>{summary.description}</ReactMarkdown>
</div>
) : (
<textarea
ref={descriptionAutosizeRef}
className={`planning-textarea ${isExpanded ? "expanded" : ""}`}
value={summary.description}
onChange={(e) => onSummaryChange({ ...summary, description: e.target.value })}
/>
)}
</div>
<div className="task-detail-section">