From 5b5e55e3454a8d342a8e3db5c96a29306a91f779 Mon Sep 17 00:00:00 2001 From: 1ilit Date: Tue, 19 Sep 2023 15:50:28 +0300 Subject: [PATCH] edit elements --- src/components/area.jsx | 32 ++++++++++--- src/components/canvas.jsx | 14 +++++- src/components/control_panel.jsx | 69 ++++++++++++++++++++++++++- src/components/editor_panel.jsx | 5 +- src/components/note.jsx | 31 +++++++++++-- src/components/table.jsx | 48 ++++++++++++------- src/components/table_overview.jsx | 22 +++++++-- src/pages/editor.jsx | 77 ++++++++++++++++++------------- 8 files changed, 225 insertions(+), 73 deletions(-) diff --git a/src/components/area.jsx b/src/components/area.jsx index 973e029..3708f50 100644 --- a/src/components/area.jsx +++ b/src/components/area.jsx @@ -15,19 +15,20 @@ import { import { AreaContext, LayoutContext, + SelectContext, TabContext, UndoRedoContext, } from "../pages/editor"; export default function Area(props) { const [hovered, setHovered] = useState(false); - const [visible, setVisible] = useState(false); const [saved, setSaved] = useState(false); const [editField, setEditField] = useState({}); const { layout } = useContext(LayoutContext); const { tab, setTab } = useContext(TabContext); const { updateArea, deleteArea } = useContext(AreaContext); const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); + const { selectedElement, setSelectedElement } = useContext(SelectContext); const handleMouseDown = (e, dir) => { props.setResize({ id: props.areaData.id, dir: dir }); @@ -46,7 +47,6 @@ export default function Area(props) { onMouseEnter={() => setHovered(true)} onMouseLeave={() => { setHovered(false); - setVisible(false); setSaved(false); }} > @@ -73,10 +73,26 @@ export default function Area(props) {
{props.areaData.name}
- {hovered && ( + {(hovered || + (selectedElement.element === ObjectType.AREA && + selectedElement.id === props.areaData.id && + selectedElement.openDialogue && + !layout.sidebar)) && (
{ + setSelectedElement((prev) => ({ + ...prev, + openDialogue: false, + })); + }} + stopPropagation content={
@@ -200,7 +216,6 @@ export default function Area(props) {
} - trigger="click" position="rightTop" showArrow > @@ -268,7 +283,12 @@ export default function Area(props) { .getElementById(`scroll_area_${props.areaData.id}`) .scrollIntoView({ behavior: "smooth" }); } else { - setVisible(true); + setSelectedElement({ + element: ObjectType.AREA, + id: props.areaData.id, + openDialogue: true, + openCollapse: false, + }); } }} > diff --git a/src/components/canvas.jsx b/src/components/canvas.jsx index 28fcfb5..cdcda37 100644 --- a/src/components/canvas.jsx +++ b/src/components/canvas.jsx @@ -9,6 +9,7 @@ import { SettingsContext, TableContext, UndoRedoContext, + SelectContext, } from "../pages/editor"; import Note from "./note"; @@ -19,6 +20,7 @@ export default function Canvas(props) { const { notes, updateNote } = useContext(NoteContext); const { settings, setSettings } = useContext(SettingsContext); const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); + const { selectedElement, setSelectedElement } = useContext(SelectContext); const [dragging, setDragging] = useState({ element: ObjectType.NONE, id: -1, @@ -100,6 +102,7 @@ export default function Canvas(props) { prevY: note.y, }); } + setSelectedElement({ element: type, id: id, openDialogue: false, openCollapse: false }); }; const handleMouseMove = (e) => { @@ -243,6 +246,7 @@ export default function Canvas(props) { }, ]); setRedoStack([]); + setSelectedElement({ element: ObjectType.NONE, id: -1 }); } setPanning({ state: false, x: 0, y: 0 }); setCursor("default"); @@ -396,8 +400,14 @@ export default function Canvas(props) { onMouseDown={(e) => handleMouseDownRect(e, table.id, ObjectType.TABLE) } - selectedTable={props.selectedTable} - setSelectedTable={props.setSelectedTable} + active={ + selectedElement.element === ObjectType.TABLE && + selectedElement.id === table.id + } + moving={ + dragging.element === ObjectType.TABLE && + dragging.id === table.id + } /> ))} {linking && ( diff --git a/src/components/control_panel.jsx b/src/components/control_panel.jsx index 42cc95a..7b9bc0e 100644 --- a/src/components/control_panel.jsx +++ b/src/components/control_panel.jsx @@ -40,12 +40,14 @@ import { AreaContext, LayoutContext, NoteContext, + SelectContext, SettingsContext, + TabContext, TableContext, UndoRedoContext, } from "../pages/editor"; import { IconAddTable, IconAddArea, IconAddNote } from "./custom_icons"; -import { ObjectType, Action } from "../data/data"; +import { ObjectType, Action, Tab } from "../data/data"; import CodeMirror from "@uiw/react-codemirror"; import { json } from "@codemirror/lang-json"; import jsPDF from "jspdf"; @@ -95,6 +97,8 @@ export default function ControlPanel(props) { useContext(AreaContext); const { undoStack, redoStack, setUndoStack, setRedoStack } = useContext(UndoRedoContext); + const { selectedElement, setSelectedElement } = useContext(SelectContext); + const { tab, setTab } = useContext(TabContext); const invertLayout = (component) => setLayout((prev) => ({ ...prev, [component]: !prev[component] })); @@ -422,6 +426,60 @@ export default function ControlPanel(props) { pan: { x: translateX, y: translateY }, })); }; + const edit = () => { + if (selectedElement.element === ObjectType.TABLE) { + if (!layout.sidebar) { + setSelectedElement({ + element: ObjectType.TABLE, + id: selectedElement.id, + openDialogue: true, + openCollapse: false, + }); + } else { + setTab(Tab.tables); + setSelectedElement({ + element: ObjectType.TABLE, + id: selectedElement.id, + openDialogue: false, + openCollapse: true, + }); + if (tab !== Tab.tables) return; + document + .getElementById(`scroll_table_${selectedElement.id}`) + .scrollIntoView({ behavior: "smooth" }); + } + } else if(selectedElement.element===ObjectType.AREA){ + if (layout.sidebar) { + setTab(Tab.subject_areas); + if (tab !== Tab.subject_areas) return; + document + .getElementById(`scroll_area_${selectedElement.id}`) + .scrollIntoView({ behavior: "smooth" }); + } else { + setSelectedElement({ + element: ObjectType.AREA, + id: selectedElement.id, + openDialogue: true, + openCollapse: false, + }); + } + } else if(selectedElement.element===ObjectType.NOTE){ + if (layout.sidebar) { + setTab(Tab.notes); + if (tab !== Tab.notes) return; + document + .getElementById(`scroll_note_${selectedElement.id}`) + .scrollIntoView({ behavior: "smooth" }); + } else { + setSelectedElement({ + element: ObjectType.NOTE, + id: selectedElement.id, + openDialogue: true, + openCollapse: false, + }); + } + } + }; const menu = { File: { @@ -591,22 +649,28 @@ export default function ControlPanel(props) { }, }, Edit: { - function: () => {}, + function: edit, + shortcut: "Ctrl+E", }, Cut: { function: () => {}, + shortcut: "Ctrl+X", }, Copy: { function: () => {}, + shortcut: "Ctrl+C", }, Paste: { function: () => {}, + shortcut: "Ctrl+V", }, Duplicate: { function: () => {}, + shortcut: "Ctrl+D", }, Delete: { function: () => {}, + shortcut: "Del", }, "Copy as image": { function: copyAsImage, @@ -698,6 +762,7 @@ export default function ControlPanel(props) { useHotkeys("ctrl+i, meta+i", fileImport, { preventDefault: true }); useHotkeys("ctrl+z, meta+z", undo, { preventDefault: true }); useHotkeys("ctrl+y, meta+y", redo, { preventDefault: true }); + useHotkeys("ctrl+e, meta+e", edit, { preventDefault: true }); useHotkeys("ctrl+shift+g, meta+shift+g", viewGrid, { preventDefault: true }); useHotkeys("ctrl+up, meta+up", zoomIn, { preventDefault: true }); useHotkeys("ctrl+down, meta+down", zoomOut, { preventDefault: true }); diff --git a/src/components/editor_panel.jsx b/src/components/editor_panel.jsx index d6ca63a..15955ee 100644 --- a/src/components/editor_panel.jsx +++ b/src/components/editor_panel.jsx @@ -38,10 +38,7 @@ const EditorPanel = (props) => { { tab: "Notes", itemKey: Tab.notes }, ]; const contentList = [ - , + , , , { const textarea = document.getElementById(`note_${props.data.id}`); @@ -111,10 +112,26 @@ export default function Note(props) { className="w-full resize-none outline-none overflow-y-hidden border-none select-none" style={{ backgroundColor: props.data.color }} > - {hovered && ( + {(hovered || + (selectedElement.element === ObjectType.NOTE && + selectedElement.id === props.data.id && + selectedElement.openDialogue && + !layout.sidebar)) && (
{ + setSelectedElement((prev) => ({ + ...prev, + openDialogue: false, + })); + }} + stopPropagation content={
Edit note
@@ -181,7 +198,6 @@ export default function Note(props) {
} - trigger="click" position="rightTop" showArrow > @@ -249,7 +265,12 @@ export default function Note(props) { .getElementById(`scroll_note_${props.data.id}`) .scrollIntoView({ behavior: "smooth" }); } else { - setVisible(true); + setSelectedElement({ + element: ObjectType.NOTE, + id: props.data.id, + openDialogue: true, + openCollapse: false, + }); } }} > diff --git a/src/components/table.jsx b/src/components/table.jsx index 98390e8..837d522 100644 --- a/src/components/table.jsx +++ b/src/components/table.jsx @@ -33,6 +33,7 @@ import { } from "@douyinfe/semi-ui"; import { LayoutContext, + SelectContext, SettingsContext, TabContext, TableContext, @@ -42,16 +43,17 @@ import { export default function Table(props) { const [isHovered, setIsHovered] = useState(false); const [hoveredField, setHoveredField] = useState(-1); - const [visible, setVisible] = useState(false); + // const [visible, setVisible] = useState(false); + const [editField, setEditField] = useState({}); const { layout } = useContext(LayoutContext); const { deleteTable, updateTable, updateField } = useContext(TableContext); const { tab, setTab } = useContext(TabContext); const { settings } = useContext(SettingsContext); - - const height = props.tableData.fields.length * 36 + 50 + 3; - const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); - const [editField, setEditField] = useState({}); + const { selectedElement, setSelectedElement } = useContext(SelectContext); + + const height = props.tableData.fields.length * 36 + 50 + 7; + return ( <> { setIsHovered(true); @@ -74,9 +76,11 @@ export default function Table(props) { }} >
{ if (!layout.sidebar) { - setVisible(true); + setSelectedElement({ + element: ObjectType.TABLE, + id: props.tableData.id, + openDialogue: true, + openCollapse: false, + }); } else { setTab(Tab.tables); - props.setSelectedTable(`${props.tableData.id}`); + setSelectedElement({ + element: ObjectType.TABLE, + id: props.tableData.id, + openDialogue: false, + openCollapse: true, + }); if (tab !== Tab.tables) return; document .getElementById(`scroll_table_${props.tableData.id}`) @@ -157,7 +171,6 @@ export default function Table(props) { onClick={() => { Toast.success(`Table deleted!`); deleteTable(props.tableData.id); - props.setSelectedTable(""); }} > Delete table @@ -233,8 +246,13 @@ export default function Table(props) { setVisible((prev) => !prev)} + visible={selectedElement.element===ObjectType.TABLE && selectedElement.id===props.tableData.id && selectedElement.openDialogue} + onCancel={() => + setSelectedElement((prev) => ({ + ...prev, + openDialogue: !prev.openDialogue, + })) + } style={{ paddingBottom: "16px" }} >
@@ -878,8 +896,6 @@ export default function Table(props) { onClick={() => { Toast.success(`Table deleted!`); deleteTable(props.tableData.id); - props.setSelectedTable(""); - setVisible(false); }} > diff --git a/src/components/table_overview.jsx b/src/components/table_overview.jsx index 374aa21..274e3b2 100644 --- a/src/components/table_overview.jsx +++ b/src/components/table_overview.jsx @@ -33,7 +33,7 @@ import { IllustrationNoContent, IllustrationNoContentDark, } from "@douyinfe/semi-illustrations"; -import { TableContext, UndoRedoContext } from "../pages/editor"; +import { SelectContext, TableContext, UndoRedoContext } from "../pages/editor"; export default function TableOverview(props) { const [indexActiveKey, setIndexActiveKey] = useState(""); @@ -41,6 +41,7 @@ export default function TableOverview(props) { const { tables, addTable, deleteTable, updateField, updateTable } = useContext(TableContext); const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); + const { selectedElement, setSelectedElement } = useContext(SelectContext); const [editField, setEditField] = useState({}); const [filteredResult, setFilteredResult] = useState( tables.map((t) => { @@ -72,7 +73,12 @@ export default function TableOverview(props) { onChange={(v) => setValue(v)} onSelect={(v) => { const { id } = tables.find((t) => t.name === v); - props.setSelectedTable(`${id}`); + setSelectedElement({ + element: ObjectType.TABLE, + id: id, + openDialogue: false, + openCollapse: true, + }); document .getElementById(`scroll_table_${id}`) .scrollIntoView({ behavior: "smooth" }); @@ -87,8 +93,15 @@ export default function TableOverview(props) { props.setSelectedTable(k)} + activeKey={selectedElement.openCollapse ? `${selectedElement.id}` : ""} + onChange={(k) => + setSelectedElement({ + element: ObjectType.TABLE, + id: parseInt(k), + openDialogue: false, + openCollapse: true, + }) + } accordion > {tables.length <= 0 ? ( @@ -746,7 +759,6 @@ export default function TableOverview(props) { onClick={() => { Toast.success(`Table deleted!`); deleteTable(i); - props.setSelectedTable(""); }} > diff --git a/src/pages/editor.jsx b/src/pages/editor.jsx index bd2f44c..fd8bd3c 100644 --- a/src/pages/editor.jsx +++ b/src/pages/editor.jsx @@ -20,6 +20,7 @@ export const TabContext = createContext(); export const NoteContext = createContext(); export const SettingsContext = createContext(); export const UndoRedoContext = createContext(); +export const SelectContext = createContext(); export default function Editor(props) { const [code, setCode] = useState(""); @@ -29,7 +30,6 @@ export default function Editor(props) { const [notes, setNotes] = useState([]); const [resize, setResize] = useState(false); const [width, setWidth] = useState(340); - const [selectedTable, setSelectedTable] = useState(""); const [tab, setTab] = useState(Tab.tables); const [layout, setLayout] = useState({ header: true, @@ -52,6 +52,12 @@ export default function Editor(props) { }); const [undoStack, setUndoStack] = useState([]); const [redoStack, setRedoStack] = useState([]); + const [selectedElement, setSelectedElement] = useState({ + element: ObjectType.NONE, + id: -1, + openDialogue: false, + openCollapse: false, + }); const dragHandler = (e) => { if (!resize) return; @@ -226,6 +232,14 @@ export default function Editor(props) { setTables((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 deleteArea = (id, addToHistory = true) => { @@ -372,39 +386,36 @@ export default function Editor(props) { -
- -
setResize(false)} - onMouseMove={dragHandler} - > - - {layout.sidebar && ( - - )} - - - {layout.services && } + +
+ +
setResize(false)} + onMouseMove={dragHandler} + > + + {layout.sidebar && ( + + )} + + + {layout.services && } +
-
+