feat: remove header and buttons, move actions to toolbar, drag&drop to any folder level

This commit is contained in:
Agent Zero
2026-07-17 17:22:26 +02:00
parent f2d624720f
commit ede37aced8
2 changed files with 26 additions and 21 deletions
+2 -16
View File
@@ -36,13 +36,12 @@ function buildTree(folders: ChatFolder[], sessions: ChatSession[]): TreeNode[] {
} }
function TreeItem({ function TreeItem({
node, activeSessionId, onSelectSession, depth, onMoveSession, onDeleteFolder, onAddFolder, onDragSession, onDropToFolder, node, activeSessionId, onSelectSession, depth, onDeleteFolder, onAddFolder, onDragSession, onDropToFolder,
}: { }: {
node: TreeNode; node: TreeNode;
activeSessionId: string | null; activeSessionId: string | null;
onSelectSession: (id: string) => void; onSelectSession: (id: string) => void;
depth: number; depth: number;
onMoveSession: (sessionId: string, folderId: string | null) => void;
onDeleteFolder: (folderId: string) => void; onDeleteFolder: (folderId: string) => void;
onAddFolder: (parentId: string | null) => void; onAddFolder: (parentId: string | null) => void;
onDragSession: (sessionId: string) => void; onDragSession: (sessionId: string) => void;
@@ -109,7 +108,6 @@ function TreeItem({
activeSessionId={activeSessionId} activeSessionId={activeSessionId}
onSelectSession={onSelectSession} onSelectSession={onSelectSession}
depth={depth + 1} depth={depth + 1}
onMoveSession={onMoveSession}
onDeleteFolder={onDeleteFolder} onDeleteFolder={onDeleteFolder}
onAddFolder={onAddFolder} onAddFolder={onAddFolder}
onDragSession={onDragSession} onDragSession={onDragSession}
@@ -138,15 +136,8 @@ export function SessionList({ activeSessionId, onSelectSession, isSidebar, class
useEffect(() => { loadData(); }, [isSidebar]); useEffect(() => { loadData(); }, [isSidebar]);
const handleNewChat = async () => {
try {
const session = await createSession({ is_sidebar: isSidebar || false });
setSessions((prev) => [session, ...prev]); onSelectSession(session.id);
} catch (e) { setError(e instanceof Error ? e.message : 'Failed'); }
};
const handleAddFolder = (parentId: string | null) => { const handleAddFolder = (parentId: string | null) => {
const name = prompt('Ordnername:');; const name = prompt('Ordnername:');
if (!name) return; if (!name) return;
createFolder({ name, parent_id: parentId || undefined }).then(() => loadData()).catch((e) => setError(e?.message)); createFolder({ name, parent_id: parentId || undefined }).then(() => loadData()).catch((e) => setError(e?.message));
}; };
@@ -171,10 +162,6 @@ export function SessionList({ activeSessionId, onSelectSession, isSidebar, class
return ( return (
<div className={clsx('flex flex-col h-full', className)}> <div className={clsx('flex flex-col h-full', className)}>
<div className="p-3 border-b border-secondary-200 flex gap-2">
<button onClick={handleNewChat} className="flex-1 rounded-lg bg-primary-600 text-white px-3 py-2 text-sm font-medium hover:bg-primary-700">+ Neuer Chat</button>
<button onClick={() => handleAddFolder(null)} className="rounded-lg border border-secondary-300 px-3 py-2 text-sm hover:bg-secondary-100" title="Neuer Ordner">📁+</button>
</div>
{error && <div className="p-2 text-xs text-red-600">{error}</div>} {error && <div className="p-2 text-xs text-red-600">{error}</div>}
<div className="flex-1 overflow-y-auto p-2"> <div className="flex-1 overflow-y-auto p-2">
{tree.map((node) => ( {tree.map((node) => (
@@ -184,7 +171,6 @@ export function SessionList({ activeSessionId, onSelectSession, isSidebar, class
activeSessionId={activeSessionId} activeSessionId={activeSessionId}
onSelectSession={onSelectSession} onSelectSession={onSelectSession}
depth={0} depth={0}
onMoveSession={() => {}}
onDeleteFolder={handleDeleteFolder} onDeleteFolder={handleDeleteFolder}
onAddFolder={handleAddFolder} onAddFolder={handleAddFolder}
onDragSession={setDragSessionId} onDragSession={setDragSessionId}
+24 -5
View File
@@ -9,6 +9,7 @@ export function AIAssistantPage() {
const [agents, setAgents] = useState<AIAgent[]>([]); const [agents, setAgents] = useState<AIAgent[]>([]);
const [selectedAgentId, setSelectedAgentId] = useState<string | null>(null); const [selectedAgentId, setSelectedAgentId] = useState<string | null>(null);
const [mobileView, setMobileView] = useState<'list' | 'chat'>('list'); const [mobileView, setMobileView] = useState<'list' | 'chat'>('list');
const [refreshKey, setRefreshKey] = useState(0);
const { registerItems, unregisterPlugin } = usePluginToolbarStore(); const { registerItems, unregisterPlugin } = usePluginToolbarStore();
useEffect(() => { fetchAgents().then(setAgents).catch(() => {}); }, []); useEffect(() => { fetchAgents().then(setAgents).catch(() => {}); }, []);
@@ -37,7 +38,27 @@ export function AIAssistantPage() {
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
</svg> </svg>
), ),
onClick: () => { setActiveSessionId(null); setMobileView('list'); }, onClick: () => { setActiveSessionId(null); setMobileView('list'); setRefreshKey(k => k + 1); },
},
{
id: 'new-folder',
plugin: 'ai_assistant',
label: 'Ordner',
type: 'button',
group: 'actions',
icon: (
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" />
</svg>
),
onClick: () => {
const name = prompt('Ordnername:');
if (name) {
import('@/api/ai').then(({ createFolder }) => {
createFolder({ name }).then(() => setRefreshKey(k => k + 1)).catch(() => {});
});
}
},
}, },
]); ]);
return () => unregisterPlugin('ai_assistant'); return () => unregisterPlugin('ai_assistant');
@@ -49,8 +70,7 @@ export function AIAssistantPage() {
<div className="flex h-full" data-testid="ai-assistant-page"> <div className="flex h-full" data-testid="ai-assistant-page">
{/* Desktop: two-pane layout */} {/* Desktop: two-pane layout */}
<div className="hidden md:flex w-72 flex-shrink-0 border-r border-secondary-200 bg-white flex-col"> <div className="hidden md:flex w-72 flex-shrink-0 border-r border-secondary-200 bg-white flex-col">
<div className="h-16 flex items-center px-6 border-b border-secondary-200"><h1 className="text-lg font-bold text-secondary-900">KI Assistent</h1></div> <SessionList key={refreshKey} activeSessionId={activeSessionId} onSelectSession={setActiveSessionId} className="flex-1" />
<SessionList activeSessionId={activeSessionId} onSelectSession={setActiveSessionId} className="h-[calc(100%-4rem)]" />
</div> </div>
<div className="hidden md:flex flex-1 flex-col"> <div className="hidden md:flex flex-1 flex-col">
{activeSessionId ? <ChatWindow sessionId={activeSessionId} agentId={selectedAgentId} className="flex-1" /> : ( {activeSessionId ? <ChatWindow sessionId={activeSessionId} agentId={selectedAgentId} className="flex-1" /> : (
@@ -61,8 +81,7 @@ export function AIAssistantPage() {
<div className="flex md:hidden flex-1 flex-col overflow-hidden"> <div className="flex md:hidden flex-1 flex-col overflow-hidden">
{mobileView === 'list' && ( {mobileView === 'list' && (
<div className="flex-1 flex flex-col bg-white"> <div className="flex-1 flex flex-col bg-white">
<div className="h-14 flex items-center px-4 border-b border-secondary-200"><h1 className="text-lg font-bold text-secondary-900">KI Assistent</h1></div> <SessionList key={refreshKey} activeSessionId={activeSessionId} onSelectSession={handleSelectSession} className="flex-1" />
<SessionList activeSessionId={activeSessionId} onSelectSession={handleSelectSession} className="flex-1" />
</div> </div>
)} )}
{mobileView === 'chat' && activeSessionId && ( {mobileView === 'chat' && activeSessionId && (