From 54c043204aaa90b315fc47380e649d5c3d21c08c Mon Sep 17 00:00:00 2001 From: 1ilit Date: Tue, 12 Mar 2024 23:36:49 +0200 Subject: [PATCH] Abstract notes out of editor --- src/components/Canvas.jsx | 6 +- src/components/ControlPanel.jsx | 4 +- src/components/Note.jsx | 5 +- src/components/NotesOverview.jsx | 6 +- src/context/NotesContext.jsx | 96 ++++++++++++++++ src/hooks/useNotes.js | 6 + src/pages/Editor.jsx | 188 +++++++++---------------------- 7 files changed, 169 insertions(+), 142 deletions(-) create mode 100644 src/context/NotesContext.jsx create mode 100644 src/hooks/useNotes.js diff --git a/src/components/Canvas.jsx b/src/components/Canvas.jsx index 28b48f0..e6c3994 100644 --- a/src/components/Canvas.jsx +++ b/src/components/Canvas.jsx @@ -1,9 +1,8 @@ -import { useContext, useRef, useState, useEffect } from "react"; +import { useRef, useState, useEffect } from "react"; import Table from "./Table"; import { Action, Cardinality, Constraint, ObjectType } from "../data/data"; import Area from "./Area"; import Relationship from "./Relationship"; -import { NoteContext } from "../pages/Editor"; import Note from "./Note"; import { Toast } from "@douyinfe/semi-ui"; import useSettings from "../hooks/useSettings"; @@ -12,11 +11,12 @@ import useTables from "../hooks/useTables"; import useUndoRedo from "../hooks/useUndoRedo"; import useSelect from "../hooks/useSelect"; import useAreas from "../hooks/useAreas"; +import useNotes from "../hooks/useNotes"; export default function Canvas() { const { tables, updateTable, relationships, addRelationship } = useTables(); const { areas, updateArea } = useAreas(); - const { notes, updateNote } = useContext(NoteContext); + const { notes, updateNote } = useNotes(); const { settings } = useSettings(); const { setUndoStack, setRedoStack } = useUndoRedo(); const { transform, setTransform } = useTransform(); diff --git a/src/components/ControlPanel.jsx b/src/components/ControlPanel.jsx index fe5355d..04a141a 100644 --- a/src/components/ControlPanel.jsx +++ b/src/components/ControlPanel.jsx @@ -44,7 +44,6 @@ import { jsonToSQLServer, } from "../utils/toSQL"; import { - NoteContext, StateContext, TabContext, TypeContext, @@ -71,6 +70,7 @@ import { enterFullscreen, exitFullscreen } from "../utils/fullscreen"; import { ddbDiagramIsValid, jsonDiagramIsValid } from "../utils/validateSchema"; import { dataURItoBlob } from "../utils/utils"; import useAreas from "../hooks/useAreas"; +import useNotes from "../hooks/useNotes"; export default function ControlPanel({ diagramId, @@ -138,7 +138,7 @@ export default function ControlPanel({ const { types, addType, deleteType, updateType, setTypes } = useContext(TypeContext); const { notes, setNotes, updateNote, addNote, deleteNote } = - useContext(NoteContext); + useNotes(); const { areas, setAreas, updateArea, addArea, deleteArea } = useAreas(); const { undoStack, redoStack, setUndoStack, setRedoStack } = useUndoRedo(); const { selectedElement, setSelectedElement } = useSelect(); diff --git a/src/components/Note.jsx b/src/components/Note.jsx index b0c6896..6477da5 100644 --- a/src/components/Note.jsx +++ b/src/components/Note.jsx @@ -1,5 +1,5 @@ import { useContext, useState } from "react"; -import { NoteContext, TabContext, StateContext } from "../pages/Editor"; +import { TabContext, StateContext } from "../pages/Editor"; import { Action, ObjectType, noteThemes, Tab, State } from "../data/data"; import { Input, Button, Popover, Toast } from "@douyinfe/semi-ui"; import { @@ -10,6 +10,7 @@ import { import useLayout from "../hooks/useLayout"; import useUndoRedo from "../hooks/useUndoRedo"; import useSelect from "../hooks/useSelect"; +import useNotes from "../hooks/useNotes"; export default function Note(props) { const [editField, setEditField] = useState({}); @@ -17,7 +18,7 @@ export default function Note(props) { const w = 180; const r = 3; const fold = 24; - const { updateNote, deleteNote } = useContext(NoteContext); + const { updateNote, deleteNote } = useNotes(); const { setUndoStack, setRedoStack } = useUndoRedo(); const { setState } = useContext(StateContext); const { layout } = useLayout(); diff --git a/src/components/NotesOverview.jsx b/src/components/NotesOverview.jsx index c956db8..826ecb2 100644 --- a/src/components/NotesOverview.jsx +++ b/src/components/NotesOverview.jsx @@ -1,4 +1,4 @@ -import { useContext, useState } from "react"; +import { useState } from "react"; import { Empty, Row, @@ -21,12 +21,12 @@ import { IconSearch, IconCheckboxTick, } from "@douyinfe/semi-icons"; -import { NoteContext } from "../pages/Editor"; import { noteThemes, Action, ObjectType } from "../data/data"; import useUndoRedo from "../hooks/useUndoRedo"; +import useNotes from "../hooks/useNotes"; export default function NotesOverview() { - const { notes, updateNote, addNote, deleteNote } = useContext(NoteContext); + const { notes, updateNote, addNote, deleteNote } = useNotes(); const { setUndoStack, setRedoStack } = useUndoRedo(); const [value, setValue] = useState(""); const [editField, setEditField] = useState({}); diff --git a/src/context/NotesContext.jsx b/src/context/NotesContext.jsx new file mode 100644 index 0000000..6b2b69a --- /dev/null +++ b/src/context/NotesContext.jsx @@ -0,0 +1,96 @@ +import { createContext, useState } from "react"; +import useTransform from "../hooks/useTransform"; +import { Action, ObjectType, defaultNoteTheme } from "../data/data"; +import useUndoRedo from "../hooks/useUndoRedo"; +import useSelect from "../hooks/useSelect"; + +export const NotesContext = createContext(null); + +export default function NotesContextProvider({ children }) { + const [notes, setNotes] = useState([]); + const { transform } = useTransform(); + const { setUndoStack, setRedoStack } = useUndoRedo(); + const { selectedElement, setSelectedElement } = useSelect(); + + 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: -transform.pan.x, + y: -transform.pan.y, + title: `note_${prev.length}`, + content: "", + color: defaultNoteTheme, + height: 88, + }, + ]); + } + if (addToHistory) { + setUndoStack((prev) => [ + ...prev, + { + action: Action.ADD, + element: ObjectType.NOTE, + message: `Add new note`, + }, + ]); + setRedoStack([]); + } + }; + + const deleteNote = (id, addToHistory = true) => { + if (addToHistory) { + setUndoStack((prev) => [ + ...prev, + { + action: Action.DELETE, + element: ObjectType.NOTE, + data: notes[id], + message: `Delete note`, + }, + ]); + setRedoStack([]); + } + setNotes((prev) => + 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 updateNote = (id, values) => { + setNotes((prev) => + prev.map((t) => { + if (t.id === id) { + return { + ...t, + ...values, + }; + } + return t; + }) + ); + }; + + return ( + + {children} + + ); +} diff --git a/src/hooks/useNotes.js b/src/hooks/useNotes.js new file mode 100644 index 0000000..838866b --- /dev/null +++ b/src/hooks/useNotes.js @@ -0,0 +1,6 @@ +import { useContext } from "react"; +import { NotesContext } from "../context/NotesContext"; + +export default function useNotes() { + return useContext(NotesContext); +} diff --git a/src/pages/Editor.jsx b/src/pages/Editor.jsx index ebe4844..622a856 100644 --- a/src/pages/Editor.jsx +++ b/src/pages/Editor.jsx @@ -2,7 +2,7 @@ import { useState, createContext, useEffect, useCallback } from "react"; import ControlPanel from "../components/ControlPanel"; import Canvas from "../components/Canvas"; import SidePanel from "../components/SidePanel"; -import { Tab, defaultNoteTheme, Action, ObjectType, State } from "../data/data"; +import { Tab, Action, ObjectType, State } from "../data/data"; import { db } from "../data/db"; import useLayout from "../hooks/useLayout"; import LayoutContextProvider from "../context/LayoutContext"; @@ -15,13 +15,13 @@ import useUndoRedo from "../hooks/useUndoRedo"; import UndoRedoContextProvider from "../context/UndoRedoContext"; import SelectContextProvider from "../context/SelectContext"; import AreasContextProvider from "../context/AreasContext"; -import useSelect from "../hooks/useSelect"; import Controls from "../components/Controls"; import useAreas from "../hooks/useAreas"; +import useNotes from "../hooks/useNotes"; +import NotesContextProvider from "../context/NotesContext"; export const StateContext = createContext(); export const TabContext = createContext(); -export const NoteContext = createContext(); export const TaskContext = createContext(); export const TypeContext = createContext(); @@ -32,9 +32,11 @@ export default function Editor() { - - - + + + + + @@ -48,18 +50,17 @@ function WorkSpace() { const [title, setTitle] = useState("Untitled Diagram"); const [state, setState] = useState(State.NONE); const [lastSaved, setLastSaved] = useState(""); - const { tables, relationships, setTables, setRelationships } = useTables(); - const [notes, setNotes] = useState([]); const [types, setTypes] = useState([]); const [resize, setResize] = useState(false); const [width, setWidth] = useState(340); const [tab, setTab] = useState(Tab.tables); - const { layout } = useLayout(); - const { settings, setSettings } = useSettings(); - const { transform, setTransform } = useTransform(); - const { selectedElement, setSelectedElement } = useSelect(); - const { areas, setAreas } = useAreas(); const [tasks, setTasks] = useState([]); + const { layout } = useLayout(); + const { areas, setAreas } = useAreas(); + const { settings, setSettings } = useSettings(); + const { notes, setNotes } = useNotes(); + const { transform, setTransform } = useTransform(); + const { tables, relationships, setTables, setRelationships } = useTables(); const { undoStack, redoStack, setUndoStack, setRedoStack } = useUndoRedo(); const dragHandler = (e) => { @@ -121,80 +122,6 @@ function WorkSpace() { ); }; - 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: -transform.pan.x, - y: -transform.pan.y, - title: `note_${prev.length}`, - content: "", - color: defaultNoteTheme, - height: 88, - }, - ]); - } - if (addToHistory) { - setUndoStack((prev) => [ - ...prev, - { - action: Action.ADD, - element: ObjectType.NOTE, - message: `Add new note`, - }, - ]); - setRedoStack([]); - } - }; - - const deleteNote = (id, addToHistory = true) => { - if (addToHistory) { - setUndoStack((prev) => [ - ...prev, - { - action: Action.DELETE, - element: ObjectType.NOTE, - data: notes[id], - message: `Delete note`, - }, - ]); - setRedoStack([]); - } - setNotes((prev) => - 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 updateNote = (id, values) => { - setNotes((prev) => - prev.map((t) => { - if (t.id === id) { - return { - ...t, - ...values, - }; - } - return t; - }) - ); - }; - const updateTask = (id, values) => setTasks((prev) => prev.map((task, i) => (id === i ? { ...task, ...values } : task)) @@ -433,59 +360,56 @@ function WorkSpace() { setRelationships, setTables, setAreas, + setNotes, ]); return ( - - - -
- - + +
+ + + +
setResize(false)} + onMouseMove={dragHandler} + > + {layout.sidebar && ( + - -
setResize(false)} - onMouseMove={dragHandler} - > - {layout.sidebar && ( - + )} +
+ + {!(layout.sidebar || layout.toolbar || layout.header) && ( +
+ +
)} -
- - {!(layout.sidebar || layout.toolbar || layout.header) && ( -
- -
- )} -
- - - +
+ + ); }