brr
This commit is contained in:
parent
003c2f734c
commit
33c5118c83
2
.gitignore
vendored
2
.gitignore
vendored
@ -21,3 +21,5 @@
|
|||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
|
||||||
|
test.html
|
BIN
src/assets/icon_136.png
Normal file
BIN
src/assets/icon_136.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
BIN
src/assets/icon_64.png
Normal file
BIN
src/assets/icon_64.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
BIN
src/assets/icon_dark_64.png
Normal file
BIN
src/assets/icon_dark_64.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
@ -1,27 +1,31 @@
|
|||||||
import { React, useState } from "react";
|
import { React, useState } from "react";
|
||||||
import {menu} from "../data/data";
|
import { menu } from "../data/data";
|
||||||
import {
|
import {
|
||||||
IconCaretUp,
|
IconCaretdown,
|
||||||
IconCaretDown,
|
IconChevronRight,
|
||||||
IconRight,
|
IconShareStroked,
|
||||||
} from "@arco-design/web-react/icon";
|
IconChevronUp,
|
||||||
import "@arco-design/web-react/dist/css/arco.css";
|
IconChevronDown,
|
||||||
|
IconPlus,
|
||||||
|
} from "@douyinfe/semi-icons";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import icon from "../assets/icon_dark_64.png";
|
||||||
|
import {
|
||||||
|
Avatar,
|
||||||
|
AvatarGroup,
|
||||||
|
Button,
|
||||||
|
Divider,
|
||||||
|
Dropdown,
|
||||||
|
} from "@douyinfe/semi-ui";
|
||||||
|
|
||||||
export default function ControlPanel() {
|
export default function ControlPanel() {
|
||||||
let cursor = 0;
|
|
||||||
const iota = (restart = false) => {
|
|
||||||
const temp = cursor;
|
|
||||||
cursor++;
|
|
||||||
return temp;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Tool = {
|
const Tool = {
|
||||||
TOOLBAR: iota(),
|
TOOLBAR: 0,
|
||||||
ZOOM: iota(),
|
ZOOM: 1,
|
||||||
UNDO: iota(),
|
UNDO: 2,
|
||||||
REDO: iota(),
|
REDO: 3,
|
||||||
ADD: iota(),
|
ADD: 4,
|
||||||
COUNT: iota(),
|
COUNT: 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
const [showToolBar, setShowToolBar] = useState(true);
|
const [showToolBar, setShowToolBar] = useState(true);
|
||||||
@ -47,64 +51,119 @@ export default function ControlPanel() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav className="bg-gray-200 relative">
|
<>
|
||||||
<div className="flex justify-between items-center">
|
|
||||||
<ul className="flex justify-start text-md ms-3 select-none relative">
|
|
||||||
{Object.keys(menu).map((category) => (
|
|
||||||
<div key={category}>
|
|
||||||
<div className="peer px-3 py-1 bg-gray-200 hover:bg-gray-300 relative z-50">
|
|
||||||
{category}
|
|
||||||
</div>
|
|
||||||
<ul className="hidden peer-hover:flex hover:flex w-[200px] flex-col bg-white drop-shadow-lg absolute z-50">
|
|
||||||
{Object.keys(menu[category]).map((item, index) => {
|
|
||||||
if (menu[category][item].length > 0) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={index}
|
|
||||||
className="group relative px-5 py-3 hover:bg-gray-200 z-50"
|
|
||||||
>
|
|
||||||
<div className="flex justify-between items-center">
|
|
||||||
<li>{item}</li>
|
|
||||||
<IconRight />
|
|
||||||
</div>
|
|
||||||
<ul className="hidden group-hover:flex hover:flex w-[200px] flex-col bg-white drop-shadow-lg absolute z-50 top-0 left-full">
|
|
||||||
{menu[category][item].map((e) => (
|
|
||||||
<li
|
|
||||||
key={e}
|
|
||||||
className="px-5 py-3 hover:bg-gray-200 z-50"
|
|
||||||
>
|
|
||||||
{e}
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<li
|
|
||||||
className="px-5 py-3 hover:bg-gray-200 relative z-50"
|
|
||||||
key={index}
|
|
||||||
>
|
|
||||||
{item}
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
<button onClick={(e) => invert(e, Tool.TOOLBAR)} className="me-3">
|
|
||||||
{showToolBar ? <IconCaretUp /> : <IconCaretDown />}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{showToolBar && (
|
{showToolBar && (
|
||||||
<div className="p-1 flex justify-start items-center">
|
<nav className="flex justify-between pt-1 items-center">
|
||||||
|
<div className="flex justify-start items-center text-slate-800">
|
||||||
|
<Link to="/">
|
||||||
|
<img width={54} src={icon} alt="logo" className="ms-8" />
|
||||||
|
</Link>
|
||||||
|
<div className="ms-1 mt-1">
|
||||||
|
<div className="text-xl ms-3">Project1 / Untitled</div>
|
||||||
|
<div className="flex justify-between items-center">
|
||||||
|
<div className="flex justify-start text-md select-none me-2">
|
||||||
|
{Object.keys(menu).map((category) => (
|
||||||
|
<Dropdown
|
||||||
|
key={category}
|
||||||
|
style={{ width: "200px" }}
|
||||||
|
render={
|
||||||
|
<Dropdown.Menu>
|
||||||
|
{Object.keys(menu[category]).map((item, index) => {
|
||||||
|
if (menu[category][item].length > 0) {
|
||||||
|
return (
|
||||||
|
<Dropdown
|
||||||
|
style={{ width: "120px" }}
|
||||||
|
key={item}
|
||||||
|
position={"rightTop"}
|
||||||
|
render={
|
||||||
|
<Dropdown.Menu>
|
||||||
|
{menu[category][item].map((e) => (
|
||||||
|
<Dropdown.Item key={e}>
|
||||||
|
<div>{e}</div>
|
||||||
|
</Dropdown.Item>
|
||||||
|
))}
|
||||||
|
</Dropdown.Menu>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Dropdown.Item
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>{item}</div>
|
||||||
|
<IconChevronRight />
|
||||||
|
</Dropdown.Item>
|
||||||
|
</Dropdown>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Dropdown.Item key={index}>
|
||||||
|
{item}
|
||||||
|
</Dropdown.Item>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Dropdown.Menu>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div className="px-3 py-1 hover:bg-gray-100">
|
||||||
|
{category}
|
||||||
|
</div>
|
||||||
|
</Dropdown>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<Button size="small" type="tertiary">
|
||||||
|
Last saved {new Date().toISOString()}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-around items-center text-md me-8">
|
||||||
|
<AvatarGroup maxCount={3} size="default">
|
||||||
|
<Avatar color="red" alt="Lisa LeBlanc">
|
||||||
|
LL
|
||||||
|
</Avatar>
|
||||||
|
<Avatar color="green" alt="Caroline Xiao">
|
||||||
|
CX
|
||||||
|
</Avatar>
|
||||||
|
<Avatar color="amber" alt="Rafal Matin">
|
||||||
|
RM
|
||||||
|
</Avatar>
|
||||||
|
<Avatar alt="Zank Lance">ZL</Avatar>
|
||||||
|
<Avatar alt="Youself Zhang">YZ</Avatar>
|
||||||
|
</AvatarGroup>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
style={{
|
||||||
|
fontSize: "16px",
|
||||||
|
marginLeft: "12px",
|
||||||
|
marginRight: "12px",
|
||||||
|
border: "1px solid white",
|
||||||
|
}}
|
||||||
|
size="large"
|
||||||
|
icon={<IconShareStroked />}
|
||||||
|
>
|
||||||
|
Share
|
||||||
|
</Button>
|
||||||
|
<Avatar size="default" alt="Buni Zhang">
|
||||||
|
BZ
|
||||||
|
</Avatar>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
)}
|
||||||
|
<div className="p-1 flex justify-between items-center rounded-xl bg-slate-100 my-1 mx-6 text-slate-700">
|
||||||
|
<div className="flex justify-start items-center">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
|
<button className="ms-2 py-2 px-3 hover:bg-gray-300 relative">
|
||||||
|
<i className="fa-solid fa-table-list"></i>
|
||||||
|
</button>
|
||||||
|
<Divider layout="vertical" margin="8px" />
|
||||||
<button
|
<button
|
||||||
className="ms-2 py-2 px-3 hover:bg-gray-300 relative"
|
className="py-2 px-3 hover:bg-gray-300 relative"
|
||||||
onClick={(e) => invert(e, Tool.ZOOM)}
|
onClick={(e) => invert(e, Tool.ZOOM)}
|
||||||
>
|
>
|
||||||
zoom <IconCaretDown />
|
zoom <IconCaretdown />
|
||||||
</button>
|
</button>
|
||||||
<ul
|
<ul
|
||||||
className={`${
|
className={`${
|
||||||
@ -160,7 +219,8 @@ export default function ControlPanel() {
|
|||||||
title="Add"
|
title="Add"
|
||||||
onClick={(e) => invert(e, Tool.ADD)}
|
onClick={(e) => invert(e, Tool.ADD)}
|
||||||
>
|
>
|
||||||
<i className="fa-solid fa-plus"></i> <IconCaretDown />
|
<IconPlus />
|
||||||
|
<IconCaretdown />
|
||||||
</button>
|
</button>
|
||||||
<ul
|
<ul
|
||||||
className={`${
|
className={`${
|
||||||
@ -188,7 +248,10 @@ export default function ControlPanel() {
|
|||||||
<i className="fa-solid fa-code-commit"></i>
|
<i className="fa-solid fa-code-commit"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
<button onClick={(e) => invert(e, Tool.TOOLBAR)} className="me-3">
|
||||||
</nav>
|
{showToolBar ? <IconChevronUp /> : <IconChevronDown />}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
import blank_pfp from "../assets/blank_pfp.webp";
|
import blank_pfp from "../assets/blank_pfp.webp";
|
||||||
import logo from "../assets/logo_80.png";
|
import logo from "../assets/logo_80.png";
|
||||||
|
|
||||||
export default function Header(props) {
|
export default function Header(props) {
|
||||||
return (
|
return (
|
||||||
<nav className="flex justify-between py-2 bg-blue text-white items-center">
|
<nav className="flex justify-between py-2 bg-blue text-white items-center">
|
||||||
<img width={136} src={logo} alt="logo" className="ms-8" />
|
<Link to="/">
|
||||||
|
<img width={136} src={logo} alt="logo" className="ms-8" />
|
||||||
|
</Link>
|
||||||
<div className="text-xl">{props.name}</div>
|
<div className="text-xl">{props.name}</div>
|
||||||
<div className="flex justify-around items-center text-md me-8">
|
<div className="flex justify-around items-center text-md me-8">
|
||||||
<button className="me-6 border px-4 py-1 rounded-xl">
|
<button className="me-6 border px-4 py-1 rounded-xl">
|
||||||
@ -13,6 +16,7 @@ export default function Header(props) {
|
|||||||
</button>
|
</button>
|
||||||
<img src={blank_pfp} alt="profile" className="rounded-full h-8 w-8" />
|
<img src={blank_pfp} alt="profile" className="rounded-full h-8 w-8" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ export default function Relationship(props) {
|
|||||||
const tableWidth = 240;
|
const tableWidth = 240;
|
||||||
const midX = (x2 + x1 + tableWidth) / 2;
|
const midX = (x2 + x1 + tableWidth) / 2;
|
||||||
const endX = x2 + tableWidth < x1 ? x2 + tableWidth - offsetX * 2 : x2;
|
const endX = x2 + tableWidth < x1 ? x2 + tableWidth - offsetX * 2 : x2;
|
||||||
|
|
||||||
if (Math.abs(y1 - y2) <= 36) {
|
if (Math.abs(y1 - y2) <= 36) {
|
||||||
r = Math.abs(y2 - y1) / 3;
|
r = Math.abs(y2 - y1) / 3;
|
||||||
if (r <= 2) {
|
if (r <= 2) {
|
||||||
@ -20,13 +20,13 @@ export default function Relationship(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (y1 <= y2) {
|
if (y1 <= y2) {
|
||||||
if (x1 + tableWidth < x2) {
|
if (x1 + tableWidth <= x2) {
|
||||||
return `M ${x1 + tableWidth - offsetX * 2} ${y1} L ${
|
return `M ${x1 + tableWidth - offsetX * 2} ${y1} L ${
|
||||||
midX - r
|
midX - r
|
||||||
} ${y1} A ${r} ${r} 0 0 1 ${midX} ${y1 + r} L ${midX} ${
|
} ${y1} A ${r} ${r} 0 0 1 ${midX} ${y1 + r} L ${midX} ${
|
||||||
y2 - r
|
y2 - r
|
||||||
} A ${r} ${r} 0 0 0 ${midX + r} ${y2} L ${endX} ${y2}`;
|
} A ${r} ${r} 0 0 0 ${midX + r} ${y2} L ${endX} ${y2}`;
|
||||||
} else if (x2 < x1 + tableWidth && x1 < x2) {
|
} else if (x2 <= x1 + tableWidth && x1 <= x2) {
|
||||||
return `M ${x1 + tableWidth - 2 * offsetX} ${y1} L ${
|
return `M ${x1 + tableWidth - 2 * offsetX} ${y1} L ${
|
||||||
x2 + tableWidth
|
x2 + tableWidth
|
||||||
} ${y1} A ${r} ${r} 0 0 1 ${x2 + tableWidth + r} ${y1 + r} L ${
|
} ${y1} A ${r} ${r} 0 0 1 ${x2 + tableWidth + r} ${y1 + r} L ${
|
||||||
@ -34,7 +34,7 @@ export default function Relationship(props) {
|
|||||||
} ${y2 - r} A ${r} ${r} 0 0 1 ${x2 + tableWidth} ${y2} L ${
|
} ${y2 - r} A ${r} ${r} 0 0 1 ${x2 + tableWidth} ${y2} L ${
|
||||||
x2 + tableWidth - 2 * offsetX
|
x2 + tableWidth - 2 * offsetX
|
||||||
} ${y2}`;
|
} ${y2}`;
|
||||||
} else if (x2 + tableWidth > x1 && x2 + tableWidth < x1 + tableWidth) {
|
} else if (x2 + tableWidth >= x1 && x2 + tableWidth <= x1 + tableWidth) {
|
||||||
return `M ${x1} ${y1} L ${x2 - r} ${y1} A ${r} ${r} 0 0 ${0} ${
|
return `M ${x1} ${y1} L ${x2 - r} ${y1} A ${r} ${r} 0 0 ${0} ${
|
||||||
x2 - r - r
|
x2 - r - r
|
||||||
} ${y1 + r} L ${x2 - r - r} ${y2 - r} A ${r} ${r} 0 0 0 ${
|
} ${y1 + r} L ${x2 - r - r} ${y2 - r} A ${r} ${r} 0 0 0 ${
|
||||||
@ -48,19 +48,19 @@ export default function Relationship(props) {
|
|||||||
} ${y2} L ${endX} ${y2}`;
|
} ${y2} L ${endX} ${y2}`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (x1 + tableWidth < x2) {
|
if (x1 + tableWidth <= x2) {
|
||||||
return `M ${x1 + tableWidth - offsetX * 2} ${y1} L ${
|
return `M ${x1 + tableWidth - offsetX * 2} ${y1} L ${
|
||||||
midX - r
|
midX - r
|
||||||
} ${y1} A ${r} ${r} 0 0 0 ${midX} ${y1 - r} L ${midX} ${
|
} ${y1} A ${r} ${r} 0 0 0 ${midX} ${y1 - r} L ${midX} ${
|
||||||
y2 + r
|
y2 + r
|
||||||
} A ${r} ${r} 0 0 1 ${midX + r} ${y2} L ${endX} ${y2}`;
|
} A ${r} ${r} 0 0 1 ${midX + r} ${y2} L ${endX} ${y2}`;
|
||||||
} else if (x1 + tableWidth > x2 && x1 + tableWidth < x2 + tableWidth) {
|
} else if (x1 + tableWidth >= x2 && x1 + tableWidth <= x2 + tableWidth) {
|
||||||
return `M ${x1} ${y1} L ${x1 - r} ${y1} A ${r} ${r} 0 0 1 ${
|
return `M ${x1} ${y1} L ${x1 - r} ${y1} A ${r} ${r} 0 0 1 ${
|
||||||
x1 - r - r
|
x1 - r - r
|
||||||
} ${y1 - r} L ${x1 - r - r} ${y2 + r} A ${r} ${r} 0 0 1 ${
|
} ${y1 - r} L ${x1 - r - r} ${y2 + r} A ${r} ${r} 0 0 1 ${
|
||||||
x1 - r
|
x1 - r
|
||||||
} ${y2} L ${endX} ${y2}`;
|
} ${y2} L ${endX} ${y2}`;
|
||||||
} else if (x1 > x2 && x1 < x2 + tableWidth) {
|
} else if (x1 >= x2 && x1 <= x2 + tableWidth) {
|
||||||
return `M ${x1 + tableWidth - 2 * offsetX} ${y1} L ${
|
return `M ${x1 + tableWidth - 2 * offsetX} ${y1} L ${
|
||||||
x1 + tableWidth - 2 * offsetX + r
|
x1 + tableWidth - 2 * offsetX + r
|
||||||
} ${y1} A ${r} ${r} 0 0 0 ${x1 + tableWidth - 2 * offsetX + r + r} ${
|
} ${y1} A ${r} ${r} 0 0 0 ${x1 + tableWidth - 2 * offsetX + r + r} ${
|
||||||
|
@ -99,6 +99,7 @@ const tableThemes = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const defaultTableTheme = "#9e9e9e";
|
const defaultTableTheme = "#9e9e9e";
|
||||||
|
const bgBlue = "#124559";
|
||||||
|
|
||||||
const Cardinality = {
|
const Cardinality = {
|
||||||
ONE_TO_ONE: "One to one",
|
ONE_TO_ONE: "One to one",
|
||||||
@ -115,4 +116,4 @@ const Constraint = {
|
|||||||
setDefault: "Set default",
|
setDefault: "Set default",
|
||||||
};
|
};
|
||||||
|
|
||||||
export { menu, sqlDataTypes, tableThemes, defaultTableTheme, Cardinality, Constraint };
|
export { menu, bgBlue, sqlDataTypes, tableThemes, defaultTableTheme, Cardinality, Constraint };
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import Header from "../components/header";
|
|
||||||
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";
|
||||||
@ -15,7 +14,6 @@ export default function Editor(props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header name={props.name} />
|
|
||||||
<ControlPanel />
|
<ControlPanel />
|
||||||
<div className="flex h-full">
|
<div className="flex h-full">
|
||||||
<DndProvider backend={HTML5Backend}>
|
<DndProvider backend={HTML5Backend}>
|
||||||
|
Loading…
Reference in New Issue
Block a user