feat: implement sidebar component for database and table navigation with filtering support
This commit is contained in:
@@ -9,11 +9,13 @@ const Sidebar: React.FC = () => {
|
|||||||
const [databases, setDatabases] = useState<string[]>([]);
|
const [databases, setDatabases] = useState<string[]>([]);
|
||||||
const [tables, setTables] = useState<string[]>([]);
|
const [tables, setTables] = useState<string[]>([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [tablesLoading, setTablesLoading] = useState(false);
|
const [expandedDbs, setExpandedDbs] = useState<string[]>([]);
|
||||||
|
|
||||||
const [dbSearch, setDbSearch] = useState('');
|
const [dbSearch, setDbSearch] = useState('');
|
||||||
const [tableSearch, setTableSearch] = useState('');
|
const [tableSearch, setTableSearch] = useState('');
|
||||||
|
|
||||||
|
const [tablesLoading, setTablesLoading] = useState(false);
|
||||||
|
|
||||||
// Fetch databases on mount
|
// Fetch databases on mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchDatabases = async () => {
|
const fetchDatabases = async () => {
|
||||||
@@ -51,13 +53,28 @@ const Sidebar: React.FC = () => {
|
|||||||
fetchTables();
|
fetchTables();
|
||||||
}, [activeDatabase]);
|
}, [activeDatabase]);
|
||||||
|
|
||||||
|
// Auto-expand when a database is active
|
||||||
|
useEffect(() => {
|
||||||
|
if (activeDatabase && !expandedDbs.includes(activeDatabase)) {
|
||||||
|
setExpandedDbs(prev => [...prev, activeDatabase]);
|
||||||
|
}
|
||||||
|
}, [activeDatabase]);
|
||||||
|
|
||||||
|
const toggleExpansion = (e: React.MouseEvent, db: string) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
setExpandedDbs(prev =>
|
||||||
|
prev.includes(db) ? prev.filter(d => d !== db) : [...prev, db]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const handleDatabaseClick = (db: string) => {
|
const handleDatabaseClick = (db: string) => {
|
||||||
if (activeDatabase === db) {
|
setActiveDatabase(db);
|
||||||
setActiveDatabase(null);
|
setActiveTable(null);
|
||||||
setTableSearch('');
|
setTableSearch('');
|
||||||
} else {
|
|
||||||
setActiveDatabase(db);
|
// Also ensure it's expanded
|
||||||
setTableSearch('');
|
if (!expandedDbs.includes(db)) {
|
||||||
|
setExpandedDbs(prev => [...prev, db]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -113,8 +130,8 @@ const Sidebar: React.FC = () => {
|
|||||||
selected={activeDatabase === db}
|
selected={activeDatabase === db}
|
||||||
sx={{ py: 0.5, px: 1 }}
|
sx={{ py: 0.5, px: 1 }}
|
||||||
>
|
>
|
||||||
<ListItemIcon sx={{ minWidth: 24 }}>
|
<ListItemIcon sx={{ minWidth: 24, cursor: 'pointer' }} onClick={(e) => toggleExpansion(e, db)}>
|
||||||
{activeDatabase === db ? <ExpandMore fontSize="small" /> : <ChevronRight fontSize="small" />}
|
{expandedDbs.includes(db) ? <ExpandMore fontSize="small" /> : <ChevronRight fontSize="small" />}
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemIcon sx={{ minWidth: 32 }}>
|
<ListItemIcon sx={{ minWidth: 32 }}>
|
||||||
<Folder fontSize="small" sx={{ color: activeDatabase === db ? 'primary.main' : 'text.secondary' }} />
|
<Folder fontSize="small" sx={{ color: activeDatabase === db ? 'primary.main' : 'text.secondary' }} />
|
||||||
@@ -125,7 +142,7 @@ const Sidebar: React.FC = () => {
|
|||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
{activeDatabase === db && (
|
{expandedDbs.includes(db) && (
|
||||||
<Box sx={{
|
<Box sx={{
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
ml: 2.5,
|
ml: 2.5,
|
||||||
|
|||||||
Reference in New Issue
Block a user