drawDB/src/components/rect.jsx

218 lines
5.9 KiB
React
Raw Normal View History

2023-09-19 20:47:11 +08:00
import { React, useState } from "react";
import Node from "./node";
2023-09-19 20:47:18 +08:00
import {
IconEdit,
IconDelete,
IconPlus,
IconMinus,
} from "@arco-design/web-react/icon";
2023-09-19 20:47:06 +08:00
const Rect = (props) => {
2023-09-19 20:47:11 +08:00
const [isHovered, setIsHovered] = useState(false);
2023-09-19 20:47:18 +08:00
const [hoveredField, setHoveredField] = useState(-1);
2023-09-19 20:47:11 +08:00
const [node, setNode] = useState(Node.NONE);
2023-09-19 20:47:18 +08:00
const [fields, setFields] = useState([
{
name: "id",
type: "uuid",
default: "",
primary: true,
unique: true,
notNull: true,
increment: false,
},
{
name: "name",
type: "varchar(20)",
default: "n/a",
primary: false,
unique: false,
notNull: true,
increment: false,
},
]);
2023-09-19 20:47:11 +08:00
2023-09-19 20:47:17 +08:00
const table = {
name: "Students",
};
2023-09-19 20:47:19 +08:00
const height = fields.length * 36 + 40 + 2;
2023-09-19 20:47:17 +08:00
2023-09-19 20:47:06 +08:00
return (
<g>
2023-09-19 20:47:10 +08:00
<foreignObject
2023-09-19 20:47:06 +08:00
key={props.id}
x={props.x}
y={props.y}
width={props.width}
2023-09-19 20:47:17 +08:00
height={height}
2023-09-19 20:47:11 +08:00
style={{ cursor: "move" }}
2023-09-19 20:47:06 +08:00
onMouseDown={props.onMouseDown}
2023-09-19 20:47:11 +08:00
onMouseEnter={() => {
setIsHovered(true);
2023-09-19 20:47:13 +08:00
props.setOnRect(true);
2023-09-19 20:47:11 +08:00
}}
onMouseLeave={() => {
setIsHovered(false);
2023-09-19 20:47:13 +08:00
props.setOnRect(false);
2023-09-19 20:47:11 +08:00
}}
2023-09-19 20:47:10 +08:00
>
2023-09-19 20:47:11 +08:00
<div
2023-09-19 20:47:17 +08:00
className={`border-2 ${
isHovered ? "border-sky-500" : "border-gray-500"
} bg-gray-300 select-none rounded-md`}
2023-09-19 20:47:11 +08:00
>
2023-09-19 20:47:18 +08:00
<div className="p-3 font-bold text-slate-800 h-[40px] bg-gray-400 rounded-t-md flex justify-between">
2023-09-19 20:47:17 +08:00
{table.name}
2023-09-19 20:47:18 +08:00
{isHovered && (
<div className="flex justify-end items-center">
<button className="btn bg-sky-800 text-white text-xs py-1 px-2 me-2 opacity-80">
<IconEdit />
</button>
<button
className="btn bg-green-600 text-white text-xs py-1 px-2 me-2 opacity-80"
onClick={(e) => {
setFields([
...fields,
{
name: "age",
type: "numeric",
default: "n/a",
primary: false,
unique: false,
notNull: true,
increment: false,
},
]);
}}
>
<IconPlus />
</button>
<button className="btn bg-red-800 text-white text-xs py-1 px-2 opacity-80">
<IconDelete />
</button>
</div>
)}
2023-09-19 20:47:17 +08:00
</div>
2023-09-19 20:47:18 +08:00
{fields.map((e, i) => {
2023-09-19 20:47:17 +08:00
return (
<div
className={`${
2023-09-19 20:47:18 +08:00
i === fields.length - 1 ? "" : "border-b-2 border-gray-400"
2023-09-19 20:47:17 +08:00
} h-[36px] p-2 flex justify-between`}
2023-09-19 20:47:18 +08:00
onMouseEnter={() => {
setHoveredField(i);
}}
onMouseLeave={() => {
setHoveredField(-1);
}}
2023-09-19 20:47:17 +08:00
>
<div>{e.name}</div>
2023-09-19 20:47:18 +08:00
<div className="text-slate-600">
{hoveredField === i ? (
<div>
<button className="btn bg-sky-800 text-white text-xs py-1 px-2 me-2 opacity-80">
<IconEdit />
</button>
2023-09-19 20:47:19 +08:00
<button
className="btn bg-red-800 text-white text-xs py-1 px-2 opacity-80"
onClick={(e) => {
const updatedFields = [...fields];
updatedFields.splice(i, 1);
setFields(updatedFields);
}}
>
2023-09-19 20:47:18 +08:00
<IconMinus />
</button>
</div>
) : (
e.type
)}
</div>
2023-09-19 20:47:17 +08:00
</div>
);
})}
2023-09-19 20:47:10 +08:00
</div>
2023-09-19 20:47:08 +08:00
</foreignObject>
2023-09-19 20:47:11 +08:00
<circle
id="TOP"
cx={props.x + props.width / 2}
cy={props.y}
r={5}
onClick={(e) => {
setNode(Node.TOP);
props.setLinks([
...props.links,
{
rect: props.id,
node: Node.TOP,
x: props.x + props.width / 2,
y: props.y,
},
]);
}}
style={{ fill: node === Node.TOP ? "green" : "black" }}
/>
<circle
id="LEFT"
cx={props.x}
2023-09-19 20:47:17 +08:00
cy={props.y + height / 2}
2023-09-19 20:47:11 +08:00
r={5}
onClick={(e) => {
setNode(Node.LEFT);
props.setLinks([
...props.links,
{
2023-09-19 20:47:11 +08:00
rect: props.id,
2023-09-19 20:47:11 +08:00
node: Node.LEFT,
x: props.x,
2023-09-19 20:47:17 +08:00
y: props.y + height / 2,
2023-09-19 20:47:11 +08:00
},
]);
}}
style={{ fill: node === Node.LEFT ? "green" : "black" }}
/>
<circle
id="RIGHT"
cx={props.x + props.width}
2023-09-19 20:47:17 +08:00
cy={props.y + height / 2}
2023-09-19 20:47:11 +08:00
r={5}
onClick={(e) => {
setNode(Node.RIGHT);
props.setLinks([
...props.links,
{
rect: props.id,
node: Node.RIGHT,
x: props.x + props.width,
2023-09-19 20:47:17 +08:00
y: props.y + height / 2,
2023-09-19 20:47:11 +08:00
},
]);
}}
style={{ fill: node === Node.RIGHT ? "green" : "black" }}
/>
<circle
id="BOTTOM"
cx={props.x + props.width / 2}
2023-09-19 20:47:17 +08:00
cy={props.y + height}
2023-09-19 20:47:11 +08:00
r={5}
onClick={(e) => {
setNode(Node.BOTTOM);
props.setLinks([
...props.links,
{
rect: props.id,
node: Node.BOTTOM,
x: props.x + props.width / 2,
2023-09-19 20:47:17 +08:00
y: props.y + height,
2023-09-19 20:47:11 +08:00
},
]);
}}
style={{ fill: node === Node.BOTTOM ? "green" : "black" }}
/>
2023-09-19 20:47:06 +08:00
</g>
);
};
export default Rect;