fix: move dbml into sections menu (#862)

This commit is contained in:
Guy Ben-Aharon
2025-08-21 14:48:47 +03:00
committed by GitHub
parent 73daf0df21
commit 2531a7023f
6 changed files with 70 additions and 89 deletions

View File

@@ -2,6 +2,7 @@ import { emptyFn } from '@/lib/utils';
import { createContext } from 'react'; import { createContext } from 'react';
export type SidebarSection = export type SidebarSection =
| 'dbml'
| 'tables' | 'tables'
| 'relationships' | 'relationships'
| 'dependencies' | 'dependencies'

View File

@@ -10,7 +10,14 @@ import {
SidebarMenuButton, SidebarMenuButton,
SidebarMenuItem, SidebarMenuItem,
} from '@/components/sidebar/sidebar'; } from '@/components/sidebar/sidebar';
import { BookOpen, Group, FileType, Plus, FolderOpen } from 'lucide-react'; import {
BookOpen,
Group,
FileType,
Plus,
FolderOpen,
CodeXml,
} from 'lucide-react';
import { SquareStack, Table, Workflow } from 'lucide-react'; import { SquareStack, Table, Workflow } from 'lucide-react';
import { useLayout } from '@/hooks/use-layout'; import { useLayout } from '@/hooks/use-layout';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@@ -76,6 +83,15 @@ export const EditorSidebar: React.FC<EditorSidebarProps> = () => {
}, },
active: selectedSidebarSection === 'tables', active: selectedSidebarSection === 'tables',
}, },
{
title: 'DBML',
icon: CodeXml,
onClick: () => {
showSidePanel();
selectSidebarSection('dbml');
},
active: selectedSidebarSection === 'dbml',
},
{ {
title: t('editor_sidebar.relationships'), title: t('editor_sidebar.relationships'),
icon: Workflow, icon: Workflow,

View File

@@ -0,0 +1,17 @@
import React from 'react';
import { TableDBML } from './table-dbml/table-dbml';
export interface DBMLSectionProps {}
export const DBMLSection: React.FC<DBMLSectionProps> = () => {
return (
<section
className="flex flex-1 flex-col overflow-hidden px-2"
data-vaul-no-drag
>
<div className="flex flex-1 flex-col overflow-hidden">
<TableDBML />
</div>
</section>
);
};

View File

@@ -5,7 +5,6 @@ import React, {
useCallback, useCallback,
useRef, useRef,
} from 'react'; } from 'react';
import type { DBTable } from '@/lib/domain/db-table';
import { useChartDB } from '@/hooks/use-chartdb'; import { useChartDB } from '@/hooks/use-chartdb';
import { useTheme } from '@/hooks/use-theme'; import { useTheme } from '@/hooks/use-theme';
import { CodeSnippet } from '@/components/code-snippet/code-snippet'; import { CodeSnippet } from '@/components/code-snippet/code-snippet';
@@ -36,9 +35,7 @@ import type * as monaco from 'monaco-editor';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useFullScreenLoader } from '@/hooks/use-full-screen-spinner'; import { useFullScreenLoader } from '@/hooks/use-full-screen-spinner';
export interface TableDBMLProps { export interface TableDBMLProps {}
filteredTables: DBTable[];
}
const getEditorTheme = (theme: EffectiveTheme) => { const getEditorTheme = (theme: EffectiveTheme) => {
return theme === 'dark' ? 'dbml-dark' : 'dbml-light'; return theme === 'dark' ? 'dbml-dark' : 'dbml-light';

View File

@@ -18,6 +18,7 @@ import { useBreakpoint } from '@/hooks/use-breakpoint';
import { AreasSection } from './areas-section/areas-section'; import { AreasSection } from './areas-section/areas-section';
import { CustomTypesSection } from './custom-types-section/custom-types-section'; import { CustomTypesSection } from './custom-types-section/custom-types-section';
import { DatabaseType } from '@/lib/domain/database-type'; import { DatabaseType } from '@/lib/domain/database-type';
import { DBMLSection } from './dbml-section/dbml-section';
export interface SidePanelProps {} export interface SidePanelProps {}
@@ -75,6 +76,8 @@ export const SidePanel: React.FC<SidePanelProps> = () => {
) : null} ) : null}
{selectedSidebarSection === 'tables' ? ( {selectedSidebarSection === 'tables' ? (
<TablesSection /> <TablesSection />
) : selectedSidebarSection === 'dbml' ? (
<DBMLSection />
) : selectedSidebarSection === 'relationships' ? ( ) : selectedSidebarSection === 'relationships' ? (
<RelationshipsSection /> <RelationshipsSection />
) : selectedSidebarSection === 'dependencies' ? ( ) : selectedSidebarSection === 'dependencies' ? (

View File

@@ -1,7 +1,7 @@
import React, { useCallback, useMemo, useState } from 'react'; import React, { useCallback, useMemo } from 'react';
import { TableList } from './table-list/table-list'; import { TableList } from './table-list/table-list';
import { Button } from '@/components/button/button'; import { Button } from '@/components/button/button';
import { Table, List, X, Code } from 'lucide-react'; import { Table, X } from 'lucide-react';
import { Input } from '@/components/input/input'; import { Input } from '@/components/input/input';
import type { DBTable } from '@/lib/domain/db-table'; import type { DBTable } from '@/lib/domain/db-table';
import { useChartDB } from '@/hooks/use-chartdb'; import { useChartDB } from '@/hooks/use-chartdb';
@@ -9,16 +9,8 @@ import { useLayout } from '@/hooks/use-layout';
import { EmptyState } from '@/components/empty-state/empty-state'; import { EmptyState } from '@/components/empty-state/empty-state';
import { ScrollArea } from '@/components/scroll-area/scroll-area'; import { ScrollArea } from '@/components/scroll-area/scroll-area';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@/components/tooltip/tooltip';
import { useViewport } from '@xyflow/react'; import { useViewport } from '@xyflow/react';
import { useDialog } from '@/hooks/use-dialog'; import { useDialog } from '@/hooks/use-dialog';
import { TableDBML } from './table-dbml/table-dbml';
import { useHotkeys } from 'react-hotkeys-hook';
import { getOperatingSystem } from '@/lib/utils';
import type { DBSchema } from '@/lib/domain'; import type { DBSchema } from '@/lib/domain';
import { useDiagramFilter } from '@/context/diagram-filter-context/use-diagram-filter'; import { useDiagramFilter } from '@/context/diagram-filter-context/use-diagram-filter';
import { filterTable } from '@/lib/domain/diagram-filter/filter'; import { filterTable } from '@/lib/domain/diagram-filter/filter';
@@ -34,7 +26,6 @@ export const TablesSection: React.FC<TablesSectionProps> = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const { openTableFromSidebar } = useLayout(); const { openTableFromSidebar } = useLayout();
const [filterText, setFilterText] = React.useState(''); const [filterText, setFilterText] = React.useState('');
const [showDBML, setShowDBML] = useState(false);
const filterInputRef = React.useRef<HTMLInputElement>(null); const filterInputRef = React.useRef<HTMLInputElement>(null);
const filteredTables = useMemo(() => { const filteredTables = useMemo(() => {
@@ -104,52 +95,12 @@ export const TablesSection: React.FC<TablesSectionProps> = () => {
setFilterText(''); setFilterText('');
}, []); }, []);
const operatingSystem = useMemo(() => getOperatingSystem(), []);
useHotkeys(
operatingSystem === 'mac' ? 'meta+p' : 'ctrl+p',
() => {
setShowDBML((value) => !value);
},
{
preventDefault: true,
},
[setShowDBML]
);
return ( return (
<section <section
className="flex flex-1 flex-col overflow-hidden px-2" className="flex flex-1 flex-col overflow-hidden px-2"
data-vaul-no-drag data-vaul-no-drag
> >
<div className="flex items-center justify-between gap-4 py-1"> <div className="flex items-center justify-between gap-4 py-1">
<div>
<Tooltip>
<TooltipTrigger asChild>
<span>
<Button
variant="ghost"
className="size-8 p-0"
onClick={() =>
setShowDBML((value) => !value)
}
>
{showDBML ? (
<List className="size-4" />
) : (
<Code className="size-4" />
)}
</Button>
</span>
</TooltipTrigger>
<TooltipContent>
{showDBML
? t('side_panel.tables_section.show_list')
: t('side_panel.tables_section.show_dbml')}
{operatingSystem === 'mac' ? ' (⌘P)' : ' (Ctrl+P)'}
</TooltipContent>
</Tooltip>
</div>
<div className="flex-1"> <div className="flex-1">
<Input <Input
ref={filterInputRef} ref={filterInputRef}
@@ -170,40 +121,36 @@ export const TablesSection: React.FC<TablesSectionProps> = () => {
</Button> </Button>
</div> </div>
<div className="flex flex-1 flex-col overflow-hidden"> <div className="flex flex-1 flex-col overflow-hidden">
{showDBML ? ( <ScrollArea className="h-full">
<TableDBML filteredTables={filteredTables} /> {tables.length === 0 ? (
) : ( <EmptyState
<ScrollArea className="h-full"> title={t(
{tables.length === 0 ? ( 'side_panel.tables_section.empty_state.title'
<EmptyState )}
title={t( description={t(
'side_panel.tables_section.empty_state.title' 'side_panel.tables_section.empty_state.description'
)} )}
description={t( className="mt-20"
'side_panel.tables_section.empty_state.description' />
)} ) : filterText && filteredTables.length === 0 ? (
className="mt-20" <div className="mt-10 flex flex-col items-center gap-2">
/> <div className="text-sm text-muted-foreground">
) : filterText && filteredTables.length === 0 ? ( {t('side_panel.tables_section.no_results')}
<div className="mt-10 flex flex-col items-center gap-2">
<div className="text-sm text-muted-foreground">
{t('side_panel.tables_section.no_results')}
</div>
<Button
variant="outline"
size="sm"
onClick={handleClearFilter}
className="gap-1"
>
<X className="size-3.5" />
{t('side_panel.tables_section.clear')}
</Button>
</div> </div>
) : ( <Button
<TableList tables={filteredTables} /> variant="outline"
)} size="sm"
</ScrollArea> onClick={handleClearFilter}
)} className="gap-1"
>
<X className="size-3.5" />
{t('side_panel.tables_section.clear')}
</Button>
</div>
) : (
<TableList tables={filteredTables} />
)}
</ScrollArea>
</div> </div>
</section> </section>
); );