diff --git a/src/context/chartdb-context/chartdb-context.tsx b/src/context/chartdb-context/chartdb-context.tsx index bb839038..e8e9a2ce 100644 --- a/src/context/chartdb-context/chartdb-context.tsx +++ b/src/context/chartdb-context/chartdb-context.tsx @@ -5,6 +5,7 @@ import { DatabaseType } from '@/lib/domain/database-type'; import { DBField } from '@/lib/domain/db-field'; import { DBIndex } from '@/lib/domain/db-index'; import { DBRelationship } from '@/lib/domain/db-relationship'; +import { Diagram } from '@/lib/domain/diagram'; export interface ChartDBContext { diagramId: string; @@ -16,6 +17,7 @@ export interface ChartDBContext { // General operations updateDiagramId: (id: string) => void; updateDiagramName: (name: string) => void; + loadDiagram: (diagramId: string) => Promise; // Database type operations updateDatabaseType: (databaseType: DatabaseType) => void; @@ -80,6 +82,7 @@ export const chartDBContext = createContext({ // General operations updateDiagramId: emptyFn, updateDiagramName: emptyFn, + loadDiagram: emptyFn, // Database type operations updateDatabaseType: emptyFn, diff --git a/src/context/chartdb-context/chartdb-provider.tsx b/src/context/chartdb-context/chartdb-provider.tsx index 5329c75c..158d439a 100644 --- a/src/context/chartdb-context/chartdb-provider.tsx +++ b/src/context/chartdb-context/chartdb-provider.tsx @@ -6,6 +6,7 @@ import { DatabaseType } from '@/lib/domain/database-type'; import { DBField } from '@/lib/domain/db-field'; import { DBIndex } from '@/lib/domain/db-index'; import { DBRelationship } from '@/lib/domain/db-relationship'; +import { Diagram } from '@/lib/domain/diagram'; export const ChartDBProvider: React.FC = ({ children, @@ -285,6 +286,11 @@ export const ChartDBProvider: React.FC = ({ ); }; + const loadDiagram = (diagramId: string) => { + console.log('Loading diagram', diagramId); + return Promise.resolve({} as Diagram); + }; + return ( = ({ relationships, updateDiagramId, updateDiagramName, + loadDiagram, updateDatabaseType, createTable, addTable, diff --git a/src/context/config-context/config-context.tsx b/src/context/config-context/config-context.tsx new file mode 100644 index 00000000..f53b5cf7 --- /dev/null +++ b/src/context/config-context/config-context.tsx @@ -0,0 +1,13 @@ +import { createContext } from 'react'; +import { emptyFn } from '@/lib/utils'; +import { ChartDBConfig } from '@/lib/domain/config'; + +export interface ConfigContext { + config?: ChartDBConfig; + updateConfig: (config: Partial) => Promise; +} + +export const ConfigContext = createContext({ + config: undefined, + updateConfig: emptyFn, +}); diff --git a/src/context/config-context/config-provider.tsx b/src/context/config-context/config-provider.tsx new file mode 100644 index 00000000..1970672b --- /dev/null +++ b/src/context/config-context/config-provider.tsx @@ -0,0 +1,36 @@ +import React, { useEffect } from 'react'; +import { ConfigContext } from './config-context'; + +import { useData } from '@/hooks/use-data'; +import { ChartDBConfig } from '@/lib/domain/config'; + +export const ConfigProvider: React.FC = ({ + children, +}) => { + const { getConfig, updateConfig: updateDataConfig } = useData(); + const [config, setConfig] = React.useState(); + + useEffect(() => { + const loadConfig = async () => { + const config = await getConfig(); + setConfig(config); + }; + + loadConfig(); + }, [getConfig]); + + const updateConfig = async (config: Partial) => { + await updateDataConfig(config); + setConfig((prevConfig) => + prevConfig + ? { ...prevConfig, ...config } + : { ...{ defaultDiagramId: '' }, ...config } + ); + }; + + return ( + + {children} + + ); +}; diff --git a/src/context/data-context/data-context.tsx b/src/context/data-context/data-context.tsx index c4916b01..ca7a60c6 100644 --- a/src/context/data-context/data-context.tsx +++ b/src/context/data-context/data-context.tsx @@ -3,8 +3,13 @@ import { Diagram } from '@/lib/domain/diagram'; import { emptyFn } from '@/lib/utils'; import { DBRelationship } from '@/lib/domain/db-relationship'; import { DBTable } from '@/lib/domain/db-table'; +import { ChartDBConfig } from '@/lib/domain/config'; export interface DataContext { + // Config operations + getConfig: () => Promise; + updateConfig: (config: Partial) => Promise; + // Diagram operations addDiagram: (params: { diagram: Diagram }) => Promise; listDiagrams: () => Promise; @@ -49,6 +54,9 @@ export interface DataContext { } export const dataContext = createContext({ + getConfig: emptyFn, + updateConfig: emptyFn, + addDiagram: emptyFn, listDiagrams: emptyFn, getDiagram: emptyFn, diff --git a/src/context/data-context/data-provider.tsx b/src/context/data-context/data-provider.tsx index b4cbbc51..f9d70793 100644 --- a/src/context/data-context/data-provider.tsx +++ b/src/context/data-context/data-provider.tsx @@ -4,6 +4,7 @@ import Dexie, { type EntityTable } from 'dexie'; import { Diagram } from '@/lib/domain/diagram'; import { DBTable } from '@/lib/domain/db-table'; import { DBRelationship } from '@/lib/domain/db-relationship'; +import { ChartDBConfig } from '@/lib/domain/config'; export const DataProvider: React.FC = ({ children, @@ -21,6 +22,10 @@ export const DataProvider: React.FC = ({ DBRelationship & { diagramId: string }, 'id' // primary key "id" (for the typings only) >; + config: EntityTable< + ChartDBConfig & { id: number }, + 'id' // primary key "id" (for the typings only) + >; }; // Schema declaration: @@ -30,8 +35,28 @@ export const DataProvider: React.FC = ({ '++id, diagramId, name, x, y, fields, indexes, color, createdAt', db_relationships: '++id, diagramId, name, sourceTableId, targetTableId, sourceFieldId, targetFieldId, type, createdAt', + config: '++id, defaultDiagramId', }); + db.on('ready', async () => { + const config = await getConfig(); + + if (!config) { + await db.config.add({ + id: 1, + defaultDiagramId: '', + }); + } + }); + + const getConfig = async (): Promise => { + return await db.config.get(1); + }; + + const updateConfig = async (config: Partial) => { + await db.config.update(1, config); + }; + const addDiagram = async ({ diagram }: { diagram: Diagram }) => { await db.diagrams.add(diagram); }; @@ -167,6 +192,8 @@ export const DataProvider: React.FC = ({ return ( = ({ DatabaseType.GENERIC ); const { closeCreateDiagramDialog } = useCreateDiagramDialog(); + const { updateConfig } = useConfig(); const [scriptResult, setScriptResult] = React.useState(''); const [step, setStep] = React.useState( CreateDiagramDialogStep.SELECT_DATABASE @@ -48,7 +50,6 @@ export const CreateDiagramDialog: React.FC = ({ useEffect(() => { const fetchDiagrams = async () => { const diagrams = await listDiagrams(); - console.log({ diagrams }); setDiagramNumber(diagrams.length + 1); }; fetchDiagrams(); @@ -63,6 +64,7 @@ export const CreateDiagramDialog: React.FC = ({ relationships: [], }; await addDiagram({ diagram }); + await updateConfig({ defaultDiagramId: diagram.id }); closeCreateDiagramDialog(); navigate(`/diagrams/${diagram.id}`); }, [ @@ -71,6 +73,7 @@ export const CreateDiagramDialog: React.FC = ({ addDiagram, closeCreateDiagramDialog, navigate, + updateConfig, ]); const renderDatabaseOption = useCallback((type: DatabaseType) => { diff --git a/src/hooks/use-config.ts b/src/hooks/use-config.ts new file mode 100644 index 00000000..23fa33ac --- /dev/null +++ b/src/hooks/use-config.ts @@ -0,0 +1,4 @@ +import { useContext } from 'react'; +import { ConfigContext } from '@/context/config-context/config-context'; + +export const useConfig = () => useContext(ConfigContext); diff --git a/src/lib/domain/config.ts b/src/lib/domain/config.ts new file mode 100644 index 00000000..f6278a47 --- /dev/null +++ b/src/lib/domain/config.ts @@ -0,0 +1,3 @@ +export interface ChartDBConfig { + defaultDiagramId: string; +} diff --git a/src/pages/editor-page/editor-page.tsx b/src/pages/editor-page/editor-page.tsx index 7772127e..f4b0fe20 100644 --- a/src/pages/editor-page/editor-page.tsx +++ b/src/pages/editor-page/editor-page.tsx @@ -8,18 +8,30 @@ import { } from '@/components/resizable/resizable'; import { SidePanel } from './side-panel/side-panel'; import { Canvas } from './canvas/canvas'; -import { useParams } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import { useCreateDiagramDialog } from '@/hooks/use-create-diagram-dialog'; +import { useConfig } from '@/hooks/use-config'; export const EditorPage: React.FC = () => { const { openCreateDiagramDialog } = useCreateDiagramDialog(); const { diagramId } = useParams<{ diagramId: string }>(); + const { config } = useConfig(); + const navigate = useNavigate(); useEffect(() => { - if (!diagramId) { + if (!config) { + return; + } + + if (diagramId) { + // load diagram + console.log('load diagram to memory'); + } else if (!diagramId && config.defaultDiagramId) { + navigate(`/diagrams/${config.defaultDiagramId}`); + } else { openCreateDiagramDialog(); } - }, [diagramId, openCreateDiagramDialog]); + }, [diagramId, openCreateDiagramDialog, config, navigate]); return (
diff --git a/src/router.tsx b/src/router.tsx index 733ad06f..6a01754a 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -6,19 +6,22 @@ import { ChartDBProvider } from './context/chartdb-context/chartdb-provider'; import { ReactFlowProvider } from '@xyflow/react'; import { DataProvider } from './context/data-context/data-provider'; import { CreateDiagramDialogProvider } from './dialogs/create-diagram-dialog/create-diagram-dialog-provider'; +import { ConfigProvider } from './context/config-context/config-provider'; const routes: RouteObject[] = [ ...['', 'diagrams/:diagramId'].map((path) => ({ path, element: ( - - - - - - - + + + + + + + + + ), })),