mirror of
https://github.com/chartdb/chartdb.git
synced 2025-11-11 17:36:10 +00:00
config
This commit is contained in:
@@ -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<Diagram | null>;
|
||||
|
||||
// Database type operations
|
||||
updateDatabaseType: (databaseType: DatabaseType) => void;
|
||||
@@ -80,6 +82,7 @@ export const chartDBContext = createContext<ChartDBContext>({
|
||||
// General operations
|
||||
updateDiagramId: emptyFn,
|
||||
updateDiagramName: emptyFn,
|
||||
loadDiagram: emptyFn,
|
||||
|
||||
// Database type operations
|
||||
updateDatabaseType: emptyFn,
|
||||
|
||||
@@ -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<React.PropsWithChildren> = ({
|
||||
children,
|
||||
@@ -285,6 +286,11 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const loadDiagram = (diagramId: string) => {
|
||||
console.log('Loading diagram', diagramId);
|
||||
return Promise.resolve({} as Diagram);
|
||||
};
|
||||
|
||||
return (
|
||||
<chartDBContext.Provider
|
||||
value={{
|
||||
@@ -295,6 +301,7 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
relationships,
|
||||
updateDiagramId,
|
||||
updateDiagramName,
|
||||
loadDiagram,
|
||||
updateDatabaseType,
|
||||
createTable,
|
||||
addTable,
|
||||
|
||||
13
src/context/config-context/config-context.tsx
Normal file
13
src/context/config-context/config-context.tsx
Normal file
@@ -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<ChartDBConfig>) => Promise<void>;
|
||||
}
|
||||
|
||||
export const ConfigContext = createContext<ConfigContext>({
|
||||
config: undefined,
|
||||
updateConfig: emptyFn,
|
||||
});
|
||||
36
src/context/config-context/config-provider.tsx
Normal file
36
src/context/config-context/config-provider.tsx
Normal file
@@ -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<React.PropsWithChildren> = ({
|
||||
children,
|
||||
}) => {
|
||||
const { getConfig, updateConfig: updateDataConfig } = useData();
|
||||
const [config, setConfig] = React.useState<ChartDBConfig | undefined>();
|
||||
|
||||
useEffect(() => {
|
||||
const loadConfig = async () => {
|
||||
const config = await getConfig();
|
||||
setConfig(config);
|
||||
};
|
||||
|
||||
loadConfig();
|
||||
}, [getConfig]);
|
||||
|
||||
const updateConfig = async (config: Partial<ChartDBConfig>) => {
|
||||
await updateDataConfig(config);
|
||||
setConfig((prevConfig) =>
|
||||
prevConfig
|
||||
? { ...prevConfig, ...config }
|
||||
: { ...{ defaultDiagramId: '' }, ...config }
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<ConfigContext.Provider value={{ config, updateConfig }}>
|
||||
{children}
|
||||
</ConfigContext.Provider>
|
||||
);
|
||||
};
|
||||
@@ -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<ChartDBConfig | undefined>;
|
||||
updateConfig: (config: Partial<ChartDBConfig>) => Promise<void>;
|
||||
|
||||
// Diagram operations
|
||||
addDiagram: (params: { diagram: Diagram }) => Promise<void>;
|
||||
listDiagrams: () => Promise<Diagram[]>;
|
||||
@@ -49,6 +54,9 @@ export interface DataContext {
|
||||
}
|
||||
|
||||
export const dataContext = createContext<DataContext>({
|
||||
getConfig: emptyFn,
|
||||
updateConfig: emptyFn,
|
||||
|
||||
addDiagram: emptyFn,
|
||||
listDiagrams: emptyFn,
|
||||
getDiagram: emptyFn,
|
||||
|
||||
@@ -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<React.PropsWithChildren> = ({
|
||||
children,
|
||||
@@ -21,6 +22,10 @@ export const DataProvider: React.FC<React.PropsWithChildren> = ({
|
||||
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<React.PropsWithChildren> = ({
|
||||
'++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<ChartDBConfig | undefined> => {
|
||||
return await db.config.get(1);
|
||||
};
|
||||
|
||||
const updateConfig = async (config: Partial<ChartDBConfig>) => {
|
||||
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<React.PropsWithChildren> = ({
|
||||
return (
|
||||
<dataContext.Provider
|
||||
value={{
|
||||
getConfig,
|
||||
updateConfig,
|
||||
addDiagram,
|
||||
listDiagrams,
|
||||
getDiagram,
|
||||
|
||||
@@ -20,6 +20,7 @@ import { Diagram } from '@/lib/domain/diagram';
|
||||
import { generateId } from '@/lib/utils';
|
||||
import { useCreateDiagramDialog } from '@/hooks/use-create-diagram-dialog';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useConfig } from '@/hooks/use-config';
|
||||
|
||||
enum CreateDiagramDialogStep {
|
||||
SELECT_DATABASE = 'SELECT_DATABASE',
|
||||
@@ -37,6 +38,7 @@ export const CreateDiagramDialog: React.FC<CreateDiagramDialogProps> = ({
|
||||
DatabaseType.GENERIC
|
||||
);
|
||||
const { closeCreateDiagramDialog } = useCreateDiagramDialog();
|
||||
const { updateConfig } = useConfig();
|
||||
const [scriptResult, setScriptResult] = React.useState('');
|
||||
const [step, setStep] = React.useState<CreateDiagramDialogStep>(
|
||||
CreateDiagramDialogStep.SELECT_DATABASE
|
||||
@@ -48,7 +50,6 @@ export const CreateDiagramDialog: React.FC<CreateDiagramDialogProps> = ({
|
||||
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<CreateDiagramDialogProps> = ({
|
||||
relationships: [],
|
||||
};
|
||||
await addDiagram({ diagram });
|
||||
await updateConfig({ defaultDiagramId: diagram.id });
|
||||
closeCreateDiagramDialog();
|
||||
navigate(`/diagrams/${diagram.id}`);
|
||||
}, [
|
||||
@@ -71,6 +73,7 @@ export const CreateDiagramDialog: React.FC<CreateDiagramDialogProps> = ({
|
||||
addDiagram,
|
||||
closeCreateDiagramDialog,
|
||||
navigate,
|
||||
updateConfig,
|
||||
]);
|
||||
|
||||
const renderDatabaseOption = useCallback((type: DatabaseType) => {
|
||||
|
||||
4
src/hooks/use-config.ts
Normal file
4
src/hooks/use-config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { useContext } from 'react';
|
||||
import { ConfigContext } from '@/context/config-context/config-context';
|
||||
|
||||
export const useConfig = () => useContext(ConfigContext);
|
||||
3
src/lib/domain/config.ts
Normal file
3
src/lib/domain/config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export interface ChartDBConfig {
|
||||
defaultDiagramId: string;
|
||||
}
|
||||
@@ -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 (
|
||||
<section className="bg-background h-screen w-screen flex flex-col">
|
||||
|
||||
@@ -6,12 +6,14 @@ 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: (
|
||||
<DataProvider>
|
||||
<ConfigProvider>
|
||||
<ChartDBProvider>
|
||||
<CreateDiagramDialogProvider>
|
||||
<ReactFlowProvider>
|
||||
@@ -19,6 +21,7 @@ const routes: RouteObject[] = [
|
||||
</ReactFlowProvider>
|
||||
</CreateDiagramDialogProvider>
|
||||
</ChartDBProvider>
|
||||
</ConfigProvider>
|
||||
</DataProvider>
|
||||
),
|
||||
})),
|
||||
|
||||
Reference in New Issue
Block a user