From bb4fb1bac73e16884273f62b9b7f5c226e9694fa Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 3 Aug 2026 18:50:33 +0000 Subject: [PATCH] =?UTF-8?q?Navigation=20:=20Discussion=20+=20discussions?= =?UTF-8?q?=20r=C3=A9centes,=20Fichiers=20passe=20en=20onglet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le remaniement précédent avait supprimé le panneau de sessions, et avec lui le seul bouton pour démarrer une discussion. - « Demander » devient « Discussion », avec en dessous le bouton « + Nouvelle discussion » et les 5 discussions les plus récentes, cliquables (point accent sur celle qui travaille). - « Fichiers » quitte la barre latérale pour devenir un onglet du panneau droit, à côté de Code. L'arborescence est extraite en composant FileTree réutilisable. - Nettoyage du code devenu mort : LeftPanel, FilesView, WorkspaceTree, formatSize et la vue « files ». Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N --- frontend/src/App.tsx | 8 +- frontend/src/components/FileTree.tsx | 79 +++++++++++ frontend/src/components/Sidebar.tsx | 77 ++++++++++- frontend/src/panels/ActivityViews.tsx | 78 ----------- frontend/src/panels/LeftPanel.tsx | 185 -------------------------- frontend/src/panels/PreviewPanel.tsx | 33 ++++- 6 files changed, 182 insertions(+), 278 deletions(-) create mode 100644 frontend/src/components/FileTree.tsx delete mode 100644 frontend/src/panels/LeftPanel.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 9cdaf9f..e464d53 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -4,7 +4,7 @@ import { TopBar } from "./components/TopBar"; import { ChatPanel } from "./panels/ChatPanel"; import { PreviewPanel } from "./panels/PreviewPanel"; import { SettingsView } from "./panels/SettingsView"; -import { FilesView, HistoryView, ToolsView } from "./panels/ActivityViews"; +import { HistoryView, ToolsView } from "./panels/ActivityViews"; import { useStore } from "./store/useStore"; export default function App() { @@ -65,12 +65,6 @@ export default function App() { )} {view === "history" && setView("chat")} />} - {view === "files" && ( - <> - - - - )} {view === "tools" && setView("settings")} />} {view === "settings" && } diff --git a/frontend/src/components/FileTree.tsx b/frontend/src/components/FileTree.tsx new file mode 100644 index 0000000..755e5b7 --- /dev/null +++ b/frontend/src/components/FileTree.tsx @@ -0,0 +1,79 @@ +import { useStore } from "../store/useStore"; +import { downloadFile, type FileNode } from "../api/client"; +import { DownloadIcon, TrashIcon } from "./Icon"; + +/** Arborescence du workspace : ouvrir dans l'aperçu, télécharger, supprimer. */ +export function FileTree({ + nodes, + depth = 0, +}: { + nodes: FileNode[]; + depth?: number; +}) { + const { openPreview, previewPath, removeFile, currentProject } = useStore(); + + const confirmDelete = (n: FileNode) => { + const msg = + n.type === "dir" + ? `Supprimer le dossier ${n.path} et tout son contenu ?` + : `Supprimer ${n.path} ?`; + if (window.confirm(msg)) void removeFile(n.path); + }; + + return ( + <> + {nodes.map((n) => { + const active = n.type === "file" && n.path === previewPath; + return ( +
+
n.type === "file" && openPreview(n.path)} + className={`group mb-[2px] flex items-center gap-2 rounded-card px-2 py-[5px] text-[13.5px] ${ + n.type === "file" + ? active + ? "cursor-pointer border border-accent-line bg-accent-ghost text-ink" + : "cursor-pointer border border-transparent text-ink-3 hover:bg-accent-ghost" + : "text-muted-2" + }`} + style={{ paddingLeft: 8 + depth * 14 }} + > + {n.type === "dir" ? ( + ▾ + ) : ( + + )} + {n.name} + {n.type === "file" && ( + + )} + +
+ {n.children && } +
+ ); + })} + + ); +} diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 9a6e4ed..0c48852 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -2,21 +2,25 @@ import { useStore } from "../store/useStore"; import { ChatIcon, ClockIcon, - FilesIcon, LokiMark, NodesIcon, + PlusIcon, SettingsIcon, } from "./Icon"; -export type View = "chat" | "history" | "files" | "tools" | "settings"; +export type View = "chat" | "history" | "tools" | "settings"; +// Les fichiers ne sont plus une vue : ils vivent dans l'onglet « Fichiers » +// du panneau droit, à côté de Code. const NAV: { id: View; label: string; icon: React.ReactNode }[] = [ - { id: "chat", label: "Demander", icon: }, + { id: "chat", label: "Discussion", icon: }, { id: "history", label: "Historique", icon: }, - { id: "files", label: "Fichiers", icon: }, { id: "tools", label: "Outils", icon: }, ]; +/** Nombre de discussions récentes listées sous « Discussion ». */ +const RECENT = 5; + /** Barre latérale (264 px) : marque, navigation, état Ollama, compte. */ export function Sidebar({ active, @@ -25,8 +29,28 @@ export function Sidebar({ active: View; onChange: (v: View) => void; }) { - const { status, selectedModel, systemStats } = useStore(); + const { + status, + selectedModel, + systemStats, + sessions, + currentSessionId, + streamingSessionId, + newSession, + openSession, + } = useStore(); const gpu = systemStats?.gpu ?? null; + const recent = sessions.slice(0, RECENT); + + const startChat = () => { + void newSession(); + onChange("chat"); + }; + + const pick = (id: string) => { + void openSession(id); + onChange("chat"); + }; return (