From 39a8dbb315a1b40d4843b37fe8c3c0d451b0a2a9 Mon Sep 17 00:00:00 2001 From: 1ilit Date: Tue, 19 Sep 2023 15:49:52 +0300 Subject: [PATCH] more undo redo --- src/components/canvas.jsx | 24 +++++--- src/components/control_panel.jsx | 62 ++++++++++++++++++++ src/components/reference_overview.jsx | 20 +++++-- src/components/table.jsx | 11 ---- src/components/table_overview.jsx | 83 ++++++++++++++++++--------- src/data/data.js | 6 +- 6 files changed, 154 insertions(+), 52 deletions(-) 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) { } }} > - 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, };