diff --git a/src/components/area.jsx b/src/components/area.jsx
index 3356c3a..e96abd0 100644
--- a/src/components/area.jsx
+++ b/src/components/area.jsx
@@ -16,8 +16,8 @@ export default function Area(props) {
y: props.areaData.y,
width: props.areaData.width,
height: props.areaData.height,
- mouseX: e.clientX/props.zoom,
- mouseY: e.clientY/props.zoom,
+ mouseX: e.clientX / props.zoom,
+ mouseY: e.clientY / props.zoom,
});
};
diff --git a/src/components/area_overview.jsx b/src/components/area_overview.jsx
index 566606a..1c10b96 100644
--- a/src/components/area_overview.jsx
+++ b/src/components/area_overview.jsx
@@ -23,7 +23,7 @@ import { defaultTableTheme, tableThemes } from "../data/data";
import { AreaContext } from "../pages/editor";
export default function AreaOverview(props) {
- const { areas, setAreas } = useContext(AreaContext);
+ const { areas, setAreas, addArea, deleteArea } = useContext(AreaContext);
const [value, setValue] = useState("");
const [filteredResult, setFilteredResult] = useState(
@@ -79,22 +79,7 @@ export default function AreaOverview(props) {
/>
- }
- block
- onClick={() => {
- const newArea = {
- id: areas.length,
- name: `area_${areas.length}`,
- x: 0,
- y: 0,
- width: 200,
- height: 200,
- color: defaultTableTheme,
- };
- setAreas((prev) => [...prev, newArea]);
- }}
- >
+ } block onClick={() => addArea()}>
Add area
@@ -208,13 +193,8 @@ export default function AreaOverview(props) {
onClick={(e) => {
e.stopPropagation();
Toast.success(`Area deleted!`);
- setAreas((prev) =>
- prev
- .filter((e) => e.id !== i)
- .map((e, idx) => ({ ...e, id: idx }))
- );
+ deleteArea(i, true);
}}
- // className="delete-button"
>
diff --git a/src/components/canvas.jsx b/src/components/canvas.jsx
index d1964e0..e9f482b 100644
--- a/src/components/canvas.jsx
+++ b/src/components/canvas.jsx
@@ -13,10 +13,10 @@ import {
import Note from "./note";
export default function Canvas(props) {
- const { tables, setTables, relationships, setRelationships } =
+ const { tables, moveTable, relationships, addRelationship } =
useContext(TableContext);
- const { areas, setAreas } = useContext(AreaContext);
- const { notes, setNotes } = useContext(NoteContext);
+ const { areas, setAreas, moveArea } = useContext(AreaContext);
+ const { notes, moveNote } = useContext(NoteContext);
const { settings, setSettings } = useContext(SettingsContext);
const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
const [dragging, setDragging] = useState({
@@ -126,66 +126,21 @@ export default function Canvas(props) {
}));
setPanOffset({ x: e.clientX, y: e.clientY });
} else if (dragging.element === ObjectType.TABLE && dragging.id >= 0) {
- const updatedTables = tables.map((t) => {
- if (t.id === dragging.id) {
- return {
- ...t,
- x: e.clientX / settings.zoom - offset.x,
- y: e.clientY / settings.zoom - offset.y,
- };
- }
- return t;
- });
- setTables(updatedTables);
- setRelationships((prev) =>
- prev.map((r) => {
- if (r.startTableId === dragging.id) {
- return {
- ...r,
- startX: tables[r.startTableId].x + 15,
- startY: tables[r.startTableId].y + r.startFieldId * 36 + 50 + 19,
- };
- } else if (r.endTableId === dragging.id) {
- return {
- ...r,
- endX: tables[r.endTableId].x + 15,
- endY: tables[r.endTableId].y + r.endFieldId * 36 + 50 + 19,
- };
- }
- return r;
- })
- );
+ const dx = e.clientX / settings.zoom - offset.x;
+ const dy = e.clientY / settings.zoom - offset.y;
+ moveTable(dragging.id, dx, dy);
} else if (
dragging.element === ObjectType.AREA &&
dragging.id >= 0 &&
areaResize.id === -1
) {
- setAreas((prev) =>
- prev.map((t) => {
- if (t.id === dragging.id) {
- const updatedArea = {
- ...t,
- x: e.clientX / settings.zoom - offset.x,
- y: e.clientY / settings.zoom - offset.y,
- };
- return updatedArea;
- }
- return t;
- })
- );
+ const dx = e.clientX / settings.zoom - offset.x;
+ const dy = e.clientY / settings.zoom - offset.y;
+ moveArea(dragging.id, dx, dy);
} else if (dragging.element === ObjectType.NOTE && dragging.id >= 0) {
- setNotes((prev) =>
- prev.map((t) => {
- if (t.id === dragging.id) {
- return {
- ...t,
- x: e.clientX / settings.zoom - offset.x,
- y: e.clientY / settings.zoom - offset.y,
- };
- }
- return t;
- })
- );
+ const dx = e.clientX / settings.zoom - offset.x;
+ const dy = e.clientY / settings.zoom - offset.y;
+ moveNote(dragging.id, dx, dy);
} else if (areaResize.id !== -1) {
if (areaResize.dir === "none") return;
@@ -237,15 +192,30 @@ export default function Canvas(props) {
setCursor("grabbing");
};
- const coordsDidUpdate = () => {
- return !(
- dragging.prevX === tables[dragging.id].x &&
- dragging.prevY === tables[dragging.id].y
- );
+ const coordsDidUpdate = (element) => {
+ switch (element) {
+ case ObjectType.TABLE:
+ return !(
+ dragging.prevX === tables[dragging.id].x &&
+ dragging.prevY === tables[dragging.id].y
+ );
+ case ObjectType.AREA:
+ return !(
+ dragging.prevX === areas[dragging.id].x &&
+ dragging.prevY === areas[dragging.id].y
+ );
+ case ObjectType.NOTE:
+ return !(
+ dragging.prevX === notes[dragging.id].x &&
+ dragging.prevY === notes[dragging.id].y
+ );
+ default:
+ return false;
+ }
};
const handleMouseUp = (e) => {
- if (dragging.element !== ObjectType.NONE && coordsDidUpdate()) {
+ if (coordsDidUpdate(dragging.element)) {
setUndoStack((prev) => [
...prev,
{
@@ -289,38 +259,25 @@ export default function Canvas(props) {
)
return;
- setRelationships((prev) => {
- const newRelationship = {
- ...line,
- endTableId: onRect.tableId,
- endFieldId: onRect.field,
- endX: tables[onRect.tableId].x + 15,
- endY: tables[onRect.tableId].y + onRect.field * 36 + 50 + 19,
- name: `${tables[line.startTableId].name}_to_${
- tables[onRect.tableId].name
- }`,
- id: prev.length,
- };
- setUndoStack((prevUndo) => [
- ...prevUndo,
- {
- action: Action.ADD,
- element: ObjectType.RELATIONSHIP,
- data: newRelationship,
- },
- ]);
- setRedoStack([]);
- return [...prev, newRelationship];
+ addRelationship(true, {
+ ...line,
+ endTableId: onRect.tableId,
+ endFieldId: onRect.field,
+ endX: tables[onRect.tableId].x + 15,
+ endY: tables[onRect.tableId].y + onRect.field * 36 + 69,
+ name: `${tables[line.startTableId].name}_to_${
+ tables[onRect.tableId].name
+ }`,
+ id: relationships.length,
});
};
const handleMouseWheel = (e) => {
e.preventDefault();
- if (e.deltaY <= 0) {
- setSettings((prev) => ({ ...prev, zoom: prev.zoom * 1.05 }));
- } else {
- setSettings((prev) => ({ ...prev, zoom: prev.zoom / 1.05 }));
- }
+ setSettings((prev) => ({
+ ...prev,
+ zoom: e.deltaY <= 0 ? prev.zoom * 1.05 : prev.zoom / 1.05,
+ }));
};
useEffect(() => {
diff --git a/src/components/control_panel.jsx b/src/components/control_panel.jsx
index e550a24..56d96c6 100644
--- a/src/components/control_panel.jsx
+++ b/src/components/control_panel.jsx
@@ -45,12 +45,7 @@ import {
UndoRedoContext,
} from "../pages/editor";
import { IconAddTable, IconAddArea, IconAddNote } from "./custom_icons";
-import {
- defaultTableTheme,
- defaultNoteTheme,
- ObjectType,
- Action,
-} from "../data/data";
+import { ObjectType, Action } from "../data/data";
import CodeMirror from "@uiw/react-codemirror";
import { json } from "@codemirror/lang-json";
import jsPDF from "jspdf";
@@ -62,7 +57,7 @@ export default function ControlPanel(props) {
CODE: 2,
IMPORT: 3,
};
- const ERROR = {
+ const STATUS = {
NONE: 0,
WARNING: 1,
ERROR: 2,
@@ -75,16 +70,27 @@ export default function ControlPanel(props) {
extension: "",
});
const [error, setError] = useState({
- type: ERROR.NONE,
+ type: STATUS.NONE,
message: "",
});
const [data, setData] = useState(null);
const { layout, setLayout } = useContext(LayoutContext);
const { settings, setSettings } = useContext(SettingsContext);
- const { relationships, tables, setTables, setRelationships } =
- useContext(TableContext);
- const { notes, setNotes } = useContext(NoteContext);
- const { areas, setAreas } = useContext(AreaContext);
+ const {
+ relationships,
+ tables,
+ setTables,
+ addTable,
+ moveTable,
+ deleteTable,
+ setRelationships,
+ addRelationship,
+ deleteRelationship,
+ } = useContext(TableContext);
+ const { notes, setNotes, moveNote, addNote, deleteNote } =
+ useContext(NoteContext);
+ const { areas, setAreas, moveArea, addArea, deleteArea } =
+ useContext(AreaContext);
const { undoStack, redoStack, setUndoStack, setRedoStack } =
useContext(UndoRedoContext);
@@ -107,155 +113,18 @@ export default function ControlPanel(props) {
setNotes(data.notes);
};
- const addTable = () => {
- setTables((prev) => [
- ...prev,
- {
- id: prev.length,
- name: `table_${prev.length}`,
- x: -settings.pan.x,
- y: -settings.pan.y,
- fields: [
- {
- name: "id",
- type: "UUID",
- default: "",
- check: "",
- primary: true,
- unique: true,
- notNull: true,
- increment: true,
- comment: "",
- },
- ],
- comment: "",
- indices: [],
- color: defaultTableTheme,
- },
- ]);
- };
-
- const addArea = () => {
- setAreas((prev) => [
- ...prev,
- {
- id: prev.length,
- name: `area_${prev.length}`,
- x: -settings.pan.x,
- y: -settings.pan.y,
- width: 200,
- height: 200,
- color: defaultTableTheme,
- },
- ]);
- };
-
- const addNote = () => {
- setNotes((prev) => [
- ...prev,
- {
- id: prev.length,
- x: -settings.pan.x,
- y: -settings.pan.y,
- title: `note_${prev.length}`,
- content: "",
- color: defaultNoteTheme,
- height: 88,
- },
- ]);
- };
-
- const moveTable = (id, x, y) => {
- setTables((prev) =>
- prev.map((t) => {
- if (t.id === id) {
- setRelationships((prev) =>
- prev.map((r) => {
- if (r.startTableId === id) {
- return {
- ...r,
- startX: x + 15,
- startY: y + r.startFieldId * 36 + 69,
- };
- } else if (r.endTableId === id) {
- return {
- ...r,
- endX: x + 15,
- endY: y + r.endFieldId * 36 + 69,
- };
- }
- return r;
- })
- );
- return {
- ...t,
- x: x,
- y: y,
- };
- }
- return t;
- })
- );
- };
-
- const moveArea = (id, x, y) => {
- setAreas((prev) =>
- prev.map((t) => {
- if (t.id === id) {
- return {
- ...t,
- x: x,
- y: y,
- };
- }
- return t;
- })
- );
- };
-
- const moveNote = (id, x, y) => {
- setNotes((prev) =>
- prev.map((t) => {
- if (t.id === id) {
- return {
- ...t,
- x: x,
- y: y,
- };
- }
- return t;
- })
- );
- };
-
const undo = () => {
if (undoStack.length === 0) return;
const a = undoStack.pop();
if (a.action === Action.ADD) {
if (a.element === ObjectType.TABLE) {
- setTables((prev) =>
- prev
- .filter((e) => e.id !== prev.length - 1)
- .map((e, i) => ({ ...e, id: i }))
- );
+ deleteTable(tables[tables.length - 1].id, false);
} else if (a.element === ObjectType.AREA) {
- setAreas((prev) =>
- prev
- .filter((e) => e.id !== prev.length - 1)
- .map((e, i) => ({ ...e, id: i }))
- );
+ deleteArea(areas[areas.length - 1].id, false);
} else if (a.element === ObjectType.NOTE) {
- setNotes((prev) =>
- prev
- .filter((e) => e.id !== prev.length - 1)
- .map((e, i) => ({ ...e, id: i }))
- );
+ deleteNote(notes[notes.length - 1].id, false);
} else if (a.element === ObjectType.RELATIONSHIP) {
- setRelationships((prev) =>
- prev
- .filter((e) => e.id !== a.data.id)
- .map((e, idx) => ({ ...e, id: idx }))
- );
+ deleteRelationship(a.data.id, false);
}
setRedoStack((prev) => [...prev, a]);
} else if (a.action === Action.MOVE) {
@@ -280,17 +149,13 @@ export default function ControlPanel(props) {
}
} else if (a.action === Action.DELETE) {
if (a.element === ObjectType.TABLE) {
- setTables((prev) => {
- const temp = prev.slice();
- temp.splice(a.data.id, 0, a.data);
- return temp.map((t, i) => ({ ...t, id: i }));
- });
+ addTable(false, a.data);
} else if (a.element === ObjectType.RELATIONSHIP) {
- setRelationships((prev) => {
- const temp = prev.slice();
- temp.splice(a.data.id, 0, a.data);
- return temp.map((t, i) => ({ ...t, id: i }));
- });
+ addRelationship(false, a.data);
+ } else if (a.element === ObjectType.NOTE) {
+ addNote(false, a.data);
+ } else if (a.element === ObjectType.AREA) {
+ addArea(false, a.data);
}
setRedoStack((prev) => [...prev, a]);
}
@@ -301,17 +166,13 @@ export default function ControlPanel(props) {
const a = redoStack.pop();
if (a.action === Action.ADD) {
if (a.element === ObjectType.TABLE) {
- addTable();
+ addTable(false);
} else if (a.element === ObjectType.AREA) {
- addArea();
+ addArea(false);
} else if (a.element === ObjectType.NOTE) {
- addNote();
+ addNote(false);
} else if (a.element === ObjectType.RELATIONSHIP) {
- setRelationships((prev) => {
- const temp = prev.slice();
- temp.splice(a.data.id, 0, a.data);
- return temp.map((t, i) => ({ ...t, id: i }));
- });
+ addRelationship(false, a.data);
}
setUndoStack((prev) => [...prev, a]);
} else if (a.action === Action.MOVE) {
@@ -336,17 +197,13 @@ export default function ControlPanel(props) {
}
} else if (a.action === Action.DELETE) {
if (a.element === ObjectType.TABLE) {
- setTables((prev) =>
- prev
- .filter((t) => t.id !== a.data.id)
- .map((t, i) => ({ ...t, id: i }))
- );
+ deleteTable(a.data.id, false);
} else if (a.element === ObjectType.RELATIONSHIP) {
- setRelationships((prev) =>
- prev
- .filter((t) => t.id !== a.data.id)
- .map((t, i) => ({ ...t, id: i }))
- );
+ deleteRelationship(a.data.id, false);
+ } else if (a.element === ObjectType.NOTE) {
+ deleteNote(a.data.id, false);
+ } else if (a.element === ObjectType.AREA) {
+ deleteArea(a.data.id, false);
}
setUndoStack((prev) => [...prev, a]);
}
@@ -772,51 +629,21 @@ export default function ControlPanel(props) {
@@ -856,7 +683,7 @@ export default function ControlPanel(props) {
});
saveAs(blob, `${exportData.filename}.${exportData.extension}`);
} else if (visible === MODAL.IMPORT) {
- if (error.type !== ERROR.ERROR) {
+ if (error.type !== STATUS.ERROR) {
setSettings((prev) => ({ ...prev, pan: { x: 0, y: 0 } }));
overwriteDiagram();
setData(null);
@@ -873,7 +700,7 @@ export default function ControlPanel(props) {
filename: `diagram_${new Date().toISOString()}`,
}));
setError({
- type: ERROR.NONE,
+ type: STATUS.NONE,
message: "",
});
setData(null);
@@ -885,7 +712,7 @@ export default function ControlPanel(props) {
okButtonProps={{
disabled:
(visible === MODAL.IMPORT &&
- (error.type === ERROR.ERROR || !data)) ||
+ (error.type === STATUS.ERROR || !data)) ||
((visible === MODAL.IMG || visible === MODAL.CODE) &&
!exportData.data),
}}
@@ -909,7 +736,7 @@ export default function ControlPanel(props) {
jsonObject = JSON.parse(event.target.result);
} catch (error) {
setError({
- type: ERROR.ERROR,
+ type: STATUS.ERROR,
message: "The file contains an error.",
});
return;
@@ -917,7 +744,7 @@ export default function ControlPanel(props) {
if (f.type === "application/json") {
if (!jsonDiagramIsValid(jsonObject)) {
setError({
- type: ERROR.ERROR,
+ type: STATUS.ERROR,
message:
"The file is missing necessary properties for a diagram.",
});
@@ -926,7 +753,7 @@ export default function ControlPanel(props) {
} else if (f.name.split(".").pop() === "ddb") {
if (!ddbDiagramIsValid(jsonObject)) {
setError({
- type: ERROR.ERROR,
+ type: STATUS.ERROR,
message:
"The file is missing necessary properties for a diagram.",
});
@@ -936,12 +763,12 @@ export default function ControlPanel(props) {
setData(jsonObject);
if (diagramIsEmpty()) {
setError({
- type: ERROR.OK,
+ type: STATUS.OK,
message: "Everything looks good. You can now import.",
});
} else {
setError({
- type: ERROR.WARNING,
+ type: STATUS.WARNING,
message:
"The current diagram is not empty. Importing a new diagram will overwrite the current changes.",
});
@@ -962,19 +789,19 @@ export default function ControlPanel(props) {
accept="application/json,.ddb"
onRemove={() =>
setError({
- type: ERROR.NONE,
+ type: STATUS.NONE,
message: "",
})
}
onFileChange={() =>
setError({
- type: ERROR.NONE,
+ type: STATUS.NONE,
message: "",
})
}
limit={1}
>
- {error.type === ERROR.ERROR ? (
+ {error.type === STATUS.ERROR ? (
{error.message}
}
/>
- ) : error.type === ERROR.OK ? (
+ ) : error.type === STATUS.OK ? (
{error.message}}
/>
) : (
- error.type === ERROR.WARNING && (
+ error.type === STATUS.WARNING && (
- }
- block
- onClick={() => {
- const newNote = {
- id: notes.length,
- x: 0,
- y: 0,
- title: `note_${notes.length}`,
- content: "",
- color: defaultNoteTheme,
- height: 88,
- };
- setNotes((prev) => [...prev, newNote]);
- }}
- >
+ } block onClick={() => addNote()}>
Add note
@@ -189,11 +174,7 @@ export default function NotesOverview(props) {
type="danger"
onClick={() => {
Toast.success(`Note deleted!`);
- setNotes((prev) =>
- prev
- .filter((e) => e.id !== i)
- .map((e, idx) => ({ ...e, id: idx }))
- );
+ deleteNote(i, true);
}}
>
diff --git a/src/components/reference_overview.jsx b/src/components/reference_overview.jsx
index 3123f94..c918a47 100644
--- a/src/components/reference_overview.jsx
+++ b/src/components/reference_overview.jsx
@@ -22,8 +22,8 @@ import {
IllustrationNoContent,
IllustrationNoContentDark,
} from "@douyinfe/semi-illustrations";
-import { Action, Cardinality, Constraint, ObjectType } from "../data/data";
-import { TableContext, UndoRedoContext } from "../pages/editor";
+import { Cardinality, Constraint } from "../data/data";
+import { TableContext } from "../pages/editor";
export default function ReferenceOverview(props) {
const columns = [
@@ -36,8 +36,8 @@ export default function ReferenceOverview(props) {
dataIndex: "foreign",
},
];
- const { tables, relationships, setRelationships } = useContext(TableContext);
- const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
+ const { tables, relationships, setRelationships, deleteRelationship } =
+ useContext(TableContext);
const [refActiveIndex, setRefActiveIndex] = useState("");
const [value, setValue] = useState("");
const [filteredResult, setFilteredResult] = useState(
@@ -233,22 +233,7 @@ export default function ReferenceOverview(props) {
icon={}
block
type="danger"
- onClick={() => {
- setUndoStack((prev) => [
- ...prev,
- {
- action: Action.DELETE,
- element: ObjectType.RELATIONSHIP,
- data: relationships[i],
- },
- ]);
- setRelationships((prev) =>
- prev
- .filter((e) => e.id !== i)
- .map((e, idx) => ({ ...e, id: idx }))
- );
- setRedoStack([]);
- }}
+ onClick={() => deleteRelationship(r.id, true)}
>
Delete
diff --git a/src/components/table.jsx b/src/components/table.jsx
index 1c0e8c8..148db62 100644
--- a/src/components/table.jsx
+++ b/src/components/table.jsx
@@ -40,7 +40,7 @@ export default function Table(props) {
const [hoveredField, setHoveredField] = useState(-1);
const [visible, setVisible] = useState(false);
const { layout } = useContext(LayoutContext);
- const { setTables } = useContext(TableContext);
+ const { setTables, deleteTable } = useContext(TableContext);
const { tab, setTab } = useContext(TabContext);
const { settings } = useContext(SettingsContext);
@@ -180,11 +180,7 @@ export default function Table(props) {
style={{ marginTop: "8px" }}
onClick={() => {
Toast.success(`Table deleted!`);
- setTables((prev) =>
- prev
- .filter((e) => e.id !== props.tableData.id)
- .map((e, idx) => ({ ...e, id: idx }))
- );
+ deleteTable(props.tableData.id);
props.setSelectedTable("");
}}
>
@@ -683,11 +679,7 @@ export default function Table(props) {
type="danger"
onClick={() => {
Toast.success(`Table deleted!`);
- setTables((prev) =>
- prev
- .filter((e) => e.id !== props.tableData.id)
- .map((e, idx) => ({ ...e, id: idx }))
- );
+ deleteTable(props.tableData.id);
props.setSelectedTable("");
setVisible(false);
}}
diff --git a/src/components/table_overview.jsx b/src/components/table_overview.jsx
index b878d20..67b8350 100644
--- a/src/components/table_overview.jsx
+++ b/src/components/table_overview.jsx
@@ -1,11 +1,5 @@
import { React, useContext, useState } from "react";
-import {
- defaultTableTheme,
- sqlDataTypes,
- tableThemes,
- Action,
- ObjectType,
-} from "../data/data";
+import { defaultTableTheme, sqlDataTypes, tableThemes } from "../data/data";
import {
Collapse,
Row,
@@ -32,18 +26,12 @@ import {
IllustrationNoContent,
IllustrationNoContentDark,
} from "@douyinfe/semi-illustrations";
-import {
- SettingsContext,
- TableContext,
- UndoRedoContext,
-} from "../pages/editor";
+import { TableContext } from "../pages/editor";
export default function TableOverview(props) {
const [indexActiveKey, setIndexActiveKey] = useState("");
const [value, setValue] = useState("");
- const { tables, setTables } = useContext(TableContext);
- const { settings } = useContext(SettingsContext);
- const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
+ const { tables, setTables, addTable, deleteTable } = useContext(TableContext);
const [filteredResult, setFilteredResult] = useState(
tables.map((t) => {
return t.name;
@@ -118,39 +106,7 @@ export default function TableOverview(props) {
icon={}
block
onClick={() => {
- setTables((prev) => [
- ...prev,
- {
- id: prev.length,
- name: `table_${prev.length}`,
- x: -settings.pan.x,
- y: -settings.pan.y,
- fields: [
- {
- name: "id",
- type: "UUID",
- default: "",
- check: "",
- primary: true,
- unique: true,
- notNull: true,
- increment: true,
- comment: "",
- },
- ],
- comment: "",
- indices: [],
- color: defaultTableTheme,
- },
- ]);
- setUndoStack((prev) => [
- ...prev,
- {
- action: Action.ADD,
- element: ObjectType.TABLE,
- },
- ]);
- setRedoStack([]);
+ addTable(true);
}}
>
Add table
@@ -570,20 +526,7 @@ export default function TableOverview(props) {
type="danger"
onClick={() => {
Toast.success(`Table deleted!`);
- setUndoStack((prev) => [
- ...prev,
- {
- action: Action.DELETE,
- element: ObjectType.TABLE,
- data: tables[i],
- },
- ]);
- setRedoStack([]);
- setTables((prev) =>
- prev
- .filter((e) => e.id !== i)
- .map((e, idx) => ({ ...e, id: idx }))
- );
+ deleteTable(i);
props.setSelectedTable("");
}}
>
diff --git a/src/pages/editor.jsx b/src/pages/editor.jsx
index a4180a2..9bd063e 100644
--- a/src/pages/editor.jsx
+++ b/src/pages/editor.jsx
@@ -5,7 +5,13 @@ import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import Canvas from "../components/canvas";
import EditorPanel from "../components/editor_panel";
-import { Tab } from "../data/data";
+import {
+ Tab,
+ defaultTableTheme,
+ defaultNoteTheme,
+ Action,
+ ObjectType,
+} from "../data/data";
export const LayoutContext = createContext();
export const TableContext = createContext();
@@ -41,7 +47,7 @@ export default function Editor(props) {
strictMode: false,
showFieldSummary: true,
zoom: 1,
- pan: {x: 0, y: 0},
+ pan: { x: 0, y: 0 },
showGrid: true,
});
const [undoStack, setUndoStack] = useState([]);
@@ -53,17 +59,297 @@ export default function Editor(props) {
if (w > 340) setWidth(w);
};
+ const addTable = (addToHistory = true, data) => {
+ if (data) {
+ setTables((prev) => {
+ const temp = prev.slice();
+ temp.splice(data.id, 0, data);
+ return temp.map((t, i) => ({ ...t, id: i }));
+ });
+ } else {
+ setTables((prev) => [
+ ...prev,
+ {
+ id: prev.length,
+ name: `table_${prev.length}`,
+ x: -settings.pan.x,
+ y: -settings.pan.y,
+ fields: [
+ {
+ name: "id",
+ type: "UUID",
+ default: "",
+ check: "",
+ primary: true,
+ unique: true,
+ notNull: true,
+ increment: true,
+ comment: "",
+ },
+ ],
+ comment: "",
+ indices: [],
+ color: defaultTableTheme,
+ },
+ ]);
+ }
+ if (addToHistory) {
+ setUndoStack((prev) => [
+ ...prev,
+ {
+ action: Action.ADD,
+ element: ObjectType.TABLE,
+ },
+ ]);
+ setRedoStack([]);
+ }
+ };
+
+ const addArea = (addToHistory = true, data) => {
+ if (data) {
+ setAreas((prev) => {
+ const temp = prev.slice();
+ temp.splice(data.id, 0, data);
+ return temp.map((t, i) => ({ ...t, id: i }));
+ });
+ } else {
+ setAreas((prev) => [
+ ...prev,
+ {
+ id: prev.length,
+ name: `area_${prev.length}`,
+ x: -settings.pan.x,
+ y: -settings.pan.y,
+ width: 200,
+ height: 200,
+ color: defaultTableTheme,
+ },
+ ]);
+ }
+ if (addToHistory) {
+ setUndoStack((prev) => [
+ ...prev,
+ {
+ action: Action.ADD,
+ element: ObjectType.AREA,
+ },
+ ]);
+ setRedoStack([]);
+ }
+ };
+
+ const addNote = (addToHistory = true, data) => {
+ if (data) {
+ setNotes((prev) => {
+ const temp = prev.slice();
+ temp.splice(data.id, 0, data);
+ return temp.map((t, i) => ({ ...t, id: i }));
+ });
+ } else {
+ setNotes((prev) => [
+ ...prev,
+ {
+ id: prev.length,
+ x: -settings.pan.x,
+ y: -settings.pan.y,
+ title: `note_${prev.length}`,
+ content: "",
+ color: defaultNoteTheme,
+ height: 88,
+ },
+ ]);
+ }
+ if (addToHistory) {
+ setUndoStack((prev) => [
+ ...prev,
+ {
+ action: Action.ADD,
+ element: ObjectType.NOTE,
+ },
+ ]);
+ setRedoStack([]);
+ }
+ };
+
+ const addRelationship = (addToHistory = true, data) => {
+ if (addToHistory) {
+ setRelationships((prev) => {
+ setUndoStack((prevUndo) => [
+ ...prevUndo,
+ {
+ action: Action.ADD,
+ element: ObjectType.RELATIONSHIP,
+ data: data,
+ },
+ ]);
+ setRedoStack([]);
+ return [...prev, data];
+ });
+ } else {
+ setRelationships((prev) => {
+ const temp = prev.slice();
+ temp.splice(data.id, 0, data);
+ return temp.map((t, i) => ({ ...t, id: i }));
+ });
+ }
+ };
+
+ const moveTable = (id, x, y) => {
+ setTables((prev) =>
+ prev.map((t) => {
+ if (t.id === id) {
+ setRelationships((prev) =>
+ prev.map((r) => {
+ if (r.startTableId === id) {
+ return {
+ ...r,
+ startX: x + 15,
+ startY: y + r.startFieldId * 36 + 69,
+ };
+ } else if (r.endTableId === id) {
+ return {
+ ...r,
+ endX: x + 15,
+ endY: y + r.endFieldId * 36 + 69,
+ };
+ }
+ return r;
+ })
+ );
+ return {
+ ...t,
+ x: x,
+ y: y,
+ };
+ }
+ return t;
+ })
+ );
+ };
+
+ const moveArea = (id, x, y) => {
+ setAreas((prev) =>
+ prev.map((t) => {
+ if (t.id === id) {
+ return {
+ ...t,
+ x: x,
+ y: y,
+ };
+ }
+ return t;
+ })
+ );
+ };
+
+ const moveNote = (id, x, y) => {
+ setNotes((prev) =>
+ prev.map((t) => {
+ if (t.id === id) {
+ return {
+ ...t,
+ x: x,
+ y: y,
+ };
+ }
+ return t;
+ })
+ );
+ };
+
+ const deleteTable = (id, addToHistory = true) => {
+ if (addToHistory) {
+ setUndoStack((prev) => [
+ ...prev,
+ {
+ action: Action.DELETE,
+ element: ObjectType.TABLE,
+ data: tables[id],
+ },
+ ]);
+ setRedoStack([]);
+ }
+ setTables((prev) =>
+ prev.filter((e) => e.id !== id).map((e, i) => ({ ...e, id: i }))
+ );
+ };
+
+ const deleteArea = (id, addToHistory = true) => {
+ if (addToHistory) {
+ setUndoStack((prev) => [
+ ...prev,
+ {
+ action: Action.DELETE,
+ element: ObjectType.AREA,
+ data: areas[id],
+ },
+ ]);
+ setRedoStack([]);
+ }
+ setAreas((prev) =>
+ prev.filter((e) => e.id !== id).map((e, i) => ({ ...e, id: i }))
+ );
+ };
+
+ const deleteNote = (id, addToHistory = true) => {
+ if (addToHistory) {
+ setUndoStack((prev) => [
+ ...prev,
+ {
+ action: Action.DELETE,
+ element: ObjectType.NOTE,
+ data: notes[id],
+ },
+ ]);
+ setRedoStack([]);
+ }
+ setNotes((prev) =>
+ prev.filter((e) => e.id !== id).map((e, i) => ({ ...e, id: i }))
+ );
+ };
+
+ const deleteRelationship = (id, addToHistory = true) => {
+ if (addToHistory) {
+ setUndoStack((prev) => [
+ ...prev,
+ {
+ action: Action.DELETE,
+ element: ObjectType.RELATIONSHIP,
+ data: relationships[id],
+ },
+ ]);
+ setRedoStack([]);
+ }
+ setRelationships((prev) =>
+ prev.filter((e) => e.id !== id).map((e, i) => ({ ...e, id: i }))
+ );
+ };
+
useEffect(() => {
- document.title = "Editor";
+ document.title = "Editor - drawDB";
}, []);
return (
-
-
+
+