This commit is contained in:
1ilit 2023-09-19 15:48:20 +03:00
parent 003c2f734c
commit 33c5118c83
9 changed files with 154 additions and 86 deletions

2
.gitignore vendored
View File

@ -21,3 +21,5 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
test.html

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
src/assets/icon_dark_64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -1,27 +1,31 @@
import { React, useState } from "react";
import {menu} from "../data/data";
import { menu } from "../data/data";
import {
IconCaretUp,
IconCaretDown,
IconRight,
} from "@arco-design/web-react/icon";
import "@arco-design/web-react/dist/css/arco.css";
IconCaretdown,
IconChevronRight,
IconShareStroked,
IconChevronUp,
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() {
let cursor = 0;
const iota = (restart = false) => {
const temp = cursor;
cursor++;
return temp;
};
const Tool = {
TOOLBAR: iota(),
ZOOM: iota(),
UNDO: iota(),
REDO: iota(),
ADD: iota(),
COUNT: iota(),
TOOLBAR: 0,
ZOOM: 1,
UNDO: 2,
REDO: 3,
ADD: 4,
COUNT: 5,
};
const [showToolBar, setShowToolBar] = useState(true);
@ -47,64 +51,119 @@ export default function ControlPanel() {
};
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 && (
<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">
<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
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)}
>
zoom <IconCaretDown />
zoom <IconCaretdown />
</button>
<ul
className={`${
@ -160,7 +219,8 @@ export default function ControlPanel() {
title="Add"
onClick={(e) => invert(e, Tool.ADD)}
>
<i className="fa-solid fa-plus"></i> <IconCaretDown />
<IconPlus />
<IconCaretdown />
</button>
<ul
className={`${
@ -188,7 +248,10 @@ export default function ControlPanel() {
<i className="fa-solid fa-code-commit"></i>
</button>
</div>
)}
</nav>
<button onClick={(e) => invert(e, Tool.TOOLBAR)} className="me-3">
{showToolBar ? <IconChevronUp /> : <IconChevronDown />}
</button>
</div>
</>
);
}

View File

@ -1,11 +1,14 @@
import React from "react";
import { Link } from "react-router-dom";
import blank_pfp from "../assets/blank_pfp.webp";
import logo from "../assets/logo_80.png";
export default function Header(props) {
return (
<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="flex justify-around items-center text-md me-8">
<button className="me-6 border px-4 py-1 rounded-xl">
@ -13,6 +16,7 @@ export default function Header(props) {
</button>
<img src={blank_pfp} alt="profile" className="rounded-full h-8 w-8" />
</div>
</nav>
);
}

View File

@ -8,7 +8,7 @@ export default function Relationship(props) {
const tableWidth = 240;
const midX = (x2 + x1 + tableWidth) / 2;
const endX = x2 + tableWidth < x1 ? x2 + tableWidth - offsetX * 2 : x2;
if (Math.abs(y1 - y2) <= 36) {
r = Math.abs(y2 - y1) / 3;
if (r <= 2) {
@ -20,13 +20,13 @@ export default function Relationship(props) {
}
if (y1 <= y2) {
if (x1 + tableWidth < x2) {
if (x1 + tableWidth <= x2) {
return `M ${x1 + tableWidth - offsetX * 2} ${y1} L ${
midX - r
} ${y1} A ${r} ${r} 0 0 1 ${midX} ${y1 + r} L ${midX} ${
y2 - r
} 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 ${
x2 + tableWidth
} ${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 ${
x2 + tableWidth - 2 * offsetX
} ${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} ${
x2 - r - r
} ${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}`;
}
} else {
if (x1 + tableWidth < x2) {
if (x1 + tableWidth <= x2) {
return `M ${x1 + tableWidth - offsetX * 2} ${y1} L ${
midX - r
} ${y1} A ${r} ${r} 0 0 0 ${midX} ${y1 - r} L ${midX} ${
y2 + r
} 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 ${
x1 - r - r
} ${y1 - r} L ${x1 - r - r} ${y2 + r} A ${r} ${r} 0 0 1 ${
x1 - r
} ${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 ${
x1 + tableWidth - 2 * offsetX + r
} ${y1} A ${r} ${r} 0 0 0 ${x1 + tableWidth - 2 * offsetX + r + r} ${

View File

@ -99,6 +99,7 @@ const tableThemes = [
];
const defaultTableTheme = "#9e9e9e";
const bgBlue = "#124559";
const Cardinality = {
ONE_TO_ONE: "One to one",
@ -115,4 +116,4 @@ const Constraint = {
setDefault: "Set default",
};
export { menu, sqlDataTypes, tableThemes, defaultTableTheme, Cardinality, Constraint };
export { menu, bgBlue, sqlDataTypes, tableThemes, defaultTableTheme, Cardinality, Constraint };

View File

@ -1,5 +1,4 @@
import React, { useState } from "react";
import Header from "../components/header";
import Sidebar from "../components/sidebar";
import ControlPanel from "../components/control_panel";
import { DndProvider } from "react-dnd";
@ -15,7 +14,6 @@ export default function Editor(props) {
return (
<>
<Header name={props.name} />
<ControlPanel />
<div className="flex h-full">
<DndProvider backend={HTML5Backend}>