feat: Improve scrolling and fullscreen editor layout with custom scrollbar styles and simplified CodeMirror wrapper structure.

This commit is contained in:
Bruno Charest 2026-03-14 11:53:49 -04:00
parent 3b82d69b22
commit 2a14e4cea2
2 changed files with 157 additions and 82 deletions

View File

@ -225,3 +225,84 @@ body {
color: var(--color-fox-500); color: var(--color-fox-500);
background: rgba(255, 109, 0, 0.1); background: rgba(255, 109, 0, 0.1);
} }
/* ─── Custom Scrollbar ───────────────────────────────────────────────────── */
.custom-scrollbar {
scrollbar-width: thin;
scrollbar-color: var(--color-surface-500) transparent;
}
.custom-scrollbar::-webkit-scrollbar {
width: 8px;
height: 8px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background: transparent;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: var(--color-surface-500);
border-radius: 4px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background: var(--color-fox-600);
}
/* ─── CodeMirror Editor Fixes ────────────────────────────────────────────── */
.cm-editor {
outline: none !important;
font-family: 'Fira Code', 'Consolas', 'Monaco', monospace !important;
}
.cm-scroller {
overflow: auto !important;
scrollbar-width: thin;
scrollbar-color: var(--color-surface-500) transparent;
}
.cm-scroller::-webkit-scrollbar {
width: 8px;
height: 8px;
}
.cm-scroller::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.2);
}
.cm-scroller::-webkit-scrollbar-thumb {
background: var(--color-surface-500);
border-radius: 4px;
}
.cm-scroller::-webkit-scrollbar-thumb:hover {
background: var(--color-fox-600);
}
.cm-content {
padding: 12px 0 !important;
}
.cm-line {
padding: 0 12px !important;
}
/* ─── Fullscreen Overlay ─────────────────────────────────────────────────── */
.fullscreen-overlay {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
width: 100vw !important;
height: 100vh !important;
z-index: 99999 !important;
margin: 0 !important;
padding: 0 !important;
border-radius: 0 !important;
background: var(--color-surface-900) !important;
}

View File

@ -397,11 +397,12 @@ function AgentMemoryViewer({ agentName }: { agentName: string }) {
</div> </div>
</div> </div>
<div className="max-h-[600px] overflow-y-auto custom-scrollbar pr-2">
<div className="relative pl-6 before:absolute before:inset-0 before:left-[11px] before:w-0.5 before:bg-gradient-to-b before:from-blue-500/50 before:to-transparent pt-2"> <div className="relative pl-6 before:absolute before:inset-0 before:left-[11px] before:w-0.5 before:bg-gradient-to-b before:from-blue-500/50 before:to-transparent pt-2">
{memory.timeline.length === 0 ? ( {memory.timeline.length === 0 ? (
<div className="text-gray-500 text-sm py-4">La mémoire existe mais elle est actuellement vide.</div> <div className="text-gray-500 text-sm py-4">La mémoire existe mais elle est actuellement vide.</div>
) : ( ) : (
<div className="space-y-6"> <div className="space-y-6 pb-4">
{memory.timeline.map((item: Record<string, any>, idx: number) => ( {memory.timeline.map((item: Record<string, any>, idx: number) => (
<div key={idx} className="relative group"> <div key={idx} className="relative group">
{/* Node dot */} {/* Node dot */}
@ -409,7 +410,7 @@ function AgentMemoryViewer({ agentName }: { agentName: string }) {
{/* Content Card */} {/* Content Card */}
<div className="glass-card p-4 border border-surface-700/50 hover:border-blue-500/30 transition-colors"> <div className="glass-card p-4 border border-surface-700/50 hover:border-blue-500/30 transition-colors">
<div className="flex items-start justify-between mb-2"> <div className="flex items-start justify-between mb-2 gap-2">
<span className="text-[10px] font-mono text-gray-500 bg-surface-800 px-2 py-0.5 rounded"> <span className="text-[10px] font-mono text-gray-500 bg-surface-800 px-2 py-0.5 rounded">
{item.timestamp || item.created_at || 'Inconnu'} {item.timestamp || item.created_at || 'Inconnu'}
</span> </span>
@ -429,6 +430,7 @@ function AgentMemoryViewer({ agentName }: { agentName: string }) {
)} )}
</div> </div>
</div> </div>
</div>
); );
} }
@ -626,9 +628,9 @@ function AgentsTab() {
{/* Identity File Editor */} {/* Identity File Editor */}
{activeFile?.agent === agent.name && ( {activeFile?.agent === agent.name && (
<div className={`border border-glass-border bg-[#282c34] overflow-hidden shadow-inner mt-4 animate-fade-in flex flex-col ${ <div className={`border border-glass-border bg-[#282c34] overflow-hidden shadow-inner mt-4 animate-fade-in flex flex-col ${
isFullscreen ? 'fixed inset-0 w-screen h-screen z-[9999] m-0 p-0 rounded-none' : 'h-[500px] rounded-xl relative' isFullscreen ? 'fullscreen-overlay' : 'h-[500px] rounded-xl relative'
}`}> }`}>
<div className={`flex items-center justify-between px-3 py-2 bg-surface-900/80 border-b border-glass-border shrink-0 ${isFullscreen ? 'h-14 px-6' : ''}`}> <div className={`flex items-center justify-between bg-surface-900/80 border-b border-glass-border shrink-0 ${isFullscreen ? 'h-16 px-6 py-4' : 'px-3 py-2'}`}>
<span className="text-xs font-mono text-purple-300 truncate pr-4">workspace/{agent.name}/{activeFile.file}</span> <span className="text-xs font-mono text-purple-300 truncate pr-4">workspace/{agent.name}/{activeFile.file}</span>
<div className="flex gap-2 shrink-0"> <div className="flex gap-2 shrink-0">
<button onClick={() => setIsFullscreen(!isFullscreen)} className="px-2 py-1 rounded text-[10px] text-gray-400 hover:bg-surface-700 hover:text-white transition-colors"> <button onClick={() => setIsFullscreen(!isFullscreen)} className="px-2 py-1 rounded text-[10px] text-gray-400 hover:bg-surface-700 hover:text-white transition-colors">
@ -645,8 +647,7 @@ function AgentsTab() {
{fileLoading ? ( {fileLoading ? (
<div className="flex-1 flex items-center justify-center text-gray-500 text-sm animate-pulse">Chargement</div> <div className="flex-1 flex items-center justify-center text-gray-500 text-sm animate-pulse">Chargement</div>
) : ( ) : (
<div className="flex-1 overflow-hidden relative min-h-0 bg-[#282c34]"> <div className="flex-1 overflow-auto bg-[#282c34] min-h-0">
<div className="absolute inset-0 custom-scrollbar [&_.cm-editor]:h-full [&_.cm-editor]:bg-transparent [&_.cm-scroller]:h-full [&_.cm-scroller]:overflow-auto [&_.cm-scroller]:font-mono [&_.cm-scroller]:text-xs pb-10">
<CodeMirror <CodeMirror
value={fileContent} value={fileContent}
height="100%" height="100%"
@ -656,7 +657,6 @@ function AgentsTab() {
basicSetup={{ lineNumbers: true, foldGutter: false, highlightActiveLine: true, tabSize: 2 }} basicSetup={{ lineNumbers: true, foldGutter: false, highlightActiveLine: true, tabSize: 2 }}
/> />
</div> </div>
</div>
)} )}
</div> </div>
)} )}
@ -1154,7 +1154,7 @@ function ConfigFileEditor({ onClose, onSave }: { onClose: () => void, onSave: ()
}; };
return ( return (
<div className="fixed inset-0 w-screen h-screen z-[9999] m-0 p-0 rounded-none glass-card flex flex-col overflow-hidden border border-glass-border shadow-[0_40px_80px_rgb(0,0,0,0.9)] bg-surface-900/95 backdrop-blur-xl animate-fade-in"> <div className="fullscreen-overlay glass-card flex flex-col overflow-hidden border border-glass-border shadow-[0_40px_80px_rgb(0,0,0,0.9)] backdrop-blur-xl animate-fade-in">
<div className="flex items-center justify-between px-6 py-4 bg-surface-800 border-b border-glass-border shrink-0 h-16"> <div className="flex items-center justify-between px-6 py-4 bg-surface-800 border-b border-glass-border shrink-0 h-16">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-amber-500/20 to-orange-600/10 border border-amber-500/20 flex items-center justify-center text-xl"> <div className="w-10 h-10 rounded-xl bg-gradient-to-br from-amber-500/20 to-orange-600/10 border border-amber-500/20 flex items-center justify-center text-xl">
@ -1186,14 +1186,13 @@ function ConfigFileEditor({ onClose, onSave }: { onClose: () => void, onSave: ()
</div> </div>
</div> </div>
<div className="flex-1 overflow-hidden relative bg-[#282c34]"> <div className="flex-1 overflow-auto bg-[#282c34] min-h-0">
{loading ? ( {loading ? (
<div className="absolute inset-0 flex items-center justify-center flex-col gap-4"> <div className="flex items-center justify-center flex-col gap-4 h-full">
<span className="text-4xl animate-spin-slow opacity-50"></span> <span className="text-4xl animate-spin-slow opacity-50"></span>
<span className="text-gray-400 font-mono">Lecture de la configuration brute...</span> <span className="text-gray-400 font-mono">Lecture de la configuration brute...</span>
</div> </div>
) : ( ) : (
<div className="h-full w-full absolute inset-0 [&_.cm-editor]:h-full [&_.cm-scroller]:h-full [&_.cm-scroller]:overflow-auto [&_.cm-scroller]:font-mono [&_.cm-scroller]:text-[13px] custom-scrollbar pb-10">
<CodeMirror <CodeMirror
value={content} value={content}
height="100%" height="100%"
@ -1207,7 +1206,6 @@ function ConfigFileEditor({ onClose, onSave }: { onClose: () => void, onSave: ()
tabSize: 2, tabSize: 2,
}} }}
/> />
</div>
)} )}
</div> </div>
</div> </div>
@ -1307,7 +1305,7 @@ function FilesystemTab() {
{/* Editor Panel */} {/* Editor Panel */}
<div className={isFullscreen <div className={isFullscreen
? "fixed inset-0 w-screen h-screen z-[9999] m-0 p-0 rounded-none glass-card flex flex-col overflow-hidden border border-glass-border bg-surface-900 shadow-[0_30px_60px_rgb(0,0,0,0.9)] min-h-0" ? "fullscreen-overlay glass-card flex flex-col overflow-hidden border border-glass-border shadow-[0_30px_60px_rgb(0,0,0,0.9)] min-h-0"
: "glass-card w-2/3 flex flex-col overflow-hidden border border-glass-border shadow-[0_8px_30px_rgb(0,0,0,0.5)] min-h-0" : "glass-card w-2/3 flex flex-col overflow-hidden border border-glass-border shadow-[0_8px_30px_rgb(0,0,0,0.5)] min-h-0"
}> }>
{fileLoading ? ( {fileLoading ? (
@ -1368,16 +1366,15 @@ function FilesystemTab() {
</div> </div>
{/* Editor Body */} {/* Editor Body */}
<div className="flex-1 overflow-hidden relative bg-[#282c34]"> <div className="flex-1 overflow-auto bg-[#282c34] min-h-0">
{selectedFile.binary ? ( {selectedFile.binary ? (
<div className="absolute inset-0 flex items-center justify-center text-gray-500 bg-surface-900/60"> <div className="flex items-center justify-center text-gray-500 bg-surface-900/60 h-full">
<div className="text-center"> <div className="text-center">
<div className="text-5xl mb-3 opacity-30">📦</div> <div className="text-5xl mb-3 opacity-30">📦</div>
<p className="tracking-wide">Fichier binaire. Aperçu non disponible.</p> <p className="tracking-wide">Fichier binaire. Aperçu non disponible.</p>
</div> </div>
</div> </div>
) : editMode ? ( ) : editMode ? (
<div className="h-full w-full absolute inset-0 [&_.cm-editor]:h-full [&_.cm-scroller]:h-full [&_.cm-scroller]:overflow-auto [&_.cm-scroller]:font-mono [&_.cm-scroller]:text-[13px] pb-10">
<CodeMirror <CodeMirror
value={editContent} value={editContent}
height="100%" height="100%"
@ -1391,15 +1388,12 @@ function FilesystemTab() {
tabSize: 2, tabSize: 2,
}} }}
/> />
</div>
) : ( ) : (
<div className="h-full overflow-y-auto w-full custom-scrollbar absolute inset-0"> <div className="p-4">
<div className="p-4 min-h-full">
<pre className="text-[13px] text-[#abb2bf] font-mono whitespace-pre-wrap leading-relaxed"> <pre className="text-[13px] text-[#abb2bf] font-mono whitespace-pre-wrap leading-relaxed">
{selectedFile.pretty || selectedFile.content} {selectedFile.pretty || selectedFile.content}
</pre> </pre>
</div> </div>
</div>
)} )}
</div> </div>
</div> </div>