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 { areas, setAreas } = useContext(AreaContext);
const { notes, setNotes } = useContext(NoteContext); const { notes, setNotes } = useContext(NoteContext);
const { settings, setSettings } = useContext(SettingsContext); const { settings, setSettings } = useContext(SettingsContext);
const { redoStack, setUndoStack, setRedoStack } = useContext(UndoRedoContext); const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
const [dragging, setDragging] = useState({ const [dragging, setDragging] = useState({
element: ObjectType.NONE, element: ObjectType.NONE,
id: -1, id: -1,
@ -256,7 +256,7 @@ export default function Canvas(props) {
id: dragging.id, id: dragging.id,
}, },
]); ]);
if (redoStack.length > 0) setRedoStack([]); setRedoStack([]);
} }
setDragging({ element: ObjectType.NONE, id: -1, prevX: 0, prevY: 0 }); setDragging({ element: ObjectType.NONE, id: -1, prevX: 0, prevY: 0 });
setPanning(false); setPanning(false);
@ -288,9 +288,9 @@ export default function Canvas(props) {
line.startFieldId === onRect.field line.startFieldId === onRect.field
) )
return; return;
setRelationships((prev) => [
...prev, setRelationships((prev) => {
{ const newRelationship = {
...line, ...line,
endTableId: onRect.tableId, endTableId: onRect.tableId,
endFieldId: onRect.field, endFieldId: onRect.field,
@ -300,8 +300,18 @@ export default function Canvas(props) {
tables[onRect.tableId].name tables[onRect.tableId].name
}`, }`,
id: prev.length, id: prev.length,
}, };
]); setUndoStack((prevUndo) => [
...prevUndo,
{
action: Action.ADD,
element: ObjectType.RELATIONSHIP,
data: newRelationship,
},
]);
setRedoStack([]);
return [...prev, newRelationship];
});
}; };
const handleMouseWheel = (e) => { const handleMouseWheel = (e) => {

View File

@ -169,6 +169,24 @@ export default function ControlPanel(props) {
setTables((prev) => setTables((prev) =>
prev.map((t) => { prev.map((t) => {
if (t.id === id) { 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 { return {
...t, ...t,
x: x, x: x,
@ -232,6 +250,12 @@ export default function ControlPanel(props) {
.filter((e) => e.id !== prev.length - 1) .filter((e) => e.id !== prev.length - 1)
.map((e, i) => ({ ...e, id: i })) .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]); setRedoStack((prev) => [...prev, a]);
} else if (a.action === Action.MOVE) { } else if (a.action === Action.MOVE) {
@ -254,6 +278,21 @@ export default function ControlPanel(props) {
]); ]);
moveNote(a.id, a.x, a.y); 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(); addArea();
} else if (a.element === ObjectType.NOTE) { } else if (a.element === ObjectType.NOTE) {
addNote(); 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]); setUndoStack((prev) => [...prev, a]);
} else if (a.action === Action.MOVE) { } else if (a.action === Action.MOVE) {
@ -289,6 +334,21 @@ export default function ControlPanel(props) {
]); ]);
moveNote(a.id, a.x, a.y); 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(); overwriteDiagram();
setData(null); setData(null);
setVisible(MODAL.NONE); setVisible(MODAL.NONE);
setUndoStack([]);
setRedoStack([]);
} }
} }
}} }}

View File

@ -22,8 +22,8 @@ import {
IllustrationNoContent, IllustrationNoContent,
IllustrationNoContentDark, IllustrationNoContentDark,
} from "@douyinfe/semi-illustrations"; } from "@douyinfe/semi-illustrations";
import { Cardinality, Constraint } from "../data/data"; import { Action, Cardinality, Constraint, ObjectType } from "../data/data";
import { TableContext } from "../pages/editor"; import { TableContext, UndoRedoContext } from "../pages/editor";
export default function ReferenceOverview(props) { export default function ReferenceOverview(props) {
const columns = [ const columns = [
@ -37,6 +37,7 @@ export default function ReferenceOverview(props) {
}, },
]; ];
const { tables, relationships, setRelationships } = useContext(TableContext); const { tables, relationships, setRelationships } = useContext(TableContext);
const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
const [refActiveIndex, setRefActiveIndex] = useState(""); const [refActiveIndex, setRefActiveIndex] = useState("");
const [value, setValue] = useState(""); const [value, setValue] = useState("");
const [filteredResult, setFilteredResult] = useState( const [filteredResult, setFilteredResult] = useState(
@ -232,13 +233,22 @@ export default function ReferenceOverview(props) {
icon={<IconDeleteStroked />} icon={<IconDeleteStroked />}
block block
type="danger" type="danger"
onClick={() => onClick={() => {
setUndoStack((prev) => [
...prev,
{
action: Action.DELETE,
element: ObjectType.RELATIONSHIP,
data: relationships[i],
},
]);
setRelationships((prev) => setRelationships((prev) =>
prev prev
.filter((e) => e.id !== i) .filter((e) => e.id !== i)
.map((e, idx) => ({ ...e, id: idx })) .map((e, idx) => ({ ...e, id: idx }))
) );
} setRedoStack([]);
}}
> >
Delete Delete
</Button> </Button>

View File

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

View File

@ -1,5 +1,11 @@
import { React, useContext, useState } from "react"; import { React, useContext, useState } from "react";
import { defaultTableTheme, sqlDataTypes, tableThemes } from "../data/data"; import {
defaultTableTheme,
sqlDataTypes,
tableThemes,
Action,
ObjectType,
} from "../data/data";
import { import {
Collapse, Collapse,
Row, Row,
@ -26,12 +32,18 @@ import {
IllustrationNoContent, IllustrationNoContent,
IllustrationNoContentDark, IllustrationNoContentDark,
} from "@douyinfe/semi-illustrations"; } from "@douyinfe/semi-illustrations";
import { TableContext } from "../pages/editor"; import {
SettingsContext,
TableContext,
UndoRedoContext,
} from "../pages/editor";
export default function TableOverview(props) { export default function TableOverview(props) {
const [indexActiveKey, setIndexActiveKey] = useState(""); const [indexActiveKey, setIndexActiveKey] = useState("");
const [value, setValue] = useState(""); const [value, setValue] = useState("");
const { tables, setTables } = useContext(TableContext); const { tables, setTables } = useContext(TableContext);
const { settings } = useContext(SettingsContext);
const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
const [filteredResult, setFilteredResult] = useState( const [filteredResult, setFilteredResult] = useState(
tables.map((t) => { tables.map((t) => {
return t.name; return t.name;
@ -106,31 +118,39 @@ export default function TableOverview(props) {
icon={<IconPlus />} icon={<IconPlus />}
block block
onClick={() => { onClick={() => {
const id = setTables((prev) => [
tables.length === 0 ? 0 : tables[tables.length - 1].id + 1; ...prev,
const newTable = { {
id: id, id: prev.length,
name: `table_${id}`, name: `table_${prev.length}`,
x: 0, x: -settings.pan.x,
y: 0, y: -settings.pan.y,
fields: [ fields: [
{ {
name: "id", name: "id",
type: "UUID", type: "UUID",
default: "", default: "",
check: "", check: "",
primary: true, primary: true,
unique: true, unique: true,
notNull: true, notNull: true,
increment: true, increment: true,
comment: "", comment: "",
}, },
], ],
comment: "", comment: "",
indices: [], indices: [],
color: defaultTableTheme, color: defaultTableTheme,
}; },
setTables((prev) => [...prev, newTable]); ]);
setUndoStack((prev) => [
...prev,
{
action: Action.ADD,
element: ObjectType.TABLE,
},
]);
setRedoStack([]);
}} }}
> >
Add table Add table
@ -550,6 +570,15 @@ export default function TableOverview(props) {
type="danger" type="danger"
onClick={() => { onClick={() => {
Toast.success(`Table deleted!`); Toast.success(`Table deleted!`);
setUndoStack((prev) => [
...prev,
{
action: Action.DELETE,
element: ObjectType.TABLE,
data: tables[i],
},
]);
setRedoStack([]);
setTables((prev) => setTables((prev) =>
prev prev
.filter((e) => e.id !== i) .filter((e) => e.id !== i)

View File

@ -73,12 +73,14 @@ const ObjectType = {
TABLE: 1, TABLE: 1,
AREA: 2, AREA: 2,
NOTE: 3, NOTE: 3,
RELATIONSHIP: 4,
}; };
const Action = { const Action = {
ADD: 0, ADD: 0,
MOVE: 1, MOVE: 1,
} DELETE: 2,
};
export { export {
bgBlue, bgBlue,
@ -91,5 +93,5 @@ export {
Constraint, Constraint,
Tab, Tab,
ObjectType, ObjectType,
Action Action,
}; };