layout context

This commit is contained in:
1ilit 2023-09-19 15:48:46 +03:00
parent f899834401
commit 23e58a0110
3 changed files with 84 additions and 59 deletions

View File

@ -1,4 +1,4 @@
import { React, useState } from "react"; import { React, useContext, useState } from "react";
import { import {
IconCaretdown, IconCaretdown,
IconChevronRight, IconChevronRight,
@ -22,6 +22,7 @@ import {
import { toPng, toJpeg, toSvg } from "html-to-image"; import { toPng, toJpeg, toSvg } from "html-to-image";
import { saveAs } from "file-saver"; import { saveAs } from "file-saver";
import { enterFullscreen, exitFullscreen } from "../utils"; import { enterFullscreen, exitFullscreen } from "../utils";
import { LayoutContext } from "../pages/editor";
export default function ControlPanel(props) { export default function ControlPanel(props) {
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
@ -30,6 +31,7 @@ export default function ControlPanel(props) {
`diagram_${new Date().toISOString()}` `diagram_${new Date().toISOString()}`
); );
const [extension, setExtension] = useState(""); const [extension, setExtension] = useState("");
const {layout, setLayout} = useContext(LayoutContext);
const menu = { const menu = {
File: { File: {
@ -237,7 +239,7 @@ export default function ControlPanel(props) {
return ( return (
<div> <div>
{props.layout.header && header()} {layout.header && header()}
<div className="p-2 px-5 flex justify-between items-center rounded-xl bg-slate-100 my-1 sm:mx-1 md:mx-6 text-slate-700 select-none overflow-x-hidden"> <div className="p-2 px-5 flex justify-between items-center rounded-xl bg-slate-100 my-1 sm:mx-1 md:mx-6 text-slate-700 select-none overflow-x-hidden">
<div className="flex justify-start items-center"> <div className="flex justify-start items-center">
{layoutDropdown()} {layoutDropdown()}
@ -341,10 +343,10 @@ export default function ControlPanel(props) {
</div> </div>
<button <button
onClick={(e) => onClick={(e) =>
props.setLayout((prev) => ({ ...prev, header: !prev.header })) setLayout((prev) => ({ ...prev, header: !prev.header }))
} }
> >
{props.layout.header ? <IconChevronUp /> : <IconChevronDown />} {layout.header ? <IconChevronUp /> : <IconChevronDown />}
</button> </button>
</div> </div>
<Modal <Modal
@ -511,14 +513,14 @@ export default function ControlPanel(props) {
<Dropdown.Menu> <Dropdown.Menu>
<Dropdown.Item <Dropdown.Item
icon={ icon={
props.layout.header ? ( layout.header ? (
<IconCheckboxTick /> <IconCheckboxTick />
) : ( ) : (
<div className="px-2"></div> <div className="px-2"></div>
) )
} }
onClick={() => onClick={() =>
props.setLayout((prev) => ({ setLayout((prev) => ({
...prev, ...prev,
header: !prev.header, header: !prev.header,
})) }))
@ -532,14 +534,14 @@ export default function ControlPanel(props) {
<Dropdown.Menu> <Dropdown.Menu>
<Dropdown.Item <Dropdown.Item
icon={ icon={
props.layout.tables ? ( layout.tables ? (
<IconCheckboxTick /> <IconCheckboxTick />
) : ( ) : (
<div className="px-2"></div> <div className="px-2"></div>
) )
} }
onClick={() => onClick={() =>
props.setLayout((prev) => ({ setLayout((prev) => ({
...prev, ...prev,
tables: !prev.tables, tables: !prev.tables,
})) }))
@ -549,14 +551,14 @@ export default function ControlPanel(props) {
</Dropdown.Item> </Dropdown.Item>
<Dropdown.Item <Dropdown.Item
icon={ icon={
props.layout.relationships ? ( layout.relationships ? (
<IconCheckboxTick /> <IconCheckboxTick />
) : ( ) : (
<div className="px-2"></div> <div className="px-2"></div>
) )
} }
onClick={() => onClick={() =>
props.setLayout((prev) => ({ setLayout((prev) => ({
...prev, ...prev,
relationships: !prev.relationships, relationships: !prev.relationships,
})) }))
@ -566,14 +568,14 @@ export default function ControlPanel(props) {
</Dropdown.Item> </Dropdown.Item>
<Dropdown.Item <Dropdown.Item
icon={ icon={
props.layout.issues ? ( layout.issues ? (
<IconCheckboxTick /> <IconCheckboxTick />
) : ( ) : (
<div className="px-2"></div> <div className="px-2"></div>
) )
} }
onClick={() => onClick={() =>
props.setLayout((prev) => ({ setLayout((prev) => ({
...prev, ...prev,
issues: !prev.issues, issues: !prev.issues,
})) }))
@ -583,14 +585,14 @@ export default function ControlPanel(props) {
</Dropdown.Item> </Dropdown.Item>
<Dropdown.Item <Dropdown.Item
icon={ icon={
props.layout.editor ? ( layout.editor ? (
<IconCheckboxTick /> <IconCheckboxTick />
) : ( ) : (
<div className="px-2"></div> <div className="px-2"></div>
) )
} }
onClick={() => onClick={() =>
props.setLayout((prev) => ({ setLayout((prev) => ({
...prev, ...prev,
editor: !prev.editor, editor: !prev.editor,
})) }))
@ -600,14 +602,14 @@ export default function ControlPanel(props) {
</Dropdown.Item> </Dropdown.Item>
<Dropdown.Item <Dropdown.Item
icon={ icon={
props.layout.shapes ? ( layout.shapes ? (
<IconCheckboxTick /> <IconCheckboxTick />
) : ( ) : (
<div className="px-2"></div> <div className="px-2"></div>
) )
} }
onClick={() => onClick={() =>
props.setLayout((prev) => ({ setLayout((prev) => ({
...prev, ...prev,
shapes: !prev.shapes, shapes: !prev.shapes,
})) }))
@ -620,14 +622,14 @@ export default function ControlPanel(props) {
> >
<Dropdown.Item <Dropdown.Item
icon={ icon={
props.layout.sidebar ? ( layout.sidebar ? (
<IconCheckboxTick /> <IconCheckboxTick />
) : ( ) : (
<div className="px-2"></div> <div className="px-2"></div>
) )
} }
onClick={() => onClick={() =>
props.setLayout((prev) => ({ setLayout((prev) => ({
...prev, ...prev,
sidebar: !prev.sidebar, sidebar: !prev.sidebar,
})) }))
@ -638,14 +640,14 @@ export default function ControlPanel(props) {
</Dropdown> </Dropdown>
<Dropdown.Item <Dropdown.Item
icon={ icon={
props.layout.services ? ( layout.services ? (
<IconCheckboxTick /> <IconCheckboxTick />
) : ( ) : (
<div className="px-2"></div> <div className="px-2"></div>
) )
} }
onClick={() => onClick={() =>
props.setLayout((prev) => ({ setLayout((prev) => ({
...prev, ...prev,
services: !prev.services, services: !prev.services,
})) }))
@ -656,19 +658,19 @@ export default function ControlPanel(props) {
<Dropdown.Divider /> <Dropdown.Divider />
<Dropdown.Item <Dropdown.Item
icon={ icon={
props.layout.fullscreen ? ( layout.fullscreen ? (
<IconCheckboxTick /> <IconCheckboxTick />
) : ( ) : (
<div className="px-2"></div> <div className="px-2"></div>
) )
} }
onClick={() => { onClick={() => {
if (props.layout.fullscreen) { if (layout.fullscreen) {
exitFullscreen(); exitFullscreen();
} else { } else {
enterFullscreen(); enterFullscreen();
} }
props.setLayout((prev) => ({ setLayout((prev) => ({
...prev, ...prev,
fullscreen: !prev.fullscreen, fullscreen: !prev.fullscreen,
})); }));

View File

@ -1,4 +1,4 @@
import { React, useState } from "react"; import { React, useState, useContext } from "react";
// import { sqlDataTypes } from "../data/data"; // import { sqlDataTypes } from "../data/data";
import { IconEdit, IconPlus, IconMore, IconMinus } from "@douyinfe/semi-icons"; import { IconEdit, IconPlus, IconMore, IconMinus } from "@douyinfe/semi-icons";
import { import {
@ -10,12 +10,15 @@ import {
Popover, Popover,
Tag, Tag,
Button, Button,
SideSheet,
} from "@douyinfe/semi-ui"; } from "@douyinfe/semi-ui";
import { LayoutContext } from "../pages/editor";
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 {layout} = useContext(LayoutContext);
// const [editFieldVisible, setEditFieldVisible] = useState(-1); // const [editFieldVisible, setEditFieldVisible] = useState(-1);
// const [field, setField] = useState({ // const [field, setField] = useState({
// name: "", // name: "",
@ -73,6 +76,7 @@ export default function Table(props) {
opacity: "0.7", opacity: "0.7",
marginRight: "6px", marginRight: "6px",
}} }}
onClick={() => setVisible(true)}
></Button> ></Button>
<Button <Button
icon={<IconPlus />} icon={<IconPlus />}
@ -106,11 +110,16 @@ export default function Table(props) {
) : ( ) : (
<div> <div>
{props.tableData.indices.map((index, k) => ( {props.tableData.indices.map((index, k) => (
<div className="flex items-center my-1 px-2 py-1 rounded bg-gray-100" key={k}> <div
className="flex items-center my-1 px-2 py-1 rounded bg-gray-100"
key={k}
>
<i className="fa-solid fa-thumbtack me-2 mt-1 text-slate-500"></i> <i className="fa-solid fa-thumbtack me-2 mt-1 text-slate-500"></i>
<div> <div>
{index.fields.map((f) => ( {index.fields.map((f) => (
<Tag color="blue" key={f} className="me-1">{f}</Tag> <Tag color="blue" key={f} className="me-1">
{f}
</Tag>
))} ))}
</div> </div>
</div> </div>
@ -250,6 +259,14 @@ export default function Table(props) {
})} })}
</div> </div>
</foreignObject> </foreignObject>
<SideSheet
title="Sidesheet"
visible={visible && !layout.sidebar}
onCancel={() => setVisible((prev) => !prev)}
>
<p>This is the content of a basic sidesheet.</p>
<p>Here is more content...</p>
</SideSheet>
</g> </g>
); );
} }

View File

@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useState, createContext } from "react";
import Sidebar from "../components/sidebar"; import Sidebar from "../components/sidebar";
import ControlPanel from "../components/control_panel"; import ControlPanel from "../components/control_panel";
import { DndProvider } from "react-dnd"; import { DndProvider } from "react-dnd";
@ -6,6 +6,8 @@ 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";
export const LayoutContext = createContext();
export default function Editor(props) { export default function Editor(props) {
const [code, setCode] = useState(""); const [code, setCode] = useState("");
const [tables, setTables] = useState([]); const [tables, setTables] = useState([]);
@ -31,21 +33,38 @@ export default function Editor(props) {
if (w > 340) setWidth(w); if (w > 340) setWidth(w);
}; };
const value = {layout, setLayout};
return ( return (
<div className="h-[100vh] overflow-hidden"> <LayoutContext.Provider value={value}>
<ControlPanel layout={layout} setLayout={setLayout} /> <div className="h-[100vh] overflow-hidden">
<div <ControlPanel/>
className={ <div
layout.header className={
? `flex h-[calc(100vh-123.93px)]` layout.header
: `flex h-[calc(100vh-51.97px)]` ? `flex h-[calc(100vh-123.93px)]`
} : `flex h-[calc(100vh-51.97px)]`
onMouseUp={() => setResize(false)} }
onMouseMove={dragHandler} onMouseUp={() => setResize(false)}
> onMouseMove={dragHandler}
<DndProvider backend={HTML5Backend}> >
{layout.sidebar && ( <DndProvider backend={HTML5Backend}>
<EditorPanel {layout.sidebar && (
<EditorPanel
tables={tables}
setTables={setTables}
code={code}
setCode={setCode}
relationships={relationships}
setRelationships={setRelationships}
areas={areas}
setAreas={setAreas}
resize={resize}
setResize={setResize}
width={width}
/>
)}
<Canvas
tables={tables} tables={tables}
setTables={setTables} setTables={setTables}
code={code} code={code}
@ -54,24 +73,11 @@ export default function Editor(props) {
setRelationships={setRelationships} setRelationships={setRelationships}
areas={areas} areas={areas}
setAreas={setAreas} setAreas={setAreas}
resize={resize}
setResize={setResize}
width={width}
/> />
)} </DndProvider>
<Canvas {layout.services && <Sidebar />}
tables={tables} </div>
setTables={setTables}
code={code}
setCode={setCode}
relationships={relationships}
setRelationships={setRelationships}
areas={areas}
setAreas={setAreas}
/>
</DndProvider>
{layout.services && <Sidebar />}
</div> </div>
</div> </LayoutContext.Provider>
); );
} }