edit table from canvas

This commit is contained in:
Guy Ben-Aharon
2024-08-21 10:05:37 +03:00
parent 4ede0f3117
commit d4da127de6
7 changed files with 88 additions and 21 deletions

View File

@@ -0,0 +1,18 @@
import { emptyFn } from '@/lib/utils';
import { createContext } from 'react';
export type SidebarSection = 'tables' | 'relationships';
export interface LayoutContext {
openedTableInSidebar: string | undefined;
openTableFromSidebar: (tableId: string) => void;
selectedSidebarSection: SidebarSection;
selectSidebarSection: (section: SidebarSection) => void;
}
export const layoutContext = createContext<LayoutContext>({
openedTableInSidebar: undefined,
selectedSidebarSection: 'tables',
selectSidebarSection: emptyFn,
openTableFromSidebar: emptyFn,
});

View File

@@ -0,0 +1,25 @@
import React from 'react';
import { layoutContext, SidebarSection } from './layout-context';
export const LayoutProvider: React.FC<React.PropsWithChildren> = ({
children,
}) => {
const [openedTableInSidebar, setOpenedTableInSidebar] = React.useState<
string | undefined
>();
const [selectedSidebarSection, setSelectedSidebarSection] =
React.useState<SidebarSection>('tables');
return (
<layoutContext.Provider
value={{
openedTableInSidebar,
selectedSidebarSection,
openTableFromSidebar: setOpenedTableInSidebar,
selectSidebarSection: setSelectedSidebarSection,
}}
>
{children}
</layoutContext.Provider>
);
};

4
src/hooks/use-layout.ts Normal file
View File

@@ -0,0 +1,4 @@
import { useContext } from 'react';
import { layoutContext } from '@/context/layout-context/layout-context';
export const useLayout = () => useContext(layoutContext);

View File

@@ -1,10 +1,11 @@
import React from 'react';
import { NodeProps, Node } from '@xyflow/react';
import { Button } from '@/components/button/button';
import { Ellipsis, Table2 } from 'lucide-react';
import { Pencil, Table2 } from 'lucide-react';
import { Label } from '@/components/label/label';
import { DBTable } from '@/lib/domain/db-table';
import { TableNodeField } from './table-node-field';
import { useLayout } from '@/hooks/use-layout';
export type TableNodeType = Node<
{
@@ -19,8 +20,14 @@ export const TableNode: React.FC<NodeProps<TableNodeType>> = ({
id,
data: { table },
}) => {
const { openTableFromSidebar, selectSidebarSection } = useLayout();
const focused = !!selected && !dragging;
const openTableInEditor = () => {
selectSidebarSection('tables');
openTableFromSidebar(table.id);
};
return (
<div
className={`flex flex-col w-56 bg-background border ${selected ? 'border-slate-400' : ''} rounded-lg shadow-sm`}
@@ -38,8 +45,9 @@ export const TableNode: React.FC<NodeProps<TableNodeType>> = ({
<Button
variant="ghost"
className="hover:bg-primary-foreground p-0 w-6 h-6 text-slate-500 hover:text-slate-700"
onClick={openTableInEditor}
>
<Ellipsis className="h-4 w-4" />
<Pencil className="h-4 w-4" />
</Button>
</div>
</div>

View File

@@ -9,17 +9,22 @@ import {
} from '@/components/select/select';
import { TablesSection } from './tables-section/tables-section';
import { RelationshipsSection } from './relationships-section/relationships-section';
import { useLayout } from '@/hooks/use-layout';
import { SidebarSection } from '@/context/layout-context/layout-context';
export interface SidePanelProps {}
export const SidePanel: React.FC<SidePanelProps> = () => {
const [selected, setSelected] = React.useState('tables');
// const [selected, setSelected] = React.useState('tables');
const { selectSidebarSection, selectedSidebarSection } = useLayout();
return (
<aside className="flex h-full flex-col overflow-hidden">
<div className="flex justify-center border-b pt-0.5">
<Select
value={selected}
onValueChange={(value) => setSelected(value)}
value={selectedSidebarSection}
onValueChange={(value) =>
selectSidebarSection(value as SidebarSection)
}
>
<SelectTrigger className="border-none rounded-none shadow-none focus:border-transparent focus:ring-0 hover:underline hover:bg-secondary font-semibold">
<SelectValue />
@@ -34,7 +39,7 @@ export const SidePanel: React.FC<SidePanelProps> = () => {
</SelectContent>
</Select>
</div>
{selected === 'tables' ? (
{selectedSidebarSection === 'tables' ? (
<TablesSection />
) : (
<RelationshipsSection />

View File

@@ -2,17 +2,21 @@ import React from 'react';
import { Accordion } from '@/components/accordion/accordion';
import { TableListItem } from './table-list-item/table-list-item';
import { DBTable } from '@/lib/domain/db-table';
import { useLayout } from '@/hooks/use-layout';
export interface TableListProps {
tables: DBTable[];
}
export const TableList: React.FC<TableListProps> = ({ tables }) => {
const { openTableFromSidebar, openedTableInSidebar } = useLayout();
return (
<Accordion
type="single"
collapsible
className="flex flex-col w-full gap-1"
value={openedTableInSidebar}
onValueChange={openTableFromSidebar}
>
{tables.map((table) => (
<TableListItem key={table.id} table={table} />

View File

@@ -9,26 +9,29 @@ import { CreateDiagramDialogProvider } from './dialogs/create-diagram-dialog/cre
import { ConfigProvider } from './context/config-context/config-provider';
import { HistoryProvider } from './context/history-context/history-provider';
import { RedoUndoStackProvider } from './context/history-context/redo-undo-stack-provider';
import { LayoutProvider } from './context/layout-context/layout-provider';
const routes: RouteObject[] = [
...['', 'diagrams/:diagramId'].map((path) => ({
path,
element: (
<StorageProvider>
<ConfigProvider>
<RedoUndoStackProvider>
<ChartDBProvider>
<HistoryProvider>
<CreateDiagramDialogProvider>
<ReactFlowProvider>
<EditorPage />
</ReactFlowProvider>
</CreateDiagramDialogProvider>
</HistoryProvider>
</ChartDBProvider>
</RedoUndoStackProvider>
</ConfigProvider>
</StorageProvider>
<LayoutProvider>
<StorageProvider>
<ConfigProvider>
<RedoUndoStackProvider>
<ChartDBProvider>
<HistoryProvider>
<CreateDiagramDialogProvider>
<ReactFlowProvider>
<EditorPage />
</ReactFlowProvider>
</CreateDiagramDialogProvider>
</HistoryProvider>
</ChartDBProvider>
</RedoUndoStackProvider>
</ConfigProvider>
</StorageProvider>
</LayoutProvider>
),
})),
{