From 8b17a175c3e7e27b789812eba4e3cd760beadb10 Mon Sep 17 00:00:00 2001
From: soryu <soryu@soryu.co>
Date: Tue, 6 Jan 2026 04:08:11 +0000
Subject: Initial Control system

---
 .../frontend/src/components/files/FileDetail.tsx   | 59 ++++++++++++++++++++++
 1 file changed, 59 insertions(+)

(limited to 'makima/frontend/src/components/files/FileDetail.tsx')

diff --git a/makima/frontend/src/components/files/FileDetail.tsx b/makima/frontend/src/components/files/FileDetail.tsx
index c7b716a..60458e9 100644
--- a/makima/frontend/src/components/files/FileDetail.tsx
+++ b/makima/frontend/src/components/files/FileDetail.tsx
@@ -3,6 +3,12 @@ import type { FileDetail as FileDetailType, FileVersionSummary, FileVersion } fr
 import { BodyRenderer } from "./BodyRenderer";
 import { VersionHistoryDropdown } from "./VersionHistoryDropdown";
 
+export interface FocusedElement {
+  index: number;
+  type: string;
+  preview: string;
+}
+
 interface FileDetailProps {
   file: FileDetailType;
   loading: boolean;
@@ -11,9 +17,17 @@ interface FileDetailProps {
   onDelete: (id: string) => void;
   onBodyElementUpdate?: (index: number, element: import("../../lib/api").BodyElement) => void;
   onBodyReorder?: (fromIndex: number, toIndex: number) => void;
+  onBodyElementDelete?: (index: number) => void;
+  onBodyElementDuplicate?: (index: number) => void;
   onEditingChange?: (isEditing: boolean) => void;
   hasPendingRemoteUpdate?: boolean;
   onOverwrite?: () => void;
+  // Focus element props
+  focusedElement?: FocusedElement | null;
+  onFocusElement?: (element: FocusedElement | null) => void;
+  onGenerateFromElement?: (index: number, action: string) => void;
+  onConvertElement?: (index: number, toType: string) => void;
+  onCreateTaskFromElement?: (index: number, selectedText?: string) => void;
   // Version history props
   versions?: FileVersionSummary[];
   versionsLoading?: boolean;
@@ -33,9 +47,16 @@ export function FileDetail({
   onDelete,
   onBodyElementUpdate,
   onBodyReorder,
+  onBodyElementDelete,
+  onBodyElementDuplicate,
   onEditingChange,
   hasPendingRemoteUpdate,
   onOverwrite,
+  focusedElement: _focusedElement,
+  onFocusElement,
+  onGenerateFromElement,
+  onConvertElement,
+  onCreateTaskFromElement,
   versions = [],
   versionsLoading = false,
   selectedVersion = null,
@@ -50,6 +71,38 @@ export function FileDetail({
   const [description, setDescription] = useState(file.description || "");
   const [transcriptExpanded, setTranscriptExpanded] = useState(false);
 
+  // Helper to get element preview text
+  const getElementPreview = (index: number): string => {
+    const element = file.body[index];
+    if (!element) return "";
+    switch (element.type) {
+      case "heading":
+      case "paragraph":
+        return element.text.slice(0, 50) + (element.text.length > 50 ? "..." : "");
+      case "code":
+        return element.content.slice(0, 50) + (element.content.length > 50 ? "..." : "");
+      case "list":
+        return element.items[0]?.slice(0, 40) + (element.items.length > 1 ? ` (+${element.items.length - 1} more)` : "");
+      case "chart":
+        return element.title || `${element.chartType} chart`;
+      case "image":
+        return element.alt || element.caption || "Image";
+      default:
+        return "Element";
+    }
+  };
+
+  // Handler for focus action from context menu
+  const handleFocusElement = (index: number) => {
+    const element = file.body[index];
+    if (!element || !onFocusElement) return;
+    onFocusElement({
+      index,
+      type: element.type,
+      preview: getElementPreview(index),
+    });
+  };
+
   // Update local state when file changes
   useEffect(() => {
     setName(file.name);
@@ -192,6 +245,12 @@ export function FileDetail({
             onEditingChange={onEditingChange}
             hasPendingRemoteUpdate={hasPendingRemoteUpdate}
             onOverwrite={onOverwrite}
+            onFocusElement={handleFocusElement}
+            onDeleteElement={onBodyElementDelete}
+            onDuplicateElement={onBodyElementDuplicate}
+            onConvertElement={onConvertElement}
+            onGenerateFromElement={onGenerateFromElement}
+            onCreateTaskFromElement={onCreateTaskFromElement}
           />
         </div>
 
-- 
cgit v1.2.3

