Clean up
This commit is contained in:
parent
39a8dbb315
commit
be66cf6e84
@ -16,8 +16,8 @@ export default function Area(props) {
|
|||||||
y: props.areaData.y,
|
y: props.areaData.y,
|
||||||
width: props.areaData.width,
|
width: props.areaData.width,
|
||||||
height: props.areaData.height,
|
height: props.areaData.height,
|
||||||
mouseX: e.clientX/props.zoom,
|
mouseX: e.clientX / props.zoom,
|
||||||
mouseY: e.clientY/props.zoom,
|
mouseY: e.clientY / props.zoom,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import { defaultTableTheme, tableThemes } from "../data/data";
|
|||||||
import { AreaContext } from "../pages/editor";
|
import { AreaContext } from "../pages/editor";
|
||||||
|
|
||||||
export default function AreaOverview(props) {
|
export default function AreaOverview(props) {
|
||||||
const { areas, setAreas } = useContext(AreaContext);
|
const { areas, setAreas, addArea, deleteArea } = useContext(AreaContext);
|
||||||
|
|
||||||
const [value, setValue] = useState("");
|
const [value, setValue] = useState("");
|
||||||
const [filteredResult, setFilteredResult] = useState(
|
const [filteredResult, setFilteredResult] = useState(
|
||||||
@ -79,22 +79,7 @@ export default function AreaOverview(props) {
|
|||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
<Button
|
<Button icon={<IconPlus />} block onClick={() => addArea()}>
|
||||||
icon={<IconPlus />}
|
|
||||||
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]);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Add area
|
Add area
|
||||||
</Button>
|
</Button>
|
||||||
</Col>
|
</Col>
|
||||||
@ -208,13 +193,8 @@ export default function AreaOverview(props) {
|
|||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
Toast.success(`Area deleted!`);
|
Toast.success(`Area deleted!`);
|
||||||
setAreas((prev) =>
|
deleteArea(i, true);
|
||||||
prev
|
|
||||||
.filter((e) => e.id !== i)
|
|
||||||
.map((e, idx) => ({ ...e, id: idx }))
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
// className="delete-button"
|
|
||||||
></Button>
|
></Button>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -13,10 +13,10 @@ import {
|
|||||||
import Note from "./note";
|
import Note from "./note";
|
||||||
|
|
||||||
export default function Canvas(props) {
|
export default function Canvas(props) {
|
||||||
const { tables, setTables, relationships, setRelationships } =
|
const { tables, moveTable, relationships, addRelationship } =
|
||||||
useContext(TableContext);
|
useContext(TableContext);
|
||||||
const { areas, setAreas } = useContext(AreaContext);
|
const { areas, setAreas, moveArea } = useContext(AreaContext);
|
||||||
const { notes, setNotes } = useContext(NoteContext);
|
const { notes, moveNote } = useContext(NoteContext);
|
||||||
const { settings, setSettings } = useContext(SettingsContext);
|
const { settings, setSettings } = useContext(SettingsContext);
|
||||||
const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
|
const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
|
||||||
const [dragging, setDragging] = useState({
|
const [dragging, setDragging] = useState({
|
||||||
@ -126,66 +126,21 @@ export default function Canvas(props) {
|
|||||||
}));
|
}));
|
||||||
setPanOffset({ x: e.clientX, y: e.clientY });
|
setPanOffset({ x: e.clientX, y: e.clientY });
|
||||||
} else if (dragging.element === ObjectType.TABLE && dragging.id >= 0) {
|
} else if (dragging.element === ObjectType.TABLE && dragging.id >= 0) {
|
||||||
const updatedTables = tables.map((t) => {
|
const dx = e.clientX / settings.zoom - offset.x;
|
||||||
if (t.id === dragging.id) {
|
const dy = e.clientY / settings.zoom - offset.y;
|
||||||
return {
|
moveTable(dragging.id, dx, dy);
|
||||||
...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;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} else if (
|
} else if (
|
||||||
dragging.element === ObjectType.AREA &&
|
dragging.element === ObjectType.AREA &&
|
||||||
dragging.id >= 0 &&
|
dragging.id >= 0 &&
|
||||||
areaResize.id === -1
|
areaResize.id === -1
|
||||||
) {
|
) {
|
||||||
setAreas((prev) =>
|
const dx = e.clientX / settings.zoom - offset.x;
|
||||||
prev.map((t) => {
|
const dy = e.clientY / settings.zoom - offset.y;
|
||||||
if (t.id === dragging.id) {
|
moveArea(dragging.id, dx, dy);
|
||||||
const updatedArea = {
|
|
||||||
...t,
|
|
||||||
x: e.clientX / settings.zoom - offset.x,
|
|
||||||
y: e.clientY / settings.zoom - offset.y,
|
|
||||||
};
|
|
||||||
return updatedArea;
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} else if (dragging.element === ObjectType.NOTE && dragging.id >= 0) {
|
} else if (dragging.element === ObjectType.NOTE && dragging.id >= 0) {
|
||||||
setNotes((prev) =>
|
const dx = e.clientX / settings.zoom - offset.x;
|
||||||
prev.map((t) => {
|
const dy = e.clientY / settings.zoom - offset.y;
|
||||||
if (t.id === dragging.id) {
|
moveNote(dragging.id, dx, dy);
|
||||||
return {
|
|
||||||
...t,
|
|
||||||
x: e.clientX / settings.zoom - offset.x,
|
|
||||||
y: e.clientY / settings.zoom - offset.y,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} else if (areaResize.id !== -1) {
|
} else if (areaResize.id !== -1) {
|
||||||
if (areaResize.dir === "none") return;
|
if (areaResize.dir === "none") return;
|
||||||
|
|
||||||
@ -237,15 +192,30 @@ export default function Canvas(props) {
|
|||||||
setCursor("grabbing");
|
setCursor("grabbing");
|
||||||
};
|
};
|
||||||
|
|
||||||
const coordsDidUpdate = () => {
|
const coordsDidUpdate = (element) => {
|
||||||
return !(
|
switch (element) {
|
||||||
dragging.prevX === tables[dragging.id].x &&
|
case ObjectType.TABLE:
|
||||||
dragging.prevY === tables[dragging.id].y
|
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) => {
|
const handleMouseUp = (e) => {
|
||||||
if (dragging.element !== ObjectType.NONE && coordsDidUpdate()) {
|
if (coordsDidUpdate(dragging.element)) {
|
||||||
setUndoStack((prev) => [
|
setUndoStack((prev) => [
|
||||||
...prev,
|
...prev,
|
||||||
{
|
{
|
||||||
@ -289,38 +259,25 @@ export default function Canvas(props) {
|
|||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setRelationships((prev) => {
|
addRelationship(true, {
|
||||||
const newRelationship = {
|
...line,
|
||||||
...line,
|
endTableId: onRect.tableId,
|
||||||
endTableId: onRect.tableId,
|
endFieldId: onRect.field,
|
||||||
endFieldId: onRect.field,
|
endX: tables[onRect.tableId].x + 15,
|
||||||
endX: tables[onRect.tableId].x + 15,
|
endY: tables[onRect.tableId].y + onRect.field * 36 + 69,
|
||||||
endY: tables[onRect.tableId].y + onRect.field * 36 + 50 + 19,
|
name: `${tables[line.startTableId].name}_to_${
|
||||||
name: `${tables[line.startTableId].name}_to_${
|
tables[onRect.tableId].name
|
||||||
tables[onRect.tableId].name
|
}`,
|
||||||
}`,
|
id: relationships.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) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (e.deltaY <= 0) {
|
setSettings((prev) => ({
|
||||||
setSettings((prev) => ({ ...prev, zoom: prev.zoom * 1.05 }));
|
...prev,
|
||||||
} else {
|
zoom: e.deltaY <= 0 ? prev.zoom * 1.05 : prev.zoom / 1.05,
|
||||||
setSettings((prev) => ({ ...prev, zoom: prev.zoom / 1.05 }));
|
}));
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -45,12 +45,7 @@ import {
|
|||||||
UndoRedoContext,
|
UndoRedoContext,
|
||||||
} from "../pages/editor";
|
} from "../pages/editor";
|
||||||
import { IconAddTable, IconAddArea, IconAddNote } from "./custom_icons";
|
import { IconAddTable, IconAddArea, IconAddNote } from "./custom_icons";
|
||||||
import {
|
import { ObjectType, Action } from "../data/data";
|
||||||
defaultTableTheme,
|
|
||||||
defaultNoteTheme,
|
|
||||||
ObjectType,
|
|
||||||
Action,
|
|
||||||
} from "../data/data";
|
|
||||||
import CodeMirror from "@uiw/react-codemirror";
|
import CodeMirror from "@uiw/react-codemirror";
|
||||||
import { json } from "@codemirror/lang-json";
|
import { json } from "@codemirror/lang-json";
|
||||||
import jsPDF from "jspdf";
|
import jsPDF from "jspdf";
|
||||||
@ -62,7 +57,7 @@ export default function ControlPanel(props) {
|
|||||||
CODE: 2,
|
CODE: 2,
|
||||||
IMPORT: 3,
|
IMPORT: 3,
|
||||||
};
|
};
|
||||||
const ERROR = {
|
const STATUS = {
|
||||||
NONE: 0,
|
NONE: 0,
|
||||||
WARNING: 1,
|
WARNING: 1,
|
||||||
ERROR: 2,
|
ERROR: 2,
|
||||||
@ -75,16 +70,27 @@ export default function ControlPanel(props) {
|
|||||||
extension: "",
|
extension: "",
|
||||||
});
|
});
|
||||||
const [error, setError] = useState({
|
const [error, setError] = useState({
|
||||||
type: ERROR.NONE,
|
type: STATUS.NONE,
|
||||||
message: "",
|
message: "",
|
||||||
});
|
});
|
||||||
const [data, setData] = useState(null);
|
const [data, setData] = useState(null);
|
||||||
const { layout, setLayout } = useContext(LayoutContext);
|
const { layout, setLayout } = useContext(LayoutContext);
|
||||||
const { settings, setSettings } = useContext(SettingsContext);
|
const { settings, setSettings } = useContext(SettingsContext);
|
||||||
const { relationships, tables, setTables, setRelationships } =
|
const {
|
||||||
useContext(TableContext);
|
relationships,
|
||||||
const { notes, setNotes } = useContext(NoteContext);
|
tables,
|
||||||
const { areas, setAreas } = useContext(AreaContext);
|
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 } =
|
const { undoStack, redoStack, setUndoStack, setRedoStack } =
|
||||||
useContext(UndoRedoContext);
|
useContext(UndoRedoContext);
|
||||||
|
|
||||||
@ -107,155 +113,18 @@ export default function ControlPanel(props) {
|
|||||||
setNotes(data.notes);
|
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 = () => {
|
const undo = () => {
|
||||||
if (undoStack.length === 0) return;
|
if (undoStack.length === 0) return;
|
||||||
const a = undoStack.pop();
|
const a = undoStack.pop();
|
||||||
if (a.action === Action.ADD) {
|
if (a.action === Action.ADD) {
|
||||||
if (a.element === ObjectType.TABLE) {
|
if (a.element === ObjectType.TABLE) {
|
||||||
setTables((prev) =>
|
deleteTable(tables[tables.length - 1].id, false);
|
||||||
prev
|
|
||||||
.filter((e) => e.id !== prev.length - 1)
|
|
||||||
.map((e, i) => ({ ...e, id: i }))
|
|
||||||
);
|
|
||||||
} else if (a.element === ObjectType.AREA) {
|
} else if (a.element === ObjectType.AREA) {
|
||||||
setAreas((prev) =>
|
deleteArea(areas[areas.length - 1].id, false);
|
||||||
prev
|
|
||||||
.filter((e) => e.id !== prev.length - 1)
|
|
||||||
.map((e, i) => ({ ...e, id: i }))
|
|
||||||
);
|
|
||||||
} else if (a.element === ObjectType.NOTE) {
|
} else if (a.element === ObjectType.NOTE) {
|
||||||
setNotes((prev) =>
|
deleteNote(notes[notes.length - 1].id, false);
|
||||||
prev
|
|
||||||
.filter((e) => e.id !== prev.length - 1)
|
|
||||||
.map((e, i) => ({ ...e, id: i }))
|
|
||||||
);
|
|
||||||
} else if (a.element === ObjectType.RELATIONSHIP) {
|
} else if (a.element === ObjectType.RELATIONSHIP) {
|
||||||
setRelationships((prev) =>
|
deleteRelationship(a.data.id, false);
|
||||||
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) {
|
||||||
@ -280,17 +149,13 @@ export default function ControlPanel(props) {
|
|||||||
}
|
}
|
||||||
} else if (a.action === Action.DELETE) {
|
} else if (a.action === Action.DELETE) {
|
||||||
if (a.element === ObjectType.TABLE) {
|
if (a.element === ObjectType.TABLE) {
|
||||||
setTables((prev) => {
|
addTable(false, a.data);
|
||||||
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) {
|
} else if (a.element === ObjectType.RELATIONSHIP) {
|
||||||
setRelationships((prev) => {
|
addRelationship(false, a.data);
|
||||||
const temp = prev.slice();
|
} else if (a.element === ObjectType.NOTE) {
|
||||||
temp.splice(a.data.id, 0, a.data);
|
addNote(false, a.data);
|
||||||
return temp.map((t, i) => ({ ...t, id: i }));
|
} else if (a.element === ObjectType.AREA) {
|
||||||
});
|
addArea(false, a.data);
|
||||||
}
|
}
|
||||||
setRedoStack((prev) => [...prev, a]);
|
setRedoStack((prev) => [...prev, a]);
|
||||||
}
|
}
|
||||||
@ -301,17 +166,13 @@ export default function ControlPanel(props) {
|
|||||||
const a = redoStack.pop();
|
const a = redoStack.pop();
|
||||||
if (a.action === Action.ADD) {
|
if (a.action === Action.ADD) {
|
||||||
if (a.element === ObjectType.TABLE) {
|
if (a.element === ObjectType.TABLE) {
|
||||||
addTable();
|
addTable(false);
|
||||||
} else if (a.element === ObjectType.AREA) {
|
} else if (a.element === ObjectType.AREA) {
|
||||||
addArea();
|
addArea(false);
|
||||||
} else if (a.element === ObjectType.NOTE) {
|
} else if (a.element === ObjectType.NOTE) {
|
||||||
addNote();
|
addNote(false);
|
||||||
} else if (a.element === ObjectType.RELATIONSHIP) {
|
} else if (a.element === ObjectType.RELATIONSHIP) {
|
||||||
setRelationships((prev) => {
|
addRelationship(false, a.data);
|
||||||
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) {
|
||||||
@ -336,17 +197,13 @@ export default function ControlPanel(props) {
|
|||||||
}
|
}
|
||||||
} else if (a.action === Action.DELETE) {
|
} else if (a.action === Action.DELETE) {
|
||||||
if (a.element === ObjectType.TABLE) {
|
if (a.element === ObjectType.TABLE) {
|
||||||
setTables((prev) =>
|
deleteTable(a.data.id, false);
|
||||||
prev
|
|
||||||
.filter((t) => t.id !== a.data.id)
|
|
||||||
.map((t, i) => ({ ...t, id: i }))
|
|
||||||
);
|
|
||||||
} else if (a.element === ObjectType.RELATIONSHIP) {
|
} else if (a.element === ObjectType.RELATIONSHIP) {
|
||||||
setRelationships((prev) =>
|
deleteRelationship(a.data.id, false);
|
||||||
prev
|
} else if (a.element === ObjectType.NOTE) {
|
||||||
.filter((t) => t.id !== a.data.id)
|
deleteNote(a.data.id, false);
|
||||||
.map((t, i) => ({ ...t, id: i }))
|
} else if (a.element === ObjectType.AREA) {
|
||||||
);
|
deleteArea(a.data.id, false);
|
||||||
}
|
}
|
||||||
setUndoStack((prev) => [...prev, a]);
|
setUndoStack((prev) => [...prev, a]);
|
||||||
}
|
}
|
||||||
@ -772,51 +629,21 @@ export default function ControlPanel(props) {
|
|||||||
<button
|
<button
|
||||||
className="flex items-center py-1 px-2 hover:bg-slate-200 rounded"
|
className="flex items-center py-1 px-2 hover:bg-slate-200 rounded"
|
||||||
title="Add new table"
|
title="Add new table"
|
||||||
onClick={() => {
|
onClick={() => addTable()}
|
||||||
addTable();
|
|
||||||
setUndoStack((prev) => [
|
|
||||||
...prev,
|
|
||||||
{
|
|
||||||
action: Action.ADD,
|
|
||||||
element: ObjectType.TABLE,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
setRedoStack([]);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<IconAddTable />
|
<IconAddTable />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="py-1 px-2 hover:bg-slate-200 rounded flex items-center"
|
className="py-1 px-2 hover:bg-slate-200 rounded flex items-center"
|
||||||
title="Add subject area"
|
title="Add subject area"
|
||||||
onClick={() => {
|
onClick={() => addArea()}
|
||||||
addArea();
|
|
||||||
setUndoStack((prev) => [
|
|
||||||
...prev,
|
|
||||||
{
|
|
||||||
action: Action.ADD,
|
|
||||||
element: ObjectType.AREA,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
setRedoStack([]);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<IconAddArea />
|
<IconAddArea />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="py-1 px-2 hover:bg-slate-200 rounded flex items-center"
|
className="py-1 px-2 hover:bg-slate-200 rounded flex items-center"
|
||||||
title="Add new note"
|
title="Add new note"
|
||||||
onClick={() => {
|
onClick={() => addNote()}
|
||||||
addNote();
|
|
||||||
setUndoStack((prev) => [
|
|
||||||
...prev,
|
|
||||||
{
|
|
||||||
action: Action.ADD,
|
|
||||||
element: ObjectType.NOTE,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
setRedoStack([]);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<IconAddNote />
|
<IconAddNote />
|
||||||
</button>
|
</button>
|
||||||
@ -856,7 +683,7 @@ export default function ControlPanel(props) {
|
|||||||
});
|
});
|
||||||
saveAs(blob, `${exportData.filename}.${exportData.extension}`);
|
saveAs(blob, `${exportData.filename}.${exportData.extension}`);
|
||||||
} else if (visible === MODAL.IMPORT) {
|
} else if (visible === MODAL.IMPORT) {
|
||||||
if (error.type !== ERROR.ERROR) {
|
if (error.type !== STATUS.ERROR) {
|
||||||
setSettings((prev) => ({ ...prev, pan: { x: 0, y: 0 } }));
|
setSettings((prev) => ({ ...prev, pan: { x: 0, y: 0 } }));
|
||||||
overwriteDiagram();
|
overwriteDiagram();
|
||||||
setData(null);
|
setData(null);
|
||||||
@ -873,7 +700,7 @@ export default function ControlPanel(props) {
|
|||||||
filename: `diagram_${new Date().toISOString()}`,
|
filename: `diagram_${new Date().toISOString()}`,
|
||||||
}));
|
}));
|
||||||
setError({
|
setError({
|
||||||
type: ERROR.NONE,
|
type: STATUS.NONE,
|
||||||
message: "",
|
message: "",
|
||||||
});
|
});
|
||||||
setData(null);
|
setData(null);
|
||||||
@ -885,7 +712,7 @@ export default function ControlPanel(props) {
|
|||||||
okButtonProps={{
|
okButtonProps={{
|
||||||
disabled:
|
disabled:
|
||||||
(visible === MODAL.IMPORT &&
|
(visible === MODAL.IMPORT &&
|
||||||
(error.type === ERROR.ERROR || !data)) ||
|
(error.type === STATUS.ERROR || !data)) ||
|
||||||
((visible === MODAL.IMG || visible === MODAL.CODE) &&
|
((visible === MODAL.IMG || visible === MODAL.CODE) &&
|
||||||
!exportData.data),
|
!exportData.data),
|
||||||
}}
|
}}
|
||||||
@ -909,7 +736,7 @@ export default function ControlPanel(props) {
|
|||||||
jsonObject = JSON.parse(event.target.result);
|
jsonObject = JSON.parse(event.target.result);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setError({
|
setError({
|
||||||
type: ERROR.ERROR,
|
type: STATUS.ERROR,
|
||||||
message: "The file contains an error.",
|
message: "The file contains an error.",
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -917,7 +744,7 @@ export default function ControlPanel(props) {
|
|||||||
if (f.type === "application/json") {
|
if (f.type === "application/json") {
|
||||||
if (!jsonDiagramIsValid(jsonObject)) {
|
if (!jsonDiagramIsValid(jsonObject)) {
|
||||||
setError({
|
setError({
|
||||||
type: ERROR.ERROR,
|
type: STATUS.ERROR,
|
||||||
message:
|
message:
|
||||||
"The file is missing necessary properties for a diagram.",
|
"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") {
|
} else if (f.name.split(".").pop() === "ddb") {
|
||||||
if (!ddbDiagramIsValid(jsonObject)) {
|
if (!ddbDiagramIsValid(jsonObject)) {
|
||||||
setError({
|
setError({
|
||||||
type: ERROR.ERROR,
|
type: STATUS.ERROR,
|
||||||
message:
|
message:
|
||||||
"The file is missing necessary properties for a diagram.",
|
"The file is missing necessary properties for a diagram.",
|
||||||
});
|
});
|
||||||
@ -936,12 +763,12 @@ export default function ControlPanel(props) {
|
|||||||
setData(jsonObject);
|
setData(jsonObject);
|
||||||
if (diagramIsEmpty()) {
|
if (diagramIsEmpty()) {
|
||||||
setError({
|
setError({
|
||||||
type: ERROR.OK,
|
type: STATUS.OK,
|
||||||
message: "Everything looks good. You can now import.",
|
message: "Everything looks good. You can now import.",
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setError({
|
setError({
|
||||||
type: ERROR.WARNING,
|
type: STATUS.WARNING,
|
||||||
message:
|
message:
|
||||||
"The current diagram is not empty. Importing a new diagram will overwrite the current changes.",
|
"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"
|
accept="application/json,.ddb"
|
||||||
onRemove={() =>
|
onRemove={() =>
|
||||||
setError({
|
setError({
|
||||||
type: ERROR.NONE,
|
type: STATUS.NONE,
|
||||||
message: "",
|
message: "",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
onFileChange={() =>
|
onFileChange={() =>
|
||||||
setError({
|
setError({
|
||||||
type: ERROR.NONE,
|
type: STATUS.NONE,
|
||||||
message: "",
|
message: "",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
limit={1}
|
limit={1}
|
||||||
></Upload>
|
></Upload>
|
||||||
{error.type === ERROR.ERROR ? (
|
{error.type === STATUS.ERROR ? (
|
||||||
<Banner
|
<Banner
|
||||||
type="danger"
|
type="danger"
|
||||||
fullMode={false}
|
fullMode={false}
|
||||||
@ -982,14 +809,14 @@ export default function ControlPanel(props) {
|
|||||||
<div className="text-red-800">{error.message}</div>
|
<div className="text-red-800">{error.message}</div>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
) : error.type === ERROR.OK ? (
|
) : error.type === STATUS.OK ? (
|
||||||
<Banner
|
<Banner
|
||||||
type="info"
|
type="info"
|
||||||
fullMode={false}
|
fullMode={false}
|
||||||
description={<div>{error.message}</div>}
|
description={<div>{error.message}</div>}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
error.type === ERROR.WARNING && (
|
error.type === STATUS.WARNING && (
|
||||||
<Banner
|
<Banner
|
||||||
type="warning"
|
type="warning"
|
||||||
fullMode={false}
|
fullMode={false}
|
||||||
|
@ -24,7 +24,7 @@ import { NoteContext } from "../pages/editor";
|
|||||||
import { defaultNoteTheme, noteThemes } from "../data/data";
|
import { defaultNoteTheme, noteThemes } from "../data/data";
|
||||||
|
|
||||||
export default function NotesOverview(props) {
|
export default function NotesOverview(props) {
|
||||||
const { notes, setNotes } = useContext(NoteContext);
|
const { notes, setNotes, addNote, deleteNote } = useContext(NoteContext);
|
||||||
const [value, setValue] = useState("");
|
const [value, setValue] = useState("");
|
||||||
const [activeKey, setActiveKey] = useState("");
|
const [activeKey, setActiveKey] = useState("");
|
||||||
const [filteredResult, setFilteredResult] = useState(
|
const [filteredResult, setFilteredResult] = useState(
|
||||||
@ -78,22 +78,7 @@ export default function NotesOverview(props) {
|
|||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
<Button
|
<Button icon={<IconPlus />} block onClick={() => addNote()}>
|
||||||
icon={<IconPlus />}
|
|
||||||
block
|
|
||||||
onClick={() => {
|
|
||||||
const newNote = {
|
|
||||||
id: notes.length,
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
title: `note_${notes.length}`,
|
|
||||||
content: "",
|
|
||||||
color: defaultNoteTheme,
|
|
||||||
height: 88,
|
|
||||||
};
|
|
||||||
setNotes((prev) => [...prev, newNote]);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Add note
|
Add note
|
||||||
</Button>
|
</Button>
|
||||||
</Col>
|
</Col>
|
||||||
@ -189,11 +174,7 @@ export default function NotesOverview(props) {
|
|||||||
type="danger"
|
type="danger"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
Toast.success(`Note deleted!`);
|
Toast.success(`Note deleted!`);
|
||||||
setNotes((prev) =>
|
deleteNote(i, true);
|
||||||
prev
|
|
||||||
.filter((e) => e.id !== i)
|
|
||||||
.map((e, idx) => ({ ...e, id: idx }))
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
></Button>
|
></Button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,8 +22,8 @@ import {
|
|||||||
IllustrationNoContent,
|
IllustrationNoContent,
|
||||||
IllustrationNoContentDark,
|
IllustrationNoContentDark,
|
||||||
} from "@douyinfe/semi-illustrations";
|
} from "@douyinfe/semi-illustrations";
|
||||||
import { Action, Cardinality, Constraint, ObjectType } from "../data/data";
|
import { Cardinality, Constraint } from "../data/data";
|
||||||
import { TableContext, UndoRedoContext } from "../pages/editor";
|
import { TableContext } from "../pages/editor";
|
||||||
|
|
||||||
export default function ReferenceOverview(props) {
|
export default function ReferenceOverview(props) {
|
||||||
const columns = [
|
const columns = [
|
||||||
@ -36,8 +36,8 @@ export default function ReferenceOverview(props) {
|
|||||||
dataIndex: "foreign",
|
dataIndex: "foreign",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const { tables, relationships, setRelationships } = useContext(TableContext);
|
const { tables, relationships, setRelationships, deleteRelationship } =
|
||||||
const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
|
useContext(TableContext);
|
||||||
const [refActiveIndex, setRefActiveIndex] = useState("");
|
const [refActiveIndex, setRefActiveIndex] = useState("");
|
||||||
const [value, setValue] = useState("");
|
const [value, setValue] = useState("");
|
||||||
const [filteredResult, setFilteredResult] = useState(
|
const [filteredResult, setFilteredResult] = useState(
|
||||||
@ -233,22 +233,7 @@ export default function ReferenceOverview(props) {
|
|||||||
icon={<IconDeleteStroked />}
|
icon={<IconDeleteStroked />}
|
||||||
block
|
block
|
||||||
type="danger"
|
type="danger"
|
||||||
onClick={() => {
|
onClick={() => deleteRelationship(r.id, true)}
|
||||||
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
|
Delete
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -40,7 +40,7 @@ export default function Table(props) {
|
|||||||
const [hoveredField, setHoveredField] = useState(-1);
|
const [hoveredField, setHoveredField] = useState(-1);
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const { layout } = useContext(LayoutContext);
|
const { layout } = useContext(LayoutContext);
|
||||||
const { setTables } = useContext(TableContext);
|
const { setTables, deleteTable } = useContext(TableContext);
|
||||||
const { tab, setTab } = useContext(TabContext);
|
const { tab, setTab } = useContext(TabContext);
|
||||||
const { settings } = useContext(SettingsContext);
|
const { settings } = useContext(SettingsContext);
|
||||||
|
|
||||||
@ -180,11 +180,7 @@ export default function Table(props) {
|
|||||||
style={{ marginTop: "8px" }}
|
style={{ marginTop: "8px" }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
Toast.success(`Table deleted!`);
|
Toast.success(`Table deleted!`);
|
||||||
setTables((prev) =>
|
deleteTable(props.tableData.id);
|
||||||
prev
|
|
||||||
.filter((e) => e.id !== props.tableData.id)
|
|
||||||
.map((e, idx) => ({ ...e, id: idx }))
|
|
||||||
);
|
|
||||||
props.setSelectedTable("");
|
props.setSelectedTable("");
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -683,11 +679,7 @@ export default function Table(props) {
|
|||||||
type="danger"
|
type="danger"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
Toast.success(`Table deleted!`);
|
Toast.success(`Table deleted!`);
|
||||||
setTables((prev) =>
|
deleteTable(props.tableData.id);
|
||||||
prev
|
|
||||||
.filter((e) => e.id !== props.tableData.id)
|
|
||||||
.map((e, idx) => ({ ...e, id: idx }))
|
|
||||||
);
|
|
||||||
props.setSelectedTable("");
|
props.setSelectedTable("");
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
}}
|
}}
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
import { React, useContext, useState } from "react";
|
import { React, useContext, useState } from "react";
|
||||||
import {
|
import { defaultTableTheme, sqlDataTypes, tableThemes } from "../data/data";
|
||||||
defaultTableTheme,
|
|
||||||
sqlDataTypes,
|
|
||||||
tableThemes,
|
|
||||||
Action,
|
|
||||||
ObjectType,
|
|
||||||
} from "../data/data";
|
|
||||||
import {
|
import {
|
||||||
Collapse,
|
Collapse,
|
||||||
Row,
|
Row,
|
||||||
@ -32,18 +26,12 @@ import {
|
|||||||
IllustrationNoContent,
|
IllustrationNoContent,
|
||||||
IllustrationNoContentDark,
|
IllustrationNoContentDark,
|
||||||
} from "@douyinfe/semi-illustrations";
|
} from "@douyinfe/semi-illustrations";
|
||||||
import {
|
import { TableContext } from "../pages/editor";
|
||||||
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, addTable, deleteTable } = 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;
|
||||||
@ -118,39 +106,7 @@ export default function TableOverview(props) {
|
|||||||
icon={<IconPlus />}
|
icon={<IconPlus />}
|
||||||
block
|
block
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setTables((prev) => [
|
addTable(true);
|
||||||
...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
|
Add table
|
||||||
@ -570,20 +526,7 @@ export default function TableOverview(props) {
|
|||||||
type="danger"
|
type="danger"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
Toast.success(`Table deleted!`);
|
Toast.success(`Table deleted!`);
|
||||||
setUndoStack((prev) => [
|
deleteTable(i);
|
||||||
...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 }))
|
|
||||||
);
|
|
||||||
props.setSelectedTable("");
|
props.setSelectedTable("");
|
||||||
}}
|
}}
|
||||||
></Button>
|
></Button>
|
||||||
|
@ -5,7 +5,13 @@ import { DndProvider } from "react-dnd";
|
|||||||
import { HTML5Backend } from "react-dnd-html5-backend";
|
import { HTML5Backend } from "react-dnd-html5-backend";
|
||||||
import Canvas from "../components/canvas";
|
import Canvas from "../components/canvas";
|
||||||
import EditorPanel from "../components/editor_panel";
|
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 LayoutContext = createContext();
|
||||||
export const TableContext = createContext();
|
export const TableContext = createContext();
|
||||||
@ -41,7 +47,7 @@ export default function Editor(props) {
|
|||||||
strictMode: false,
|
strictMode: false,
|
||||||
showFieldSummary: true,
|
showFieldSummary: true,
|
||||||
zoom: 1,
|
zoom: 1,
|
||||||
pan: {x: 0, y: 0},
|
pan: { x: 0, y: 0 },
|
||||||
showGrid: true,
|
showGrid: true,
|
||||||
});
|
});
|
||||||
const [undoStack, setUndoStack] = useState([]);
|
const [undoStack, setUndoStack] = useState([]);
|
||||||
@ -53,17 +59,297 @@ export default function Editor(props) {
|
|||||||
if (w > 340) setWidth(w);
|
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(() => {
|
useEffect(() => {
|
||||||
document.title = "Editor";
|
document.title = "Editor - drawDB";
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LayoutContext.Provider value={{ layout, setLayout }}>
|
<LayoutContext.Provider value={{ layout, setLayout }}>
|
||||||
<TableContext.Provider
|
<TableContext.Provider
|
||||||
value={{ tables, setTables, relationships, setRelationships }}
|
value={{
|
||||||
|
tables,
|
||||||
|
setTables,
|
||||||
|
addTable,
|
||||||
|
moveTable,
|
||||||
|
deleteTable,
|
||||||
|
relationships,
|
||||||
|
setRelationships,
|
||||||
|
addRelationship,
|
||||||
|
deleteRelationship,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<AreaContext.Provider value={{ areas, setAreas }}>
|
<AreaContext.Provider
|
||||||
<NoteContext.Provider value={{ notes, setNotes }}>
|
value={{ areas, setAreas, moveArea, addArea, deleteArea }}
|
||||||
|
>
|
||||||
|
<NoteContext.Provider
|
||||||
|
value={{ notes, setNotes, moveNote, addNote, deleteNote }}
|
||||||
|
>
|
||||||
<TabContext.Provider value={{ tab, setTab }}>
|
<TabContext.Provider value={{ tab, setTab }}>
|
||||||
<SettingsContext.Provider value={{ settings, setSettings }}>
|
<SettingsContext.Provider value={{ settings, setSettings }}>
|
||||||
<UndoRedoContext.Provider
|
<UndoRedoContext.Provider
|
||||||
|
Loading…
Reference in New Issue
Block a user