mirror of
https://github.com/chartdb/chartdb.git
synced 2025-11-09 16:36:27 +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 { DBField } from '@/lib/domain/db-field';
|
||||||
import { DBIndex } from '@/lib/domain/db-index';
|
import { DBIndex } from '@/lib/domain/db-index';
|
||||||
import { DBRelationship } from '@/lib/domain/db-relationship';
|
import { DBRelationship } from '@/lib/domain/db-relationship';
|
||||||
|
import { Diagram } from '@/lib/domain/diagram';
|
||||||
|
|
||||||
export interface ChartDBContext {
|
export interface ChartDBContext {
|
||||||
diagramId: string;
|
diagramId: string;
|
||||||
@@ -16,6 +17,7 @@ export interface ChartDBContext {
|
|||||||
// General operations
|
// General operations
|
||||||
updateDiagramId: (id: string) => void;
|
updateDiagramId: (id: string) => void;
|
||||||
updateDiagramName: (name: string) => void;
|
updateDiagramName: (name: string) => void;
|
||||||
|
loadDiagram: (diagramId: string) => Promise<Diagram | null>;
|
||||||
|
|
||||||
// Database type operations
|
// Database type operations
|
||||||
updateDatabaseType: (databaseType: DatabaseType) => void;
|
updateDatabaseType: (databaseType: DatabaseType) => void;
|
||||||
@@ -80,6 +82,7 @@ export const chartDBContext = createContext<ChartDBContext>({
|
|||||||
// General operations
|
// General operations
|
||||||
updateDiagramId: emptyFn,
|
updateDiagramId: emptyFn,
|
||||||
updateDiagramName: emptyFn,
|
updateDiagramName: emptyFn,
|
||||||
|
loadDiagram: emptyFn,
|
||||||
|
|
||||||
// Database type operations
|
// Database type operations
|
||||||
updateDatabaseType: emptyFn,
|
updateDatabaseType: emptyFn,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { DatabaseType } from '@/lib/domain/database-type';
|
|||||||
import { DBField } from '@/lib/domain/db-field';
|
import { DBField } from '@/lib/domain/db-field';
|
||||||
import { DBIndex } from '@/lib/domain/db-index';
|
import { DBIndex } from '@/lib/domain/db-index';
|
||||||
import { DBRelationship } from '@/lib/domain/db-relationship';
|
import { DBRelationship } from '@/lib/domain/db-relationship';
|
||||||
|
import { Diagram } from '@/lib/domain/diagram';
|
||||||
|
|
||||||
export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||||
children,
|
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 (
|
return (
|
||||||
<chartDBContext.Provider
|
<chartDBContext.Provider
|
||||||
value={{
|
value={{
|
||||||
@@ -295,6 +301,7 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
|||||||
relationships,
|
relationships,
|
||||||
updateDiagramId,
|
updateDiagramId,
|
||||||
updateDiagramName,
|
updateDiagramName,
|
||||||
|
loadDiagram,
|
||||||
updateDatabaseType,
|
updateDatabaseType,
|
||||||
createTable,
|
createTable,
|
||||||
addTable,
|
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 { emptyFn } from '@/lib/utils';
|
||||||
import { DBRelationship } from '@/lib/domain/db-relationship';
|
import { DBRelationship } from '@/lib/domain/db-relationship';
|
||||||
import { DBTable } from '@/lib/domain/db-table';
|
import { DBTable } from '@/lib/domain/db-table';
|
||||||
|
import { ChartDBConfig } from '@/lib/domain/config';
|
||||||
|
|
||||||
export interface DataContext {
|
export interface DataContext {
|
||||||
|
// Config operations
|
||||||
|
getConfig: () => Promise<ChartDBConfig | undefined>;
|
||||||
|
updateConfig: (config: Partial<ChartDBConfig>) => Promise<void>;
|
||||||
|
|
||||||
// Diagram operations
|
// Diagram operations
|
||||||
addDiagram: (params: { diagram: Diagram }) => Promise<void>;
|
addDiagram: (params: { diagram: Diagram }) => Promise<void>;
|
||||||
listDiagrams: () => Promise<Diagram[]>;
|
listDiagrams: () => Promise<Diagram[]>;
|
||||||
@@ -49,6 +54,9 @@ export interface DataContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const dataContext = createContext<DataContext>({
|
export const dataContext = createContext<DataContext>({
|
||||||
|
getConfig: emptyFn,
|
||||||
|
updateConfig: emptyFn,
|
||||||
|
|
||||||
addDiagram: emptyFn,
|
addDiagram: emptyFn,
|
||||||
listDiagrams: emptyFn,
|
listDiagrams: emptyFn,
|
||||||
getDiagram: emptyFn,
|
getDiagram: emptyFn,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import Dexie, { type EntityTable } from 'dexie';
|
|||||||
import { Diagram } from '@/lib/domain/diagram';
|
import { Diagram } from '@/lib/domain/diagram';
|
||||||
import { DBTable } from '@/lib/domain/db-table';
|
import { DBTable } from '@/lib/domain/db-table';
|
||||||
import { DBRelationship } from '@/lib/domain/db-relationship';
|
import { DBRelationship } from '@/lib/domain/db-relationship';
|
||||||
|
import { ChartDBConfig } from '@/lib/domain/config';
|
||||||
|
|
||||||
export const DataProvider: React.FC<React.PropsWithChildren> = ({
|
export const DataProvider: React.FC<React.PropsWithChildren> = ({
|
||||||
children,
|
children,
|
||||||
@@ -21,6 +22,10 @@ export const DataProvider: React.FC<React.PropsWithChildren> = ({
|
|||||||
DBRelationship & { diagramId: string },
|
DBRelationship & { diagramId: string },
|
||||||
'id' // primary key "id" (for the typings only)
|
'id' // primary key "id" (for the typings only)
|
||||||
>;
|
>;
|
||||||
|
config: EntityTable<
|
||||||
|
ChartDBConfig & { id: number },
|
||||||
|
'id' // primary key "id" (for the typings only)
|
||||||
|
>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Schema declaration:
|
// Schema declaration:
|
||||||
@@ -30,8 +35,28 @@ export const DataProvider: React.FC<React.PropsWithChildren> = ({
|
|||||||
'++id, diagramId, name, x, y, fields, indexes, color, createdAt',
|
'++id, diagramId, name, x, y, fields, indexes, color, createdAt',
|
||||||
db_relationships:
|
db_relationships:
|
||||||
'++id, diagramId, name, sourceTableId, targetTableId, sourceFieldId, targetFieldId, type, createdAt',
|
'++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 }) => {
|
const addDiagram = async ({ diagram }: { diagram: Diagram }) => {
|
||||||
await db.diagrams.add(diagram);
|
await db.diagrams.add(diagram);
|
||||||
};
|
};
|
||||||
@@ -167,6 +192,8 @@ export const DataProvider: React.FC<React.PropsWithChildren> = ({
|
|||||||
return (
|
return (
|
||||||
<dataContext.Provider
|
<dataContext.Provider
|
||||||
value={{
|
value={{
|
||||||
|
getConfig,
|
||||||
|
updateConfig,
|
||||||
addDiagram,
|
addDiagram,
|
||||||
listDiagrams,
|
listDiagrams,
|
||||||
getDiagram,
|
getDiagram,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { Diagram } from '@/lib/domain/diagram';
|
|||||||
import { generateId } from '@/lib/utils';
|
import { generateId } from '@/lib/utils';
|
||||||
import { useCreateDiagramDialog } from '@/hooks/use-create-diagram-dialog';
|
import { useCreateDiagramDialog } from '@/hooks/use-create-diagram-dialog';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { useConfig } from '@/hooks/use-config';
|
||||||
|
|
||||||
enum CreateDiagramDialogStep {
|
enum CreateDiagramDialogStep {
|
||||||
SELECT_DATABASE = 'SELECT_DATABASE',
|
SELECT_DATABASE = 'SELECT_DATABASE',
|
||||||
@@ -37,6 +38,7 @@ export const CreateDiagramDialog: React.FC<CreateDiagramDialogProps> = ({
|
|||||||
DatabaseType.GENERIC
|
DatabaseType.GENERIC
|
||||||
);
|
);
|
||||||
const { closeCreateDiagramDialog } = useCreateDiagramDialog();
|
const { closeCreateDiagramDialog } = useCreateDiagramDialog();
|
||||||
|
const { updateConfig } = useConfig();
|
||||||
const [scriptResult, setScriptResult] = React.useState('');
|
const [scriptResult, setScriptResult] = React.useState('');
|
||||||
const [step, setStep] = React.useState<CreateDiagramDialogStep>(
|
const [step, setStep] = React.useState<CreateDiagramDialogStep>(
|
||||||
CreateDiagramDialogStep.SELECT_DATABASE
|
CreateDiagramDialogStep.SELECT_DATABASE
|
||||||
@@ -48,7 +50,6 @@ export const CreateDiagramDialog: React.FC<CreateDiagramDialogProps> = ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchDiagrams = async () => {
|
const fetchDiagrams = async () => {
|
||||||
const diagrams = await listDiagrams();
|
const diagrams = await listDiagrams();
|
||||||
console.log({ diagrams });
|
|
||||||
setDiagramNumber(diagrams.length + 1);
|
setDiagramNumber(diagrams.length + 1);
|
||||||
};
|
};
|
||||||
fetchDiagrams();
|
fetchDiagrams();
|
||||||
@@ -63,6 +64,7 @@ export const CreateDiagramDialog: React.FC<CreateDiagramDialogProps> = ({
|
|||||||
relationships: [],
|
relationships: [],
|
||||||
};
|
};
|
||||||
await addDiagram({ diagram });
|
await addDiagram({ diagram });
|
||||||
|
await updateConfig({ defaultDiagramId: diagram.id });
|
||||||
closeCreateDiagramDialog();
|
closeCreateDiagramDialog();
|
||||||
navigate(`/diagrams/${diagram.id}`);
|
navigate(`/diagrams/${diagram.id}`);
|
||||||
}, [
|
}, [
|
||||||
@@ -71,6 +73,7 @@ export const CreateDiagramDialog: React.FC<CreateDiagramDialogProps> = ({
|
|||||||
addDiagram,
|
addDiagram,
|
||||||
closeCreateDiagramDialog,
|
closeCreateDiagramDialog,
|
||||||
navigate,
|
navigate,
|
||||||
|
updateConfig,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const renderDatabaseOption = useCallback((type: DatabaseType) => {
|
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';
|
} from '@/components/resizable/resizable';
|
||||||
import { SidePanel } from './side-panel/side-panel';
|
import { SidePanel } from './side-panel/side-panel';
|
||||||
import { Canvas } from './canvas/canvas';
|
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 { useCreateDiagramDialog } from '@/hooks/use-create-diagram-dialog';
|
||||||
|
import { useConfig } from '@/hooks/use-config';
|
||||||
|
|
||||||
export const EditorPage: React.FC = () => {
|
export const EditorPage: React.FC = () => {
|
||||||
const { openCreateDiagramDialog } = useCreateDiagramDialog();
|
const { openCreateDiagramDialog } = useCreateDiagramDialog();
|
||||||
const { diagramId } = useParams<{ diagramId: string }>();
|
const { diagramId } = useParams<{ diagramId: string }>();
|
||||||
|
const { config } = useConfig();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
useEffect(() => {
|
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();
|
openCreateDiagramDialog();
|
||||||
}
|
}
|
||||||
}, [diagramId, openCreateDiagramDialog]);
|
}, [diagramId, openCreateDiagramDialog, config, navigate]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="bg-background h-screen w-screen flex flex-col">
|
<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 { ReactFlowProvider } from '@xyflow/react';
|
||||||
import { DataProvider } from './context/data-context/data-provider';
|
import { DataProvider } from './context/data-context/data-provider';
|
||||||
import { CreateDiagramDialogProvider } from './dialogs/create-diagram-dialog/create-diagram-dialog-provider';
|
import { CreateDiagramDialogProvider } from './dialogs/create-diagram-dialog/create-diagram-dialog-provider';
|
||||||
|
import { ConfigProvider } from './context/config-context/config-provider';
|
||||||
|
|
||||||
const routes: RouteObject[] = [
|
const routes: RouteObject[] = [
|
||||||
...['', 'diagrams/:diagramId'].map((path) => ({
|
...['', 'diagrams/:diagramId'].map((path) => ({
|
||||||
path,
|
path,
|
||||||
element: (
|
element: (
|
||||||
<DataProvider>
|
<DataProvider>
|
||||||
|
<ConfigProvider>
|
||||||
<ChartDBProvider>
|
<ChartDBProvider>
|
||||||
<CreateDiagramDialogProvider>
|
<CreateDiagramDialogProvider>
|
||||||
<ReactFlowProvider>
|
<ReactFlowProvider>
|
||||||
@@ -19,6 +21,7 @@ const routes: RouteObject[] = [
|
|||||||
</ReactFlowProvider>
|
</ReactFlowProvider>
|
||||||
</CreateDiagramDialogProvider>
|
</CreateDiagramDialogProvider>
|
||||||
</ChartDBProvider>
|
</ChartDBProvider>
|
||||||
|
</ConfigProvider>
|
||||||
</DataProvider>
|
</DataProvider>
|
||||||
),
|
),
|
||||||
})),
|
})),
|
||||||
|
|||||||
Reference in New Issue
Block a user