diff --git a/src/components/Area.jsx b/src/components/Area.jsx index b53d09b..6c213ff 100644 --- a/src/components/Area.jsx +++ b/src/components/Area.jsx @@ -13,15 +13,11 @@ import { defaultTableTheme, State, } from "../data/data"; -import { - AreaContext, - SelectContext, - StateContext, - TabContext, - UndoRedoContext, -} from "../pages/Editor"; +import { AreaContext, StateContext, TabContext } from "../pages/Editor"; import useLayout from "../hooks/useLayout"; import useSettings from "../hooks/useSettings"; +import useUndoRedo from "../hooks/useUndoRedo"; +import useSelect from "../hooks/useSelect"; export default function Area(props) { const [hovered, setHovered] = useState(false); @@ -31,8 +27,8 @@ export default function Area(props) { const { settings } = useSettings(); const { tab, setTab } = useContext(TabContext); const { updateArea, deleteArea } = useContext(AreaContext); - const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); - const { selectedElement, setSelectedElement } = useContext(SelectContext); + const { setUndoStack, setRedoStack } = useUndoRedo(); + const { selectedElement, setSelectedElement } = useSelect(); const handleMouseDown = (e, dir) => { props.setResize({ id: props.areaData.id, dir: dir }); diff --git a/src/components/AreaOverview.jsx b/src/components/AreaOverview.jsx index 4dc37c5..5f49494 100644 --- a/src/components/AreaOverview.jsx +++ b/src/components/AreaOverview.jsx @@ -26,12 +26,13 @@ import { ObjectType, State, } from "../data/data"; -import { AreaContext, StateContext, UndoRedoContext } from "../pages/Editor"; +import { AreaContext, StateContext } from "../pages/Editor"; +import useUndoRedo from "../hooks/useUndoRedo"; export default function AreaOverview() { const { setState } = useContext(StateContext); const { areas, addArea, deleteArea, updateArea } = useContext(AreaContext); - const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); + const { setUndoStack, setRedoStack } = useUndoRedo(); const [editField, setEditField] = useState({}); const [value, setValue] = useState(""); const [filteredResult, setFilteredResult] = useState( diff --git a/src/components/Canvas.jsx b/src/components/Canvas.jsx index 81c1d64..d10ca38 100644 --- a/src/components/Canvas.jsx +++ b/src/components/Canvas.jsx @@ -3,27 +3,23 @@ import Table from "./Table"; import { Action, Cardinality, Constraint, ObjectType } from "../data/data"; import Area from "./Area"; import Relationship from "./Relationship"; -import { - AreaContext, - NoteContext, - TableContext, - UndoRedoContext, - SelectContext, -} from "../pages/Editor"; +import { AreaContext, NoteContext } from "../pages/Editor"; import Note from "./Note"; import { Toast } from "@douyinfe/semi-ui"; import useSettings from "../hooks/useSettings"; import useTransform from "../hooks/useTransform"; +import useTables from "../hooks/useTables"; +import useUndoRedo from "../hooks/useUndoRedo"; +import useSelect from "../hooks/useSelect"; export default function Canvas() { - const { tables, updateTable, relationships, addRelationship } = - useContext(TableContext); + const { tables, updateTable, relationships, addRelationship } = useTables(); const { areas, updateArea } = useContext(AreaContext); const { notes, updateNote } = useContext(NoteContext); const { settings } = useSettings(); - const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); + const { setUndoStack, setRedoStack } = useUndoRedo(); const { transform, setTransform } = useTransform(); - const { selectedElement, setSelectedElement } = useContext(SelectContext); + const { selectedElement, setSelectedElement } = useSelect(); const [dragging, setDragging] = useState({ element: ObjectType.NONE, id: -1, diff --git a/src/components/ControlPanel.jsx b/src/components/ControlPanel.jsx index 5be75dc..fa74c4d 100644 --- a/src/components/ControlPanel.jsx +++ b/src/components/ControlPanel.jsx @@ -51,12 +51,9 @@ import { import { AreaContext, NoteContext, - SelectContext, StateContext, TabContext, - TableContext, TypeContext, - UndoRedoContext, } from "../pages/Editor"; import { IconAddTable, IconAddArea, IconAddNote } from "./CustomIcons"; import { ObjectType, Action, Tab, State, Cardinality } from "../data/data"; @@ -73,6 +70,9 @@ import { Thumbnail } from "./Thumbnail"; import useLayout from "../hooks/useLayout"; import useSettings from "../hooks/useSettings"; import useTransform from "../hooks/useTransform"; +import useTables from "../hooks/useTables"; +import useUndoRedo from "../hooks/useUndoRedo"; +import useSelect from "../hooks/useSelect"; export default function ControlPanel({ diagramId, @@ -136,16 +136,15 @@ export default function ControlPanel({ setRelationships, addRelationship, deleteRelationship, - } = useContext(TableContext); + } = useTables(); const { types, addType, deleteType, updateType, setTypes } = useContext(TypeContext); const { notes, setNotes, updateNote, addNote, deleteNote } = useContext(NoteContext); const { areas, setAreas, updateArea, addArea, deleteArea } = useContext(AreaContext); - const { undoStack, redoStack, setUndoStack, setRedoStack } = - useContext(UndoRedoContext); - const { selectedElement, setSelectedElement } = useContext(SelectContext); + const { undoStack, redoStack, setUndoStack, setRedoStack } = useUndoRedo(); + const { selectedElement, setSelectedElement } = useSelect(); const { tab, setTab } = useContext(TabContext); const { transform, setTransform } = useTransform(); diff --git a/src/components/Issues.jsx b/src/components/Issues.jsx index aab30c4..99c24db 100644 --- a/src/components/Issues.jsx +++ b/src/components/Issues.jsx @@ -1,13 +1,14 @@ import { useContext, useState, useEffect } from "react"; import { Collapse, Badge } from "@douyinfe/semi-ui"; -import { TableContext, TypeContext } from "../pages/Editor"; +import { TypeContext } from "../pages/Editor"; import { validateDiagram, arrayIsEqual } from "../utils"; import useSettings from "../hooks/useSettings"; +import useTables from "../hooks/useTables"; export default function Issues() { const { settings } = useSettings(); const { types } = useContext(TypeContext); - const { tables, relationships } = useContext(TableContext); + const { tables, relationships } = useTables(); const [issues, setIssues] = useState([]); useEffect(() => { diff --git a/src/components/Note.jsx b/src/components/Note.jsx index dc6b100..b0c6896 100644 --- a/src/components/Note.jsx +++ b/src/components/Note.jsx @@ -1,11 +1,5 @@ import { useContext, useState } from "react"; -import { - NoteContext, - UndoRedoContext, - TabContext, - SelectContext, - StateContext, -} from "../pages/Editor"; +import { NoteContext, TabContext, StateContext } from "../pages/Editor"; import { Action, ObjectType, noteThemes, Tab, State } from "../data/data"; import { Input, Button, Popover, Toast } from "@douyinfe/semi-ui"; import { @@ -14,6 +8,8 @@ import { IconCheckboxTick, } from "@douyinfe/semi-icons"; import useLayout from "../hooks/useLayout"; +import useUndoRedo from "../hooks/useUndoRedo"; +import useSelect from "../hooks/useSelect"; export default function Note(props) { const [editField, setEditField] = useState({}); @@ -22,11 +18,11 @@ export default function Note(props) { const r = 3; const fold = 24; const { updateNote, deleteNote } = useContext(NoteContext); - const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); + const { setUndoStack, setRedoStack } = useUndoRedo(); const { setState } = useContext(StateContext); const { layout } = useLayout(); const { tab, setTab } = useContext(TabContext); - const { selectedElement, setSelectedElement } = useContext(SelectContext); + const { selectedElement, setSelectedElement } = useSelect(); const handleChange = (e) => { const textarea = document.getElementById(`note_${props.data.id}`); diff --git a/src/components/NotesOverview.jsx b/src/components/NotesOverview.jsx index 69048e1..c956db8 100644 --- a/src/components/NotesOverview.jsx +++ b/src/components/NotesOverview.jsx @@ -21,12 +21,13 @@ import { IconSearch, IconCheckboxTick, } from "@douyinfe/semi-icons"; -import { NoteContext, UndoRedoContext } from "../pages/Editor"; +import { NoteContext } from "../pages/Editor"; import { noteThemes, Action, ObjectType } from "../data/data"; +import useUndoRedo from "../hooks/useUndoRedo"; export default function NotesOverview() { const { notes, updateNote, addNote, deleteNote } = useContext(NoteContext); - const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); + const { setUndoStack, setRedoStack } = useUndoRedo(); const [value, setValue] = useState(""); const [editField, setEditField] = useState({}); const [activeKey, setActiveKey] = useState(""); diff --git a/src/components/ReferenceOverview.jsx b/src/components/ReferenceOverview.jsx index 89a21c0..d953d2a 100644 --- a/src/components/ReferenceOverview.jsx +++ b/src/components/ReferenceOverview.jsx @@ -1,4 +1,4 @@ -import { useContext, useState } from "react"; +import { useState } from "react"; import { AutoComplete, Collapse, @@ -21,7 +21,8 @@ import { IllustrationNoContentDark, } from "@douyinfe/semi-illustrations"; import { Cardinality, Constraint, Action, ObjectType } from "../data/data"; -import { TableContext, UndoRedoContext } from "../pages/Editor"; +import useTables from "../hooks/useTables"; +import useUndoRedo from "../hooks/useUndoRedo"; export default function ReferenceOverview() { const columns = [ @@ -35,8 +36,8 @@ export default function ReferenceOverview() { }, ]; const { tables, relationships, setRelationships, deleteRelationship } = - useContext(TableContext); - const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); + useTables(); + const { setUndoStack, setRedoStack } = useUndoRedo(); const [refActiveIndex, setRefActiveIndex] = useState(""); const [value, setValue] = useState(""); const [filteredResult, setFilteredResult] = useState( @@ -118,11 +119,13 @@ export default function ReferenceOverview() { dataSource={[ { key: "1", - foreign: `${tables[r.startTableId].name}(${tables[r.startTableId].fields[r.startFieldId] - .name - })`, - primary: `${tables[r.endTableId].name}(${tables[r.endTableId].fields[r.endFieldId].name - })`, + foreign: `${tables[r.startTableId].name}(${ + tables[r.startTableId].fields[r.startFieldId] + .name + })`, + primary: `${tables[r.endTableId].name}(${ + tables[r.endTableId].fields[r.endFieldId].name + })`, }, ]} pagination={false} @@ -160,12 +163,12 @@ export default function ReferenceOverview() { prev.map((e, idx) => idx === i ? { - ...e, - startTableId: e.endTableId, - startFieldId: e.endFieldId, - endTableId: e.startTableId, - endFieldId: e.startFieldId, - } + ...e, + startTableId: e.endTableId, + startFieldId: e.endFieldId, + endTableId: e.startTableId, + endFieldId: e.startFieldId, + } : e ) ); diff --git a/src/components/Sidebar.jsx b/src/components/Sidebar.jsx deleted file mode 100644 index 2316f1b..0000000 --- a/src/components/Sidebar.jsx +++ /dev/null @@ -1,219 +0,0 @@ -import { useContext, useEffect, useState } from "react"; -import chatIcon from "../assets/chat.png"; -import botIcon from "../assets/bot.png"; -import teamIcon from "../assets/group.png"; -import timeLine from "../assets/process.png"; -import timeLineDark from "../assets/process_dark.png"; -import todo from "../assets/calendar.png"; -import { Tooltip, SideSheet, List, Badge } from "@douyinfe/semi-ui"; -import { - BotMessageContext, - MessageContext, - UndoRedoContext, -} from "../pages/Editor"; -import Todo from "./Todo"; -import Chat from "./Chat"; -import DrawBot from "./DrawBot"; -import useSettings from "../hooks/useSettings"; - -export default function Sidebar() { - const SidesheetType = { - NONE: 0, - CHAT: 1, - TEAM: 2, - TODO: 3, - TIMELINE: 4, - BOT: 5, - }; - const { undoStack } = useContext(UndoRedoContext); - const { messages } = useContext(MessageContext); - const { settings } = useSettings(); - const { botMessages } = useContext(BotMessageContext); - const [sidesheet, setSidesheet] = useState(SidesheetType.NONE); - const [seen, setSeen] = useState(0); - const [seenBot, setSeenBot] = useState(0); - const [count, setCount] = useState(messages.length - seen); - const [botCount, setBotCount] = useState(botMessages.length - seenBot); - - const getTitle = (type) => { - switch (type) { - case SidesheetType.TIMELINE: - return ( -
- chat icon -
Timeline
-
- ); - case SidesheetType.CHAT: - return ( -
- chat icon -
Chat
-
- ); - case SidesheetType.TODO: - return ( -
- todo icon -
To-do list
-
- ); - case SidesheetType.BOT: - return ( -
- todo icon -
drawBOT
-
- ); - default: - break; - } - }; - - const getContent = (type) => { - switch (type) { - case SidesheetType.TIMELINE: - return renderTimeline(); - case SidesheetType.TODO: - return ; - case SidesheetType.CHAT: - return ; - case SidesheetType.BOT: - return ; - default: - break; - } - }; - - useEffect(() => { - if (sidesheet !== SidesheetType.CHAT) { - setCount(messages.length - seen); - } - if (sidesheet !== SidesheetType.BOT) { - setBotCount(botMessages.length - seenBot); - } - }, [ - sidesheet, - seen, - messages.length, - SidesheetType.CHAT, - seenBot, - botMessages.length, - SidesheetType.BOT, - ]); - - return ( - <> -
- - - - - - - - - - - - - - - - - - - -
- { - if (sidesheet === SidesheetType.CHAT) { - setSeen(messages.length); - } else if (sidesheet === SidesheetType.BOT) { - setSeenBot(botMessages.length); - } - setSidesheet(SidesheetType.NONE); - }} - width={340} - title={getTitle(sidesheet)} - style={{ paddingBottom: "16px" }} - bodyStyle={{ padding: "0px" }} - > - {getContent(sidesheet)} - - - ); - - function renderTimeline() { - if (undoStack.length > 0) { - return ( - - {[...undoStack].reverse().map((e, i) => ( - -
- -
{e.message}
-
-
- ))} -
- ); - } else { - return ( -
- No activity was recorded. You have not added anything to your diagram - yet. -
- ); - } - } -} diff --git a/src/components/Table.jsx b/src/components/Table.jsx index 7a30aef..54927a4 100644 --- a/src/components/Table.jsx +++ b/src/components/Table.jsx @@ -31,16 +31,13 @@ import { SideSheet, Toast, } from "@douyinfe/semi-ui"; -import { - SelectContext, - TabContext, - TableContext, - TypeContext, - UndoRedoContext, -} from "../pages/Editor"; +import { TabContext, TypeContext } from "../pages/Editor"; import { getSize, hasCheck, hasPrecision, isSized } from "../utils"; import useLayout from "../hooks/useLayout"; import useSettings from "../hooks/useSettings"; +import useUndoRedo from "../hooks/useUndoRedo"; +import useTables from "../hooks/useTables"; +import useSelect from "../hooks/useSelect"; export default function Table(props) { const [isHovered, setIsHovered] = useState(false); @@ -48,12 +45,12 @@ export default function Table(props) { const [editField, setEditField] = useState({}); const { layout } = useLayout(); const { deleteTable, updateTable, updateField, setRelationships } = - useContext(TableContext); + useTables(); const { tab, setTab } = useContext(TabContext); const { settings } = useSettings(); const { types } = useContext(TypeContext); - const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); - const { selectedElement, setSelectedElement } = useContext(SelectContext); + const { setUndoStack, setRedoStack } = useUndoRedo(); + const { selectedElement, setSelectedElement } = useSelect(); const height = props.tableData.fields.length * 36 + 50 + 7; diff --git a/src/components/TableOverview.jsx b/src/components/TableOverview.jsx index c3ae353..438ead8 100644 --- a/src/components/TableOverview.jsx +++ b/src/components/TableOverview.jsx @@ -35,13 +35,11 @@ import { IllustrationNoContent, IllustrationNoContentDark, } from "@douyinfe/semi-illustrations"; -import { - SelectContext, - TableContext, - TypeContext, - UndoRedoContext, -} from "../pages/Editor"; +import { TypeContext } from "../pages/Editor"; import { getSize, hasCheck, hasPrecision, isSized } from "../utils"; +import useTables from "../hooks/useTables"; +import useUndoRedo from "../hooks/useUndoRedo"; +import useSelect from "../hooks/useSelect"; export default function TableOverview() { const [indexActiveKey, setIndexActiveKey] = useState(""); @@ -53,10 +51,10 @@ export default function TableOverview() { updateField, updateTable, setRelationships, - } = useContext(TableContext); + } = useTables(); const { types } = useContext(TypeContext); - const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); - const { selectedElement, setSelectedElement } = useContext(SelectContext); + const { setUndoStack, setRedoStack } = useUndoRedo(); + const { selectedElement, setSelectedElement } = useSelect(); const [editField, setEditField] = useState({}); const [filteredResult, setFilteredResult] = useState( tables.map((t) => { diff --git a/src/components/TypesOverview.jsx b/src/components/TypesOverview.jsx index bf95020..0c08091 100644 --- a/src/components/TypesOverview.jsx +++ b/src/components/TypesOverview.jsx @@ -27,13 +27,14 @@ import { IllustrationNoContent, IllustrationNoContentDark, } from "@douyinfe/semi-illustrations"; -import { TypeContext, UndoRedoContext } from "../pages/Editor"; +import { TypeContext } from "../pages/Editor"; import { isSized, hasPrecision, getSize } from "../utils"; +import useUndoRedo from "../hooks/useUndoRedo"; export default function TableOverview() { const [value, setValue] = useState(""); const { types, addType, deleteType, updateType } = useContext(TypeContext); - const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); + const { setUndoStack, setRedoStack } = useUndoRedo(); const [editField, setEditField] = useState({}); const [filteredResult, setFilteredResult] = useState( types.map((t) => { diff --git a/src/context/SelectContext.jsx b/src/context/SelectContext.jsx new file mode 100644 index 0000000..7cb2e59 --- /dev/null +++ b/src/context/SelectContext.jsx @@ -0,0 +1,19 @@ +import { createContext, useState } from "react"; +import { ObjectType } from "../data/data"; + +export const SelectContext = createContext(null); + +export default function SelectContextProvider({ children }) { + const [selectedElement, setSelectedElement] = useState({ + element: ObjectType.NONE, + id: -1, + openDialogue: false, + openCollapse: false, + }); + + return ( + + {children} + + ); +} diff --git a/src/context/TablesContext.jsx b/src/context/TablesContext.jsx new file mode 100644 index 0000000..6a8906f --- /dev/null +++ b/src/context/TablesContext.jsx @@ -0,0 +1,212 @@ +import { createContext, useState } from "react"; +import useTransform from "../hooks/useTransform"; +import { Action, ObjectType, defaultTableTheme } from "../data/data"; +import useUndoRedo from "../hooks/useUndoRedo"; +import useSelect from "../hooks/useSelect"; + +export const TablesContext = createContext(null); + +export default function TablesContextProvider({ children }) { + const [tables, setTables] = useState([]); + const [relationships, setRelationships] = useState([]); + const { transform } = useTransform(); + const { setUndoStack, setRedoStack } = useUndoRedo(); + const { selectedElement, setSelectedElement } = useSelect(); + + 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: -transform.pan.x, + y: -transform.pan.y, + fields: [ + { + name: "id", + type: "INT", + default: "", + check: "", + primary: true, + unique: true, + notNull: true, + increment: true, + comment: "", + id: 0, + }, + ], + comment: "", + indices: [], + color: defaultTableTheme, + }, + ]); + } + if (addToHistory) { + setUndoStack((prev) => [ + ...prev, + { + action: Action.ADD, + element: ObjectType.TABLE, + message: `Add new table`, + }, + ]); + setRedoStack([]); + } + }; + + const deleteTable = (id, addToHistory = true) => { + if (addToHistory) { + setUndoStack((prev) => [ + ...prev, + { + action: Action.DELETE, + element: ObjectType.TABLE, + data: tables[id], + message: `Delete table`, + }, + ]); + setRedoStack([]); + } + setRelationships((prevR) => { + return prevR + .filter((e) => !(e.startTableId === id || e.endTableId === id)) + .map((e, i) => { + const newR = { ...e }; + + if (e.startTableId > id) { + newR.startTableId = e.startTableId - 1; + } + if (e.endTableId > id) { + newR.endTableId = e.endTableId - 1; + } + + return { ...newR, id: i }; + }); + }); + setTables((prev) => { + return prev.filter((e) => e.id !== id).map((e, i) => ({ ...e, id: i })); + }); + if (id === selectedElement.id) { + setSelectedElement({ + element: ObjectType.NONE, + id: -1, + openDialogue: false, + openCollapse: false, + }); + } + }; + + const updateTable = (id, updatedValues, updateRelationships = false) => { + setTables((prev) => + prev.map((table) => { + if (table.id === id) { + if (updateRelationships) { + setRelationships((prev) => + prev.map((r) => { + let newR = { ...r }; + if (r.startTableId === id) { + newR.startX = updatedValues.x + 15; + newR.startY = updatedValues.y + r.startFieldId * 36 + 69; + } + if (r.endTableId === id) { + newR.endX = updatedValues.x + 15; + newR.endY = updatedValues.y + r.endFieldId * 36 + 69; + } + return newR; + }) + ); + } + return { + ...table, + ...updatedValues, + }; + } + return table; + }) + ); + }; + + const updateField = (tid, fid, updatedValues) => { + setTables((prev) => + prev.map((table, i) => { + if (tid === i) { + return { + ...table, + fields: table.fields.map((field, j) => + fid === j ? { ...field, ...updatedValues } : field + ), + }; + } + return table; + }) + ); + }; + + const addRelationship = (addToHistory = true, data) => { + if (addToHistory) { + setRelationships((prev) => { + setUndoStack((prevUndo) => [ + ...prevUndo, + { + action: Action.ADD, + element: ObjectType.RELATIONSHIP, + data: data, + message: `Add new relationship`, + }, + ]); + 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 deleteRelationship = (id, addToHistory = true) => { + if (addToHistory) { + setUndoStack((prev) => [ + ...prev, + { + action: Action.DELETE, + element: ObjectType.RELATIONSHIP, + data: relationships[id], + message: `Delete relationship`, + }, + ]); + setRedoStack([]); + } + setRelationships((prev) => + prev.filter((e) => e.id !== id).map((e, i) => ({ ...e, id: i })) + ); + }; + + return ( + + {children} + + ); +} diff --git a/src/context/UndoRedoContext.jsx b/src/context/UndoRedoContext.jsx new file mode 100644 index 0000000..de9aaf6 --- /dev/null +++ b/src/context/UndoRedoContext.jsx @@ -0,0 +1,15 @@ +import { createContext, useState } from "react"; + +export const UndoRedoContext = createContext(null); + +export default function UndoRedoContextProvider({ children }) { + const [undoStack, setUndoStack] = useState([]); + const [redoStack, setRedoStack] = useState([]); + return ( + + {children} + + ); +} diff --git a/src/hooks/useSelect.js b/src/hooks/useSelect.js new file mode 100644 index 0000000..f45c01a --- /dev/null +++ b/src/hooks/useSelect.js @@ -0,0 +1,6 @@ +import { useContext } from "react"; +import { SelectContext } from "../context/SelectContext"; + +export default function useSelect() { + return useContext(SelectContext); +} diff --git a/src/hooks/useTables.js b/src/hooks/useTables.js new file mode 100644 index 0000000..3d21dd5 --- /dev/null +++ b/src/hooks/useTables.js @@ -0,0 +1,6 @@ +import { useContext } from "react"; +import { TablesContext } from "../context/TablesContext"; + +export default function useTables() { + return useContext(TablesContext); +} diff --git a/src/hooks/useUndoRedo.js b/src/hooks/useUndoRedo.js new file mode 100644 index 0000000..6260adf --- /dev/null +++ b/src/hooks/useUndoRedo.js @@ -0,0 +1,6 @@ +import { useContext } from "react"; +import { UndoRedoContext } from "../context/UndoRedoContext"; + +export default function useUndoRedo() { + return useContext(UndoRedoContext); +} diff --git a/src/pages/Editor.jsx b/src/pages/Editor.jsx index a939083..14e0d6d 100644 --- a/src/pages/Editor.jsx +++ b/src/pages/Editor.jsx @@ -18,25 +18,31 @@ import LayoutContextProvider from "../context/LayoutContext"; import useSettings from "../hooks/useSettings"; import TransformContextProvider from "../context/TransformContext"; import useTransform from "../hooks/useTransform"; +import useTables from "../hooks/useTables"; +import TablesContextProvider from "../context/TablesContext"; +import useUndoRedo from "../hooks/useUndoRedo"; +import UndoRedoContextProvider from "../context/UndoRedoContext"; +import SelectContextProvider from "../context/SelectContext"; +import useSelect from "../hooks/useSelect"; export const StateContext = createContext(); -export const TableContext = createContext(); export const AreaContext = createContext(); export const TabContext = createContext(); export const NoteContext = createContext(); -export const UndoRedoContext = createContext(); -export const SelectContext = createContext(); export const TaskContext = createContext(); -export const MessageContext = createContext(); -export const BotMessageContext = createContext(); export const TypeContext = createContext(); -// export const TransformContext = createContext(); export default function Editor() { return ( - + + + + + + + ); @@ -47,8 +53,7 @@ function WorkSpace() { const [title, setTitle] = useState("Untitled Diagram"); const [state, setState] = useState(State.NONE); const [lastSaved, setLastSaved] = useState(""); - const [tables, setTables] = useState([]); - const [relationships, setRelationships] = useState([]); + const { tables, relationships, setTables, setRelationships } = useTables(); const [areas, setAreas] = useState([]); const [notes, setNotes] = useState([]); const [types, setTypes] = useState([]); @@ -58,15 +63,9 @@ function WorkSpace() { const { layout, setLayout } = useLayout(); const { settings, setSettings } = useSettings(); const { transform, setTransform } = useTransform(); + const { selectedElement, setSelectedElement } = useSelect(); const [tasks, setTasks] = useState([]); - const [undoStack, setUndoStack] = useState([]); - const [redoStack, setRedoStack] = useState([]); - const [selectedElement, setSelectedElement] = useState({ - element: ObjectType.NONE, - id: -1, - openDialogue: false, - openCollapse: false, - }); + const { undoStack, redoStack, setUndoStack, setRedoStack } = useUndoRedo(); const dragHandler = (e) => { if (!resize) return; @@ -74,54 +73,6 @@ function WorkSpace() { 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: -transform.pan.x, - y: -transform.pan.y, - fields: [ - { - name: "id", - type: "INT", - default: "", - check: "", - primary: true, - unique: true, - notNull: true, - increment: true, - comment: "", - id: 0, - }, - ], - comment: "", - indices: [], - color: defaultTableTheme, - }, - ]); - } - if (addToHistory) { - setUndoStack((prev) => [ - ...prev, - { - action: Action.ADD, - element: ObjectType.TABLE, - message: `Add new table`, - }, - ]); - setRedoStack([]); - } - }; - const addType = (addToHistory = true, data) => { if (data) { setTypes((prev) => { @@ -175,22 +126,6 @@ function WorkSpace() { ); }; - const updateField = (tid, fid, updatedValues) => { - setTables((prev) => - prev.map((table, i) => { - if (tid === i) { - return { - ...table, - fields: table.fields.map((field, j) => - fid === j ? { ...field, ...updatedValues } : field - ), - }; - } - return table; - }) - ); - }; - const addArea = (addToHistory = true, data) => { if (data) { setAreas((prev) => { @@ -259,72 +194,6 @@ function WorkSpace() { } }; - const addRelationship = (addToHistory = true, data) => { - if (addToHistory) { - setRelationships((prev) => { - setUndoStack((prevUndo) => [ - ...prevUndo, - { - action: Action.ADD, - element: ObjectType.RELATIONSHIP, - data: data, - message: `Add new relationship`, - }, - ]); - 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 deleteTable = (id, addToHistory = true) => { - if (addToHistory) { - setUndoStack((prev) => [ - ...prev, - { - action: Action.DELETE, - element: ObjectType.TABLE, - data: tables[id], - message: `Delete table`, - }, - ]); - setRedoStack([]); - } - setRelationships((prevR) => { - return prevR - .filter((e) => !(e.startTableId === id || e.endTableId === id)) - .map((e, i) => { - const newR = { ...e }; - - if (e.startTableId > id) { - newR.startTableId = e.startTableId - 1; - } - if (e.endTableId > id) { - newR.endTableId = e.endTableId - 1; - } - - return { ...newR, id: i }; - }); - }); - setTables((prev) => { - return prev.filter((e) => e.id !== id).map((e, i) => ({ ...e, id: i })); - }); - if (id === selectedElement.id) { - setSelectedElement({ - element: ObjectType.NONE, - id: -1, - openDialogue: false, - openCollapse: false, - }); - } - }; - const deleteArea = (id, addToHistory = true) => { if (addToHistory) { setUndoStack((prev) => [ @@ -377,24 +246,6 @@ function WorkSpace() { } }; - const deleteRelationship = (id, addToHistory = true) => { - if (addToHistory) { - setUndoStack((prev) => [ - ...prev, - { - action: Action.DELETE, - element: ObjectType.RELATIONSHIP, - data: relationships[id], - message: `Delete relationship`, - }, - ]); - setRedoStack([]); - } - setRelationships((prev) => - prev.filter((e) => e.id !== id).map((e, i) => ({ ...e, id: i })) - ); - }; - const updateArea = (id, values) => { setAreas((prev) => prev.map((t) => { @@ -423,36 +274,6 @@ function WorkSpace() { ); }; - const updateTable = (id, updatedValues, updateRelationships = false) => { - setTables((prev) => - prev.map((table) => { - if (table.id === id) { - if (updateRelationships) { - setRelationships((prev) => - prev.map((r) => { - let newR = { ...r }; - if (r.startTableId === id) { - newR.startX = updatedValues.x + 15; - newR.startY = updatedValues.y + r.startFieldId * 36 + 69; - } - if (r.endTableId === id) { - newR.endX = updatedValues.x + 15; - newR.endY = updatedValues.y + r.endFieldId * 36 + 69; - } - return newR; - }) - ); - } - return { - ...table, - ...updatedValues, - }; - } - return table; - }) - ); - }; - const updateTask = (id, values) => setTasks((prev) => prev.map((task, i) => (id === i ? { ...task, ...values } : task)) @@ -683,134 +504,114 @@ function WorkSpace() { break; } } - }, [setSettings, setTransform]); + }, [ + setSettings, + setTransform, + setRedoStack, + setUndoStack, + setRelationships, + setTables, + ]); return ( - - - - - - + +
+ + + +
setResize(false)} + onMouseMove={dragHandler} > - - -
- -
setResize(false)} - onMouseMove={dragHandler} - > - {layout.sidebar && ( - - )} -
- - {!( - layout.sidebar || - layout.toolbar || - layout.header - ) && ( -
-
- - -
- {parseInt(transform.zoom * 100)}% -
- - -
- - - -
- )} + {layout.sidebar && ( + + )} +
+ + {!(layout.sidebar || layout.toolbar || layout.header) && ( +
+
+ + +
+ {parseInt(transform.zoom * 100)}%
+ +
+ + +
- - - - - - - - + )} +
+
+
+ + + + ); }