/** * SourceTree - left sidebar directory tree for DMS. * Replaces FolderTree with a "sources" concept: * ▼ Meine Dateien (local folders) * ▼ Geteilte Ordner (shared files from other users) * ▼ Externe Speicher (placeholder for future plugins) */ import React, { useState } from 'react'; import clsx from 'clsx'; import { useTranslation } from 'react-i18next'; import type { DmsFolder, DmsFile } from '@/api/dms'; interface SourceTreeFolderItemProps { folder: DmsFolder; level: number; selectedFolderId: string | null; onSelect: (folderId: string) => void; } function SourceTreeFolderItem({ folder, level, selectedFolderId, onSelect, }: SourceTreeFolderItemProps) { const { t } = useTranslation(); const [expanded, setExpanded] = useState(true); const hasChildren = folder.children && folder.children.length > 0; const isSelected = selectedFolderId === folder.id; return (
  • onSelect(folder.id)} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onSelect(folder.id); } }} tabIndex={0} role="button" aria-label={folder.name} > {hasChildren && ( )} {!hasChildren &&
    {hasChildren && expanded && ( )}
  • ); } interface SourceSectionProps { title: string; icon: React.ReactNode; selected: boolean; onClick: () => void; children?: React.ReactNode; defaultExpanded?: boolean; } function SourceSection({ title, icon, selected, onClick, children, defaultExpanded = true }: SourceSectionProps) { const [expanded, setExpanded] = useState(defaultExpanded); return (
    { onClick(); setExpanded(true); }} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onClick(); setExpanded(true); } }} tabIndex={0} role="button" aria-label={title} > {icon} {title}
    {expanded && children && ( )}
    ); } export interface SourceTreeProps { folders: DmsFolder[]; sharedFiles: DmsFile[]; selectedFolderId: string | null; selectedSource: string | null; onSelectFolder: (folderId: string | null) => void; onSelectSource: (source: string) => void; loading?: boolean; } export function SourceTree({ folders, sharedFiles, selectedFolderId, selectedSource, onSelectFolder, onSelectSource, loading = false, }: SourceTreeProps) { const { t } = useTranslation(); if (loading) { return (
    {[1, 2, 3].map((i) => (
    ))}
    ); } const localSelected = selectedSource === 'local' || (selectedSource === null && selectedFolderId !== null); const sharedSelected = selectedSource === 'shared'; const externalSelected = selectedSource === 'external'; return ( ); }