more undo redo

This commit is contained in:
1ilit 2023-09-19 15:49:52 +03:00
parent a030656bcf
commit 39a8dbb315
6 changed files with 154 additions and 52 deletions

View File

@ -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) => {

View File

@ -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([]);
}
}
}}

View File

@ -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={<IconDeleteStroked />}
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
</Button>

View File

@ -7,7 +7,6 @@ import {
} from "../data/data";
import {
IconEdit,
IconPlus,
IconMore,
IconMinus,
IconDeleteStroked,
@ -133,16 +132,6 @@ export default function Table(props) {
}
}}
></Button>
<Button
icon={<IconPlus />}
size="small"
theme="solid"
style={{
backgroundColor: "#3cb558",
opacity: "0.7",
marginRight: "6px",
}}
></Button>
<Popover
content={
<div className="text-slate-600">

View File

@ -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={<IconPlus />}
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)

View File

@ -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,
};