edit elements

This commit is contained in:
1ilit 2023-09-19 15:50:28 +03:00
parent d571a09b39
commit 5b5e55e345
8 changed files with 225 additions and 73 deletions

View File

@ -15,19 +15,20 @@ import {
import { import {
AreaContext, AreaContext,
LayoutContext, LayoutContext,
SelectContext,
TabContext, TabContext,
UndoRedoContext, UndoRedoContext,
} from "../pages/editor"; } from "../pages/editor";
export default function Area(props) { export default function Area(props) {
const [hovered, setHovered] = useState(false); const [hovered, setHovered] = useState(false);
const [visible, setVisible] = useState(false);
const [saved, setSaved] = useState(false); const [saved, setSaved] = useState(false);
const [editField, setEditField] = useState({}); const [editField, setEditField] = useState({});
const { layout } = useContext(LayoutContext); const { layout } = useContext(LayoutContext);
const { tab, setTab } = useContext(TabContext); const { tab, setTab } = useContext(TabContext);
const { updateArea, deleteArea } = useContext(AreaContext); const { updateArea, deleteArea } = useContext(AreaContext);
const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
const { selectedElement, setSelectedElement } = useContext(SelectContext);
const handleMouseDown = (e, dir) => { const handleMouseDown = (e, dir) => {
props.setResize({ id: props.areaData.id, dir: dir }); props.setResize({ id: props.areaData.id, dir: dir });
@ -46,7 +47,6 @@ export default function Area(props) {
onMouseEnter={() => setHovered(true)} onMouseEnter={() => setHovered(true)}
onMouseLeave={() => { onMouseLeave={() => {
setHovered(false); setHovered(false);
setVisible(false);
setSaved(false); setSaved(false);
}} }}
> >
@ -73,10 +73,26 @@ export default function Area(props) {
<div className="text-gray-900 absolute top-2 left-3 select-none"> <div className="text-gray-900 absolute top-2 left-3 select-none">
{props.areaData.name} {props.areaData.name}
</div> </div>
{hovered && ( {(hovered ||
(selectedElement.element === ObjectType.AREA &&
selectedElement.id === props.areaData.id &&
selectedElement.openDialogue &&
!layout.sidebar)) && (
<div className="absolute top-2 right-3"> <div className="absolute top-2 right-3">
<Popover <Popover
visible={visible} visible={
selectedElement.element === ObjectType.AREA &&
selectedElement.id === props.areaData.id &&
selectedElement.openDialogue &&
!layout.sidebar
}
onClickOutSide={() => {
setSelectedElement((prev) => ({
...prev,
openDialogue: false,
}));
}}
stopPropagation
content={ content={
<div> <div>
<div className="font-semibold mb-2 ms-1"> <div className="font-semibold mb-2 ms-1">
@ -200,7 +216,6 @@ export default function Area(props) {
</div> </div>
</div> </div>
} }
trigger="click"
position="rightTop" position="rightTop"
showArrow showArrow
> >
@ -268,7 +283,12 @@ export default function Area(props) {
.getElementById(`scroll_area_${props.areaData.id}`) .getElementById(`scroll_area_${props.areaData.id}`)
.scrollIntoView({ behavior: "smooth" }); .scrollIntoView({ behavior: "smooth" });
} else { } else {
setVisible(true); setSelectedElement({
element: ObjectType.AREA,
id: props.areaData.id,
openDialogue: true,
openCollapse: false,
});
} }
}} }}
></Button> ></Button>

View File

@ -9,6 +9,7 @@ import {
SettingsContext, SettingsContext,
TableContext, TableContext,
UndoRedoContext, UndoRedoContext,
SelectContext,
} from "../pages/editor"; } from "../pages/editor";
import Note from "./note"; import Note from "./note";
@ -19,6 +20,7 @@ export default function Canvas(props) {
const { notes, updateNote } = useContext(NoteContext); const { notes, updateNote } = useContext(NoteContext);
const { settings, setSettings } = useContext(SettingsContext); const { settings, setSettings } = useContext(SettingsContext);
const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
const { selectedElement, setSelectedElement } = useContext(SelectContext);
const [dragging, setDragging] = useState({ const [dragging, setDragging] = useState({
element: ObjectType.NONE, element: ObjectType.NONE,
id: -1, id: -1,
@ -100,6 +102,7 @@ export default function Canvas(props) {
prevY: note.y, prevY: note.y,
}); });
} }
setSelectedElement({ element: type, id: id, openDialogue: false, openCollapse: false });
}; };
const handleMouseMove = (e) => { const handleMouseMove = (e) => {
@ -243,6 +246,7 @@ export default function Canvas(props) {
}, },
]); ]);
setRedoStack([]); setRedoStack([]);
setSelectedElement({ element: ObjectType.NONE, id: -1 });
} }
setPanning({ state: false, x: 0, y: 0 }); setPanning({ state: false, x: 0, y: 0 });
setCursor("default"); setCursor("default");
@ -396,8 +400,14 @@ export default function Canvas(props) {
onMouseDown={(e) => onMouseDown={(e) =>
handleMouseDownRect(e, table.id, ObjectType.TABLE) handleMouseDownRect(e, table.id, ObjectType.TABLE)
} }
selectedTable={props.selectedTable} active={
setSelectedTable={props.setSelectedTable} selectedElement.element === ObjectType.TABLE &&
selectedElement.id === table.id
}
moving={
dragging.element === ObjectType.TABLE &&
dragging.id === table.id
}
/> />
))} ))}
{linking && ( {linking && (

View File

@ -40,12 +40,14 @@ import {
AreaContext, AreaContext,
LayoutContext, LayoutContext,
NoteContext, NoteContext,
SelectContext,
SettingsContext, SettingsContext,
TabContext,
TableContext, TableContext,
UndoRedoContext, UndoRedoContext,
} from "../pages/editor"; } from "../pages/editor";
import { IconAddTable, IconAddArea, IconAddNote } from "./custom_icons"; 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 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";
@ -95,6 +97,8 @@ export default function ControlPanel(props) {
useContext(AreaContext); useContext(AreaContext);
const { undoStack, redoStack, setUndoStack, setRedoStack } = const { undoStack, redoStack, setUndoStack, setRedoStack } =
useContext(UndoRedoContext); useContext(UndoRedoContext);
const { selectedElement, setSelectedElement } = useContext(SelectContext);
const { tab, setTab } = useContext(TabContext);
const invertLayout = (component) => const invertLayout = (component) =>
setLayout((prev) => ({ ...prev, [component]: !prev[component] })); setLayout((prev) => ({ ...prev, [component]: !prev[component] }));
@ -422,6 +426,60 @@ export default function ControlPanel(props) {
pan: { x: translateX, y: translateY }, 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 = { const menu = {
File: { File: {
@ -591,22 +649,28 @@ export default function ControlPanel(props) {
}, },
}, },
Edit: { Edit: {
function: () => {}, function: edit,
shortcut: "Ctrl+E",
}, },
Cut: { Cut: {
function: () => {}, function: () => {},
shortcut: "Ctrl+X",
}, },
Copy: { Copy: {
function: () => {}, function: () => {},
shortcut: "Ctrl+C",
}, },
Paste: { Paste: {
function: () => {}, function: () => {},
shortcut: "Ctrl+V",
}, },
Duplicate: { Duplicate: {
function: () => {}, function: () => {},
shortcut: "Ctrl+D",
}, },
Delete: { Delete: {
function: () => {}, function: () => {},
shortcut: "Del",
}, },
"Copy as image": { "Copy as image": {
function: copyAsImage, function: copyAsImage,
@ -698,6 +762,7 @@ export default function ControlPanel(props) {
useHotkeys("ctrl+i, meta+i", fileImport, { preventDefault: true }); useHotkeys("ctrl+i, meta+i", fileImport, { preventDefault: true });
useHotkeys("ctrl+z, meta+z", undo, { preventDefault: true }); useHotkeys("ctrl+z, meta+z", undo, { preventDefault: true });
useHotkeys("ctrl+y, meta+y", redo, { 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+shift+g, meta+shift+g", viewGrid, { preventDefault: true });
useHotkeys("ctrl+up, meta+up", zoomIn, { preventDefault: true }); useHotkeys("ctrl+up, meta+up", zoomIn, { preventDefault: true });
useHotkeys("ctrl+down, meta+down", zoomOut, { preventDefault: true }); useHotkeys("ctrl+down, meta+down", zoomOut, { preventDefault: true });

View File

@ -38,10 +38,7 @@ const EditorPanel = (props) => {
{ tab: "Notes", itemKey: Tab.notes }, { tab: "Notes", itemKey: Tab.notes },
]; ];
const contentList = [ const contentList = [
<TableOverview <TableOverview />,
selectedTable={props.selectedTable}
setSelectedTable={props.setSelectedTable}
/>,
<ReferenceOverview />, <ReferenceOverview />,
<AreaOverview />, <AreaOverview />,
<CodeMirror <CodeMirror

View File

@ -4,6 +4,7 @@ import {
NoteContext, NoteContext,
UndoRedoContext, UndoRedoContext,
TabContext, TabContext,
SelectContext,
} from "../pages/editor"; } from "../pages/editor";
import { Action, ObjectType, noteThemes, Tab } from "../data/data"; import { Action, ObjectType, noteThemes, Tab } from "../data/data";
import { Input, Button, Popover, Toast } from "@douyinfe/semi-ui"; import { Input, Button, Popover, Toast } from "@douyinfe/semi-ui";
@ -16,7 +17,6 @@ import {
export default function Note(props) { export default function Note(props) {
const [editField, setEditField] = useState({}); const [editField, setEditField] = useState({});
const [hovered, setHovered] = useState(false); const [hovered, setHovered] = useState(false);
const [visible, setVisible] = useState(false);
const [saved, setSaved] = useState(false); const [saved, setSaved] = useState(false);
const w = 180; const w = 180;
const r = 3; const r = 3;
@ -25,6 +25,7 @@ export default function Note(props) {
const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
const { layout } = useContext(LayoutContext); const { layout } = useContext(LayoutContext);
const { tab, setTab } = useContext(TabContext); const { tab, setTab } = useContext(TabContext);
const { selectedElement, setSelectedElement } = useContext(SelectContext);
const handleChange = (e) => { const handleChange = (e) => {
const textarea = document.getElementById(`note_${props.data.id}`); 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" className="w-full resize-none outline-none overflow-y-hidden border-none select-none"
style={{ backgroundColor: props.data.color }} style={{ backgroundColor: props.data.color }}
></textarea> ></textarea>
{hovered && ( {(hovered ||
(selectedElement.element === ObjectType.NOTE &&
selectedElement.id === props.data.id &&
selectedElement.openDialogue &&
!layout.sidebar)) && (
<div className="absolute top-2 right-3"> <div className="absolute top-2 right-3">
<Popover <Popover
visible={visible} visible={
selectedElement.element === ObjectType.NOTE &&
selectedElement.id === props.data.id &&
selectedElement.openDialogue &&
!layout.sidebar
}
onClickOutSide={() => {
setSelectedElement((prev) => ({
...prev,
openDialogue: false,
}));
}}
stopPropagation
content={ content={
<div> <div>
<div className="font-semibold mb-2 ms-1">Edit note</div> <div className="font-semibold mb-2 ms-1">Edit note</div>
@ -181,7 +198,6 @@ export default function Note(props) {
</div> </div>
</div> </div>
} }
trigger="click"
position="rightTop" position="rightTop"
showArrow showArrow
> >
@ -249,7 +265,12 @@ export default function Note(props) {
.getElementById(`scroll_note_${props.data.id}`) .getElementById(`scroll_note_${props.data.id}`)
.scrollIntoView({ behavior: "smooth" }); .scrollIntoView({ behavior: "smooth" });
} else { } else {
setVisible(true); setSelectedElement({
element: ObjectType.NOTE,
id: props.data.id,
openDialogue: true,
openCollapse: false,
});
} }
}} }}
></Button> ></Button>

View File

@ -33,6 +33,7 @@ import {
} from "@douyinfe/semi-ui"; } from "@douyinfe/semi-ui";
import { import {
LayoutContext, LayoutContext,
SelectContext,
SettingsContext, SettingsContext,
TabContext, TabContext,
TableContext, TableContext,
@ -42,16 +43,17 @@ import {
export default function Table(props) { export default function Table(props) {
const [isHovered, setIsHovered] = useState(false); const [isHovered, setIsHovered] = useState(false);
const [hoveredField, setHoveredField] = useState(-1); const [hoveredField, setHoveredField] = useState(-1);
const [visible, setVisible] = useState(false); // const [visible, setVisible] = useState(false);
const [editField, setEditField] = useState({});
const { layout } = useContext(LayoutContext); const { layout } = useContext(LayoutContext);
const { deleteTable, updateTable, updateField } = useContext(TableContext); const { deleteTable, updateTable, updateField } = useContext(TableContext);
const { tab, setTab } = useContext(TabContext); const { tab, setTab } = useContext(TabContext);
const { settings } = useContext(SettingsContext); const { settings } = useContext(SettingsContext);
const height = props.tableData.fields.length * 36 + 50 + 3;
const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
const [editField, setEditField] = useState({}); const { selectedElement, setSelectedElement } = useContext(SelectContext);
const height = props.tableData.fields.length * 36 + 50 + 7;
return ( return (
<> <>
<foreignObject <foreignObject
@ -60,7 +62,7 @@ export default function Table(props) {
y={props.tableData.y} y={props.tableData.y}
width={200} width={200}
height={height} height={height}
className="shadow-lg rounded-md cursor-move" className="drop-shadow-lg rounded-md cursor-move"
onMouseDown={props.onMouseDown} onMouseDown={props.onMouseDown}
onMouseEnter={() => { onMouseEnter={() => {
setIsHovered(true); setIsHovered(true);
@ -74,9 +76,11 @@ export default function Table(props) {
}} }}
> >
<div <div
className={`border-2 ${ className={`border-2 border-gray-400 ${
isHovered ? "border-sky-500" : "border-gray-400" props.active && !props.moving && "border-blue-500 border-4"
} bg-gray-100 select-none rounded-md w-full`} } ${
props.moving && "border-blue-500 border-4 border-dashed"
} bg-gray-100 select-none rounded-lg w-full`}
> >
<div <div
className={`h-[10px] w-full rounded-t-md`} className={`h-[10px] w-full rounded-t-md`}
@ -97,10 +101,20 @@ export default function Table(props) {
}} }}
onClick={() => { onClick={() => {
if (!layout.sidebar) { if (!layout.sidebar) {
setVisible(true); setSelectedElement({
element: ObjectType.TABLE,
id: props.tableData.id,
openDialogue: true,
openCollapse: false,
});
} else { } else {
setTab(Tab.tables); 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; if (tab !== Tab.tables) return;
document document
.getElementById(`scroll_table_${props.tableData.id}`) .getElementById(`scroll_table_${props.tableData.id}`)
@ -157,7 +171,6 @@ export default function Table(props) {
onClick={() => { onClick={() => {
Toast.success(`Table deleted!`); Toast.success(`Table deleted!`);
deleteTable(props.tableData.id); deleteTable(props.tableData.id);
props.setSelectedTable("");
}} }}
> >
Delete table Delete table
@ -233,8 +246,13 @@ export default function Table(props) {
<SideSheet <SideSheet
title="Edit table" title="Edit table"
size="small" size="small"
visible={visible} visible={selectedElement.element===ObjectType.TABLE && selectedElement.id===props.tableData.id && selectedElement.openDialogue}
onCancel={() => setVisible((prev) => !prev)} onCancel={() =>
setSelectedElement((prev) => ({
...prev,
openDialogue: !prev.openDialogue,
}))
}
style={{ paddingBottom: "16px" }} style={{ paddingBottom: "16px" }}
> >
<div className="flex items-center"> <div className="flex items-center">
@ -878,8 +896,6 @@ export default function Table(props) {
onClick={() => { onClick={() => {
Toast.success(`Table deleted!`); Toast.success(`Table deleted!`);
deleteTable(props.tableData.id); deleteTable(props.tableData.id);
props.setSelectedTable("");
setVisible(false);
}} }}
></Button> ></Button>
</Col> </Col>

View File

@ -33,7 +33,7 @@ import {
IllustrationNoContent, IllustrationNoContent,
IllustrationNoContentDark, IllustrationNoContentDark,
} from "@douyinfe/semi-illustrations"; } from "@douyinfe/semi-illustrations";
import { TableContext, UndoRedoContext } from "../pages/editor"; import { SelectContext, TableContext, UndoRedoContext } from "../pages/editor";
export default function TableOverview(props) { export default function TableOverview(props) {
const [indexActiveKey, setIndexActiveKey] = useState(""); const [indexActiveKey, setIndexActiveKey] = useState("");
@ -41,6 +41,7 @@ export default function TableOverview(props) {
const { tables, addTable, deleteTable, updateField, updateTable } = const { tables, addTable, deleteTable, updateField, updateTable } =
useContext(TableContext); useContext(TableContext);
const { setUndoStack, setRedoStack } = useContext(UndoRedoContext); const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
const { selectedElement, setSelectedElement } = useContext(SelectContext);
const [editField, setEditField] = useState({}); const [editField, setEditField] = useState({});
const [filteredResult, setFilteredResult] = useState( const [filteredResult, setFilteredResult] = useState(
tables.map((t) => { tables.map((t) => {
@ -72,7 +73,12 @@ export default function TableOverview(props) {
onChange={(v) => setValue(v)} onChange={(v) => setValue(v)}
onSelect={(v) => { onSelect={(v) => {
const { id } = tables.find((t) => t.name === v); const { id } = tables.find((t) => t.name === v);
props.setSelectedTable(`${id}`); setSelectedElement({
element: ObjectType.TABLE,
id: id,
openDialogue: false,
openCollapse: true,
});
document document
.getElementById(`scroll_table_${id}`) .getElementById(`scroll_table_${id}`)
.scrollIntoView({ behavior: "smooth" }); .scrollIntoView({ behavior: "smooth" });
@ -87,8 +93,15 @@ export default function TableOverview(props) {
</Col> </Col>
</Row> </Row>
<Collapse <Collapse
activeKey={props.selectedTable} activeKey={selectedElement.openCollapse ? `${selectedElement.id}` : ""}
onChange={(k) => props.setSelectedTable(k)} onChange={(k) =>
setSelectedElement({
element: ObjectType.TABLE,
id: parseInt(k),
openDialogue: false,
openCollapse: true,
})
}
accordion accordion
> >
{tables.length <= 0 ? ( {tables.length <= 0 ? (
@ -746,7 +759,6 @@ export default function TableOverview(props) {
onClick={() => { onClick={() => {
Toast.success(`Table deleted!`); Toast.success(`Table deleted!`);
deleteTable(i); deleteTable(i);
props.setSelectedTable("");
}} }}
></Button> ></Button>
</Col> </Col>

View File

@ -20,6 +20,7 @@ export const TabContext = createContext();
export const NoteContext = createContext(); export const NoteContext = createContext();
export const SettingsContext = createContext(); export const SettingsContext = createContext();
export const UndoRedoContext = createContext(); export const UndoRedoContext = createContext();
export const SelectContext = createContext();
export default function Editor(props) { export default function Editor(props) {
const [code, setCode] = useState(""); const [code, setCode] = useState("");
@ -29,7 +30,6 @@ export default function Editor(props) {
const [notes, setNotes] = useState([]); const [notes, setNotes] = useState([]);
const [resize, setResize] = useState(false); const [resize, setResize] = useState(false);
const [width, setWidth] = useState(340); const [width, setWidth] = useState(340);
const [selectedTable, setSelectedTable] = useState("");
const [tab, setTab] = useState(Tab.tables); const [tab, setTab] = useState(Tab.tables);
const [layout, setLayout] = useState({ const [layout, setLayout] = useState({
header: true, header: true,
@ -52,6 +52,12 @@ export default function Editor(props) {
}); });
const [undoStack, setUndoStack] = useState([]); const [undoStack, setUndoStack] = useState([]);
const [redoStack, setRedoStack] = useState([]); const [redoStack, setRedoStack] = useState([]);
const [selectedElement, setSelectedElement] = useState({
element: ObjectType.NONE,
id: -1,
openDialogue: false,
openCollapse: false,
});
const dragHandler = (e) => { const dragHandler = (e) => {
if (!resize) return; if (!resize) return;
@ -226,6 +232,14 @@ export default function Editor(props) {
setTables((prev) => setTables((prev) =>
prev.filter((e) => e.id !== id).map((e, i) => ({ ...e, id: i })) 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) => { const deleteArea = (id, addToHistory = true) => {
@ -372,39 +386,36 @@ export default function Editor(props) {
<UndoRedoContext.Provider <UndoRedoContext.Provider
value={{ undoStack, redoStack, setUndoStack, setRedoStack }} value={{ undoStack, redoStack, setUndoStack, setRedoStack }}
> >
<div className="h-[100vh] overflow-hidden"> <SelectContext.Provider
<ControlPanel /> value={{ selectedElement, setSelectedElement }}
<div >
className={ <div className="h-[100vh] overflow-hidden">
layout.header <ControlPanel />
? `flex h-[calc(100vh-123.93px)]` <div
: `flex h-[calc(100vh-51.97px)]` className={
} layout.header
onMouseUp={() => setResize(false)} ? `flex h-[calc(100vh-123.93px)]`
onMouseMove={dragHandler} : `flex h-[calc(100vh-51.97px)]`
> }
<DndProvider backend={HTML5Backend}> onMouseUp={() => setResize(false)}
{layout.sidebar && ( onMouseMove={dragHandler}
<EditorPanel >
code={code} <DndProvider backend={HTML5Backend}>
setCode={setCode} {layout.sidebar && (
resize={resize} <EditorPanel
setResize={setResize} code={code}
width={width} setCode={setCode}
selectedTable={selectedTable} resize={resize}
setSelectedTable={setSelectedTable} setResize={setResize}
/> width={width}
)} />
<Canvas )}
code={code} <Canvas code={code} setCode={setCode} />
setCode={setCode} </DndProvider>
selectedTable={selectedTable} {layout.services && <Sidebar />}
setSelectedTable={setSelectedTable} </div>
/>
</DndProvider>
{layout.services && <Sidebar />}
</div> </div>
</div> </SelectContext.Provider>
</UndoRedoContext.Provider> </UndoRedoContext.Provider>
</SettingsContext.Provider> </SettingsContext.Provider>
</TabContext.Provider> </TabContext.Provider>