tftsr-devops_investigation/src/components/DocEditor.tsx
Shaun Arman 6602fd7cd2
Some checks failed
Test / rust-fmt-check (push) Has been cancelled
Test / rust-clippy (push) Has been cancelled
Test / rust-tests (push) Has been cancelled
Test / frontend-typecheck (push) Has been cancelled
Test / frontend-tests (push) Has been cancelled
Auto Tag / auto-tag (push) Has been cancelled
fix: improve download button visibility and add DOCX export
1. Download Button Visibility:
   - Changed from variant=outline to default variant (solid background)
   - Provides better contrast and icon visibility in both themes
   - Removed unnecessary text-foreground class

2. DOCX Export Support:
   - Added DOCX export via pandoc conversion
   - Writes temp markdown file, converts with pandoc, cleans up
   - Returns clear error if pandoc not installed
   - Supports same workflow as MD/PDF exports

3. Triaging Status Investigation:
   - triaging status is defined in schema and used in dashboard counts
   - Currently not automatically set when entering triage
   - Kept in filter dropdown as part of the data model

Tested: Rust compilation, TypeScript types, Rust formatting

Note: DOCX export requires pandoc to be installed on the system.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-03 12:33:27 -05:00

91 lines
3.1 KiB
TypeScript

import React, { useState } from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { FileText, Eye, Edit3, Download } from "lucide-react";
import { Button } from "@/components/ui";
interface DocEditorProps {
content: string;
onChange: (content: string) => void;
version?: number;
updatedAt?: string;
onExport?: (format: "md" | "pdf" | "docx") => void;
}
export function DocEditor({ content, onChange, version, updatedAt, onExport }: DocEditorProps) {
const [mode, setMode] = useState<"edit" | "preview">("edit");
return (
<div className="flex flex-col h-full border rounded-lg overflow-hidden">
{/* Toolbar */}
<div className="flex items-center justify-between border-b px-4 py-2 bg-card">
<div className="flex items-center gap-2">
<button
onClick={() => setMode("edit")}
className={`flex items-center gap-1 px-2 py-1 rounded text-sm ${
mode === "edit"
? "bg-primary text-primary-foreground"
: "text-muted-foreground hover:bg-accent"
}`}
>
<Edit3 className="w-3 h-3" />
Edit
</button>
<button
onClick={() => setMode("preview")}
className={`flex items-center gap-1 px-2 py-1 rounded text-sm ${
mode === "preview"
? "bg-primary text-primary-foreground"
: "text-muted-foreground hover:bg-accent"
}`}
>
<Eye className="w-3 h-3" />
Preview
</button>
</div>
<div className="flex items-center gap-2">
{version != null && (
<span className="text-xs text-muted-foreground">
v{version}
{updatedAt && ` | ${new Date(updatedAt).toLocaleDateString()}`}
</span>
)}
{onExport && (
<div className="flex items-center gap-1">
<Button size="sm" onClick={() => onExport("md")}>
<FileText className="w-3 h-3 mr-1" />
MD
</Button>
<Button size="sm" onClick={() => onExport("pdf")}>
<Download className="w-3 h-3 mr-1" />
PDF
</Button>
<Button size="sm" onClick={() => onExport("docx")}>
<Download className="w-3 h-3 mr-1" />
DOCX
</Button>
</div>
)}
</div>
</div>
{/* Editor / Preview */}
<div className="flex-1 overflow-y-auto">
{mode === "edit" ? (
<textarea
value={content}
onChange={(e) => onChange(e.target.value)}
className="w-full h-full min-h-[400px] p-4 bg-background text-sm font-mono resize-none focus:outline-none"
placeholder="Start writing your document..."
/>
) : (
<div className="p-4 prose prose-sm dark:prose-invert max-w-none text-foreground">
<ReactMarkdown remarkPlugins={[remarkGfm]}>{content}</ReactMarkdown>
</div>
)}
</div>
</div>
);
}