diff --git a/src/components/canvas.jsx b/src/components/canvas.jsx
index 3391b58..d1964e0 100644
--- a/src/components/canvas.jsx
+++ b/src/components/canvas.jsx
@@ -18,7 +18,7 @@ export default function Canvas(props) {
const { areas, setAreas } = useContext(AreaContext);
const { notes, setNotes } = useContext(NoteContext);
const { settings, setSettings } = useContext(SettingsContext);
- const { redoStack, setUndoStack, setRedoStack } = useContext(UndoRedoContext);
+ const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
const [dragging, setDragging] = useState({
element: ObjectType.NONE,
id: -1,
@@ -256,7 +256,7 @@ export default function Canvas(props) {
id: dragging.id,
},
]);
- if (redoStack.length > 0) setRedoStack([]);
+ setRedoStack([]);
}
setDragging({ element: ObjectType.NONE, id: -1, prevX: 0, prevY: 0 });
setPanning(false);
@@ -288,9 +288,9 @@ export default function Canvas(props) {
line.startFieldId === onRect.field
)
return;
- setRelationships((prev) => [
- ...prev,
- {
+
+ setRelationships((prev) => {
+ const newRelationship = {
...line,
endTableId: onRect.tableId,
endFieldId: onRect.field,
@@ -300,8 +300,18 @@ export default function Canvas(props) {
tables[onRect.tableId].name
}`,
id: prev.length,
- },
- ]);
+ };
+ setUndoStack((prevUndo) => [
+ ...prevUndo,
+ {
+ action: Action.ADD,
+ element: ObjectType.RELATIONSHIP,
+ data: newRelationship,
+ },
+ ]);
+ setRedoStack([]);
+ return [...prev, newRelationship];
+ });
};
const handleMouseWheel = (e) => {
diff --git a/src/components/control_panel.jsx b/src/components/control_panel.jsx
index 0899f01..e550a24 100644
--- a/src/components/control_panel.jsx
+++ b/src/components/control_panel.jsx
@@ -169,6 +169,24 @@ export default function ControlPanel(props) {
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,
@@ -232,6 +250,12 @@ export default function ControlPanel(props) {
.filter((e) => e.id !== prev.length - 1)
.map((e, i) => ({ ...e, id: i }))
);
+ } else if (a.element === ObjectType.RELATIONSHIP) {
+ setRelationships((prev) =>
+ prev
+ .filter((e) => e.id !== a.data.id)
+ .map((e, idx) => ({ ...e, id: idx }))
+ );
}
setRedoStack((prev) => [...prev, a]);
} else if (a.action === Action.MOVE) {
@@ -254,6 +278,21 @@ export default function ControlPanel(props) {
]);
moveNote(a.id, a.x, a.y);
}
+ } 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 }));
+ });
+ } 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 }));
+ });
+ }
+ setRedoStack((prev) => [...prev, a]);
}
};
@@ -267,6 +306,12 @@ export default function ControlPanel(props) {
addArea();
} else if (a.element === ObjectType.NOTE) {
addNote();
+ } 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 }));
+ });
}
setUndoStack((prev) => [...prev, a]);
} else if (a.action === Action.MOVE) {
@@ -289,6 +334,21 @@ export default function ControlPanel(props) {
]);
moveNote(a.id, a.x, a.y);
}
+ } 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 }))
+ );
+ } else if (a.element === ObjectType.RELATIONSHIP) {
+ setRelationships((prev) =>
+ prev
+ .filter((t) => t.id !== a.data.id)
+ .map((t, i) => ({ ...t, id: i }))
+ );
+ }
+ setUndoStack((prev) => [...prev, a]);
}
};
@@ -801,6 +861,8 @@ export default function ControlPanel(props) {
overwriteDiagram();
setData(null);
setVisible(MODAL.NONE);
+ setUndoStack([]);
+ setRedoStack([]);
}
}
}}
diff --git a/src/components/reference_overview.jsx b/src/components/reference_overview.jsx
index f2361b8..3123f94 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 { Cardinality, Constraint } from "../data/data";
-import { TableContext } from "../pages/editor";
+import { Action, Cardinality, Constraint, ObjectType } from "../data/data";
+import { TableContext, UndoRedoContext } from "../pages/editor";
export default function ReferenceOverview(props) {
const columns = [
@@ -37,6 +37,7 @@ export default function ReferenceOverview(props) {
},
];
const { tables, relationships, setRelationships } = useContext(TableContext);
+ const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
const [refActiveIndex, setRefActiveIndex] = useState("");
const [value, setValue] = useState("");
const [filteredResult, setFilteredResult] = useState(
@@ -232,13 +233,22 @@ export default function ReferenceOverview(props) {
icon={}
block
type="danger"
- onClick={() =>
+ 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([]);
+ }}
>
Delete
diff --git a/src/components/table.jsx b/src/components/table.jsx
index f6ad52d..1c0e8c8 100644
--- a/src/components/table.jsx
+++ b/src/components/table.jsx
@@ -7,7 +7,6 @@ import {
} from "../data/data";
import {
IconEdit,
- IconPlus,
IconMore,
IconMinus,
IconDeleteStroked,
@@ -133,16 +132,6 @@ export default function Table(props) {
}
}}
>
- }
- size="small"
- theme="solid"
- style={{
- backgroundColor: "#3cb558",
- opacity: "0.7",
- marginRight: "6px",
- }}
- >
diff --git a/src/components/table_overview.jsx b/src/components/table_overview.jsx
index 84b87b8..b878d20 100644
--- a/src/components/table_overview.jsx
+++ b/src/components/table_overview.jsx
@@ -1,5 +1,11 @@
import { React, useContext, useState } from "react";
-import { defaultTableTheme, sqlDataTypes, tableThemes } from "../data/data";
+import {
+ defaultTableTheme,
+ sqlDataTypes,
+ tableThemes,
+ Action,
+ ObjectType,
+} from "../data/data";
import {
Collapse,
Row,
@@ -26,12 +32,18 @@ import {
IllustrationNoContent,
IllustrationNoContentDark,
} from "@douyinfe/semi-illustrations";
-import { TableContext } from "../pages/editor";
+import {
+ SettingsContext,
+ TableContext,
+ UndoRedoContext,
+} 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 [filteredResult, setFilteredResult] = useState(
tables.map((t) => {
return t.name;
@@ -106,31 +118,39 @@ export default function TableOverview(props) {
icon={}
block
onClick={() => {
- const id =
- tables.length === 0 ? 0 : tables[tables.length - 1].id + 1;
- const newTable = {
- id: id,
- name: `table_${id}`,
- x: 0,
- y: 0,
- fields: [
- {
- name: "id",
- type: "UUID",
- default: "",
- check: "",
- primary: true,
- unique: true,
- notNull: true,
- increment: true,
- comment: "",
- },
- ],
- comment: "",
- indices: [],
- color: defaultTableTheme,
- };
- setTables((prev) => [...prev, newTable]);
+ 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([]);
}}
>
Add table
@@ -550,6 +570,15 @@ 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)
diff --git a/src/data/data.js b/src/data/data.js
index 43e3c7a..d0a1726 100644
--- a/src/data/data.js
+++ b/src/data/data.js
@@ -73,12 +73,14 @@ const ObjectType = {
TABLE: 1,
AREA: 2,
NOTE: 3,
+ RELATIONSHIP: 4,
};
const Action = {
ADD: 0,
MOVE: 1,
-}
+ DELETE: 2,
+};
export {
bgBlue,
@@ -91,5 +93,5 @@ export {
Constraint,
Tab,
ObjectType,
- Action
+ Action,
};