drawDB/src/components/table.jsx

273 lines
9.5 KiB
React
Raw Normal View History

2023-09-19 20:48:46 +08:00
import { React, useState, useContext } from "react";
2023-09-19 20:48:44 +08:00
// import { sqlDataTypes } from "../data/data";
import { IconEdit, IconPlus, IconMore, IconMinus } from "@douyinfe/semi-icons";
2023-09-19 20:47:18 +08:00
import {
2023-09-19 20:48:44 +08:00
// Modal,
// Form,
// Checkbox,
// Row,
// Col,
2023-09-19 20:47:28 +08:00
Popover,
Tag,
2023-09-19 20:48:44 +08:00
Button,
2023-09-19 20:48:46 +08:00
SideSheet,
2023-09-19 20:47:28 +08:00
} from "@douyinfe/semi-ui";
2023-09-19 20:48:46 +08:00
import { LayoutContext } from "../pages/editor";
2023-09-19 20:47:06 +08:00
2023-09-19 20:47:43 +08:00
export default function Table(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:48:46 +08:00
const [visible, setVisible] = useState(false);
const {layout} = useContext(LayoutContext);
2023-09-19 20:48:44 +08:00
// const [editFieldVisible, setEditFieldVisible] = useState(-1);
// const [field, setField] = useState({
// name: "",
// type: "",
// default: "",
// primary: false,
// unique: false,
// notNull: false,
// increment: false,
// comment: "",
// });
2023-09-19 20:47:17 +08:00
2023-09-19 20:48:44 +08:00
const height = props.tableData.fields.length * 36 + 50 + 3;
2023-09-19 20:47:31 +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.tableData.x}
y={props.tableData.y}
2023-09-19 20:48:41 +08:00
width={200}
2023-09-19 20:47:17 +08:00
height={height}
2023-09-19 20:48:44 +08:00
className="shadow-lg rounded-md cursor-move"
2023-09-19 20:47:06 +08:00
onMouseDown={props.onMouseDown}
2023-09-19 20:47:11 +08:00
onMouseEnter={() => {
setIsHovered(true);
}}
onMouseLeave={() => {
setIsHovered(false);
2023-09-19 20:47:45 +08:00
props.setOnRect({
tableId: -1,
field: -2,
});
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 ${
2023-09-19 20:48:44 +08:00
isHovered ? "border-sky-500" : "border-gray-400"
} bg-gray-100 select-none rounded-md w-full`}
2023-09-19 20:47:11 +08:00
>
2023-09-19 20:47:54 +08:00
<div
2023-09-19 20:48:44 +08:00
className={`h-[10px] w-full rounded-t-md`}
style={{ backgroundColor: props.tableData.color }}
/>
<div className="font-bold text-slate-800 h-[40px] flex justify-between items-center border-b border-gray-400 bg-gray-200">
<div className="px-3">{props.tableData.name}</div>
2023-09-19 20:47:18 +08:00
{isHovered && (
2023-09-19 20:48:44 +08:00
<div className="flex justify-end items-center mx-2">
<Button
icon={<IconEdit />}
size="small"
theme="solid"
style={{
backgroundColor: "#2f68ad",
opacity: "0.7",
marginRight: "6px",
}}
2023-09-19 20:48:46 +08:00
onClick={() => setVisible(true)}
2023-09-19 20:48:44 +08:00
></Button>
<Button
icon={<IconPlus />}
size="small"
theme="solid"
style={{
backgroundColor: "#3cb558",
opacity: "0.7",
marginRight: "6px",
2023-09-19 20:47:33 +08:00
}}
2023-09-19 20:48:44 +08:00
></Button>
<Popover
content={
<div className="text-slate-600">
<p>
<strong>Comment :</strong>{" "}
{props.tableData.comment === ""
? "No comment"
: props.tableData.comment}
</p>
<p className="text-slate-600">
<strong
className={`${
props.tableData.indices.length === 0 ? "" : "block"
}`}
>
Indices :
</strong>{" "}
{props.tableData.indices.length === 0 ? (
"No indices"
) : (
<div>
{props.tableData.indices.map((index, k) => (
2023-09-19 20:48:46 +08:00
<div
className="flex items-center my-1 px-2 py-1 rounded bg-gray-100"
key={k}
>
2023-09-19 20:48:44 +08:00
<i className="fa-solid fa-thumbtack me-2 mt-1 text-slate-500"></i>
<div>
{index.fields.map((f) => (
2023-09-19 20:48:46 +08:00
<Tag color="blue" key={f} className="me-1">
{f}
</Tag>
2023-09-19 20:48:44 +08:00
))}
</div>
</div>
))}
</div>
)}
</p>
</div>
}
position="rightTop"
showArrow
trigger="click"
2023-09-19 20:47:26 +08:00
>
2023-09-19 20:48:44 +08:00
<Button
icon={<IconMore />}
type="tertiary"
size="small"
theme="solid"
style={{
opacity: "0.7",
}}
></Button>
</Popover>
2023-09-19 20:47:18 +08:00
</div>
)}
2023-09-19 20:47:17 +08:00
</div>
{props.tableData.fields.map((e, i) => {
2023-09-19 20:47:17 +08:00
return (
2023-09-19 20:47:28 +08:00
<Popover
2023-09-19 20:47:24 +08:00
key={i}
2023-09-19 20:47:28 +08:00
content={
2023-09-19 20:48:44 +08:00
<>
2023-09-19 20:47:28 +08:00
<div className="flex justify-between items-center pb-2">
<p className="me-4 font-bold">{e.name}</p>
<p className="ms-4 text-slate-600">{e.type}</p>
2023-09-19 20:47:18 +08:00
</div>
2023-09-19 20:47:28 +08:00
<hr />
{e.primary && (
<Tag color="blue" className="me-2 my-2">
Primary
</Tag>
)}
{e.unique && (
<Tag color="amber" className="me-2 my-2">
Unique
</Tag>
)}
{e.notNull && (
<Tag color="purple" className="me-2 my-2">
Not null
</Tag>
)}
{e.increment && (
<Tag color="green" className="me-2 my-2">
2023-09-19 20:47:29 +08:00
Increment
2023-09-19 20:47:28 +08:00
</Tag>
)}
<p className="text-slate-600">
<strong>Default :</strong>{" "}
{e.default === "" ? "Not set" : e.default}
</p>
2023-09-19 20:47:52 +08:00
<p className="text-slate-600">
<strong>Comment :</strong>{" "}
{e.comment === "" ? "Not comment" : e.comment}
2023-09-19 20:47:52 +08:00
</p>
2023-09-19 20:48:44 +08:00
</>
2023-09-19 20:47:28 +08:00
}
position="right"
showArrow
>
<div
className={`${
i === props.tableData.fields.length - 1
? ""
2023-09-19 20:48:44 +08:00
: "border-b border-gray-400"
} h-[36px] px-2 py-1 flex justify-between`}
2023-09-19 20:47:28 +08:00
onMouseEnter={() => {
setHoveredField(i);
2023-09-19 20:47:45 +08:00
props.setOnRect({
tableId: props.id,
field: i,
});
2023-09-19 20:47:28 +08:00
}}
onMouseLeave={() => {
setHoveredField(-1);
}}
>
<div
2023-09-19 20:48:44 +08:00
className={`${hoveredField === i ? "text-slate-500" : ""}`}
>
2023-09-19 20:47:35 +08:00
<button
2023-09-19 20:48:44 +08:00
className={`w-[10px] h-[10px] bg-[#2f68ad] opacity-80 z-50 rounded-full me-2`}
2023-09-19 20:47:35 +08:00
onMouseDown={(ev) => {
props.handleGripField(i);
2023-09-19 20:47:48 +08:00
props.setLine((prev) => ({
2023-09-19 20:47:48 +08:00
...prev,
startFieldId: i,
startTableId: props.id,
startX: props.tableData.x + 15,
2023-09-19 20:48:44 +08:00
startY: props.tableData.y + i * 36 + 50 + 19,
endX: props.tableData.x + 15,
2023-09-19 20:48:44 +08:00
endY: props.tableData.y + i * 36 + 50 + 19,
2023-09-19 20:47:48 +08:00
}));
2023-09-19 20:47:35 +08:00
}}
></button>
2023-09-19 20:47:34 +08:00
{e.name}
</div>
2023-09-19 20:48:44 +08:00
<div className="text-slate-400">
2023-09-19 20:47:28 +08:00
{hoveredField === i ? (
2023-09-19 20:48:44 +08:00
<Button
theme="solid"
size="small"
style={{
opacity: "0.7",
backgroundColor: "#d42020",
}}
onClick={(ev) => {
props.setTables((prev) => {
const updatedTables = [...prev];
const updatedFields = [
...updatedTables[props.id].fields,
];
updatedFields.splice(i, 1);
updatedTables[props.id].fields = [...updatedFields];
return updatedTables;
});
}}
icon={<IconMinus />}
></Button>
2023-09-19 20:47:28 +08:00
) : (
e.type
)}
</div>
2023-09-19 20:47:18 +08:00
</div>
2023-09-19 20:47:28 +08:00
</Popover>
2023-09-19 20:47:17 +08:00
);
})}
2023-09-19 20:47:10 +08:00
</div>
2023-09-19 20:47:08 +08:00
</foreignObject>
2023-09-19 20:48:46 +08:00
<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>
2023-09-19 20:47:06 +08:00
</g>
);
2023-09-19 20:47:43 +08:00
}