This commit is contained in:
1ilit 2023-09-19 15:48:44 +03:00
parent 24190bc460
commit 032d77df2c
3 changed files with 131 additions and 359 deletions

View File

@ -131,13 +131,13 @@ export default function Canvas(props) {
...r,
startX: props.tables[r.startTableId].x + 15,
startY:
props.tables[r.startTableId].y + r.startFieldId * 36 + 40 + 19,
props.tables[r.startTableId].y + r.startFieldId * 36 + 50 + 19,
};
} else if (r.endTableId === dragging[1]) {
return {
...r,
endX: props.tables[r.endTableId].x + 15,
endY: props.tables[r.endTableId].y + r.endFieldId * 36 + 40 + 19,
endY: props.tables[r.endTableId].y + r.endFieldId * 36 + 50 + 19,
};
}
return r;
@ -247,7 +247,7 @@ export default function Canvas(props) {
endTableId: onRect.tableId,
endFieldId: onRect.field,
endX: props.tables[onRect.tableId].x + 15,
endY: props.tables[onRect.tableId].y + onRect.field * 36 + 40 + 19,
endY: props.tables[onRect.tableId].y + onRect.field * 36 + 50 + 19,
name: `${props.tables[line.startTableId].name}_to_${
props.tables[onRect.tableId].name
}`,

View File

@ -1,91 +1,34 @@
import { React, useState } from "react";
import { sqlDataTypes } from "../data/data";
// import { sqlDataTypes } from "../data/data";
import { IconEdit, IconPlus, IconMore, IconMinus } from "@douyinfe/semi-icons";
import {
IconEdit,
IconDelete,
IconPlus,
IconMinus,
} from "@douyinfe/semi-icons";
import {
Modal,
Form,
Checkbox,
Row,
Col,
// Modal,
// Form,
// Checkbox,
// Row,
// Col,
Popover,
Tag,
Popconfirm,
Toast,
Button,
} from "@douyinfe/semi-ui";
export default function Table(props) {
const [isHovered, setIsHovered] = useState(false);
const [hoveredField, setHoveredField] = useState(-1);
// const [name, setName] = useState(props.tableData.name);
const [visible, setVisible] = useState(false);
const [editFieldVisible, setEditFieldVisible] = useState(-1);
// const [visible, setVisible] = useState(false);
// const [editFieldVisible, setEditFieldVisible] = useState(-1);
// const [field, setField] = useState({
// name: "",
// type: "",
// default: "",
// primary: false,
// unique: false,
// notNull: false,
// increment: false,
// comment: "",
// });
const [field, setField] = useState({
name: "",
type: "",
default: "",
primary: false,
unique: false,
notNull: false,
increment: false,
comment: "",
});
const handleEditField = () => {
props.setTables((prev) => {
const updatedTables = [...prev];
updatedTables[props.id].fields[editFieldVisible] = { ...field };
return updatedTables;
});
setField({
name: "",
type: "",
default: "",
primary: false,
unique: false,
notNull: false,
increment: false,
comment: "",
});
setEditFieldVisible(-1);
};
const handleAddField = () => {
props.setTables((prev) => {
const updatedTables = [...prev];
updatedTables[props.id].fields = [
...updatedTables[props.id].fields,
{ ...field },
];
return updatedTables;
});
setField({
name: "",
type: "",
default: "",
primary: false,
unique: false,
notNull: false,
increment: false,
comment: "",
});
setVisible(false);
};
const height = props.tableData.fields.length * 36 + 40 + 4 + 36;
const onCheck = (checkedValues) => {
setField({
...field,
[checkedValues.target.value]: checkedValues.target.checked,
});
};
const height = props.tableData.fields.length * 36 + 50 + 3;
return (
<g>
@ -95,7 +38,7 @@ export default function Table(props) {
y={props.tableData.y}
width={200}
height={height}
style={{ cursor: "move" }}
className="shadow-lg rounded-md cursor-move"
onMouseDown={props.onMouseDown}
onMouseEnter={() => {
setIsHovered(true);
@ -110,42 +53,87 @@ export default function Table(props) {
>
<div
className={`border-2 ${
isHovered ? "border-sky-500" : "border-gray-500"
} bg-gray-200 select-none rounded-md`}
isHovered ? "border-sky-500" : "border-gray-400"
} bg-gray-100 select-none rounded-md w-full`}
>
<div
// style={{ backgroundColor: props.tableData.color }}
className="p-3 bg-gray-300 font-bold text-slate-800 h-[40px] rounded-t-md flex justify-between items-center"
>
<div className="p-1">
{props.tableData.name}
</div>
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>
{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) => setVisible(true)}
>
<IconPlus />
</button>
<Popconfirm
title="Are you sure you want to delete this table?"
content="This modification will be irreversible."
cancelText="Cancel"
okText="Delete"
onConfirm={() => {
Toast.success(`Table deleted!`);
console.log("table.jsx ", props.id);
<div className="flex justify-end items-center mx-2">
<Button
icon={<IconEdit />}
size="small"
theme="solid"
style={{
backgroundColor: "#2f68ad",
opacity: "0.7",
marginRight: "6px",
}}
onCancel={() => {}}
></Button>
<Button
icon={<IconPlus />}
size="small"
theme="solid"
style={{
backgroundColor: "#3cb558",
opacity: "0.7",
marginRight: "6px",
}}
></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"
}`}
>
<button className="btn bg-red-800 text-white text-xs py-1 px-2 opacity-80">
<IconDelete />
</button>
</Popconfirm>
Indices :
</strong>{" "}
{props.tableData.indices.length === 0 ? (
"No indices"
) : (
<div>
{props.tableData.indices.map((index, 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>
<div>
{index.fields.map((f) => (
<Tag color="blue" key={f} className="me-1">{f}</Tag>
))}
</div>
</div>
))}
</div>
)}
</p>
</div>
}
position="rightTop"
showArrow
trigger="click"
>
<Button
icon={<IconMore />}
type="tertiary"
size="small"
theme="solid"
style={{
opacity: "0.7",
}}
></Button>
</Popover>
</div>
)}
</div>
@ -154,7 +142,7 @@ export default function Table(props) {
<Popover
key={i}
content={
<div>
<>
<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>
@ -188,7 +176,7 @@ export default function Table(props) {
<strong>Comment :</strong>{" "}
{e.comment === "" ? "Not comment" : e.comment}
</p>
</div>
</>
}
position="right"
showArrow
@ -197,8 +185,8 @@ export default function Table(props) {
className={`${
i === props.tableData.fields.length - 1
? ""
: "border-b-2 border-gray-400"
} h-[36px] p-2 flex justify-between`}
: "border-b border-gray-400"
} h-[36px] px-2 py-1 flex justify-between`}
onMouseEnter={() => {
setHoveredField(i);
props.setOnRect({
@ -211,10 +199,10 @@ export default function Table(props) {
}}
>
<div
className={`${hoveredField === i ? "text-slate-600" : ""}`}
className={`${hoveredField === i ? "text-slate-500" : ""}`}
>
<button
className={`w-[10px] h-[10px] bg-green-600 rounded-full me-2`}
className={`w-[10px] h-[10px] bg-[#2f68ad] opacity-80 z-50 rounded-full me-2`}
onMouseDown={(ev) => {
props.handleGripField(i);
props.setLine((prev) => ({
@ -222,28 +210,23 @@ export default function Table(props) {
startFieldId: i,
startTableId: props.id,
startX: props.tableData.x + 15,
startY: props.tableData.y + i * 36 + 40 + 19,
startY: props.tableData.y + i * 36 + 50 + 19,
endX: props.tableData.x + 15,
endY: props.tableData.y + i * 36 + 40 + 19,
endY: props.tableData.y + i * 36 + 50 + 19,
}));
}}
></button>
{e.name}
</div>
<div className="text-slate-600">
<div className="text-slate-400">
{hoveredField === i ? (
<div>
<button
className="btn bg-sky-800 text-white text-xs py-1 px-2 me-2 opacity-80"
onClick={(ev) => {
setEditFieldVisible(i);
setField({ ...e });
<Button
theme="solid"
size="small"
style={{
opacity: "0.7",
backgroundColor: "#d42020",
}}
>
<IconEdit />
</button>
<button
className="btn bg-red-800 text-white text-xs py-1 px-2 opacity-80"
onClick={(ev) => {
props.setTables((prev) => {
const updatedTables = [...prev];
@ -251,16 +234,12 @@ export default function Table(props) {
...updatedTables[props.id].fields,
];
updatedFields.splice(i, 1);
updatedTables[props.id].fields = [
...updatedFields,
];
updatedTables[props.id].fields = [...updatedFields];
return updatedTables;
});
}}
>
<IconMinus />
</button>
</div>
icon={<IconMinus />}
></Button>
) : (
e.type
)}
@ -269,215 +248,8 @@ export default function Table(props) {
</Popover>
);
})}
<div className="h-[36px] p-2">
{props.tableData.comment === ""
? "No comment"
: props.tableData.comment}
</div>
</div>
</foreignObject>
<Modal
title="Add new field"
visible={visible}
onOk={handleAddField}
onCancel={() => setVisible(false)}
centered
closeOnEsc={true}
okText="Add"
cancelText="Cancel"
>
<Form
labelPosition="left"
labelAlign="right"
onValueChange={(v) => setField({ ...field, ...v })}
>
<Row>
<Col span={11}>
<Form.Input field="name" label="Name" trigger="blur" />
</Col>
<Col span={2}></Col>
<Col span={11}>
<Form.Input field="default" label="Default" trigger="blur" />
</Col>
</Row>
<Row>
<Col span={24}>
<Form.Select
field="type"
label="Type"
className="w-full"
filter
optionList={sqlDataTypes.map((value, index) => {
return {
label: value,
value: value,
};
})}
></Form.Select>
<Form.Input field="comment" label="Comment" className="w-full" />
<div className="flex justify-around mt-2">
<Checkbox
value="primary"
onChange={() =>
setField({ ...field, primary: !field.primary })
}
>
Primary
</Checkbox>
<Checkbox
value="unique"
onChange={() => setField({ ...field, unique: !field.unique })}
>
Unique
</Checkbox>
<Checkbox
value="not null"
onChange={() =>
setField({ ...field, notNull: !field.notNull })
}
>
Not null
</Checkbox>
<Checkbox
value="increment"
onChange={() =>
setField({ ...field, increment: !field.increment })
}
>
Increment
</Checkbox>
</div>
</Col>
</Row>
</Form>
</Modal>
<Modal
title={`Edit field ${
editFieldVisible !== -1
? props.tableData.fields[editFieldVisible].name
: ""
}`}
visible={editFieldVisible !== -1}
onOk={handleEditField}
onCancel={() => setEditFieldVisible(-1)}
centered
closeOnEsc={true}
okText="Edit"
cancelText="Cancel"
>
<Form
labelPosition="left"
labelAlign="right"
onValueChange={(v) => setField({ ...field, ...v })}
>
<Row>
<Col span={11}>
<Form.Input
field="name"
label="Name"
trigger="blur"
initValue={
editFieldVisible !== -1
? props.tableData.fields[editFieldVisible].name
: ""
}
/>
</Col>
<Col span={2}></Col>
<Col span={11}>
<Form.Input
field="default"
label="Default"
trigger="blur"
initValue={
editFieldVisible !== -1
? props.tableData.fields[editFieldVisible].default
: ""
}
/>
</Col>
</Row>
<Row>
<Col span={24}>
<Form.Select
field="type"
label="Type"
className="w-full"
optionList={sqlDataTypes.map((value, index) => {
return {
label: value,
value: value,
};
})}
filter
initValue={
editFieldVisible !== -1
? props.tableData.fields[editFieldVisible].type
: ""
}
></Form.Select>
<Form.Input
field="comment"
label="Comment"
trigger="blur"
initValue={
editFieldVisible !== -1
? props.tableData.fields[editFieldVisible].comment
: ""
}
/>
<div className="flex justify-around mt-2">
<Checkbox
value="primary"
onChange={onCheck}
defaultChecked={
editFieldVisible !== -1
? props.tableData.fields[editFieldVisible].primary
: undefined
}
>
Primary
</Checkbox>
<Checkbox
value="unique"
onChange={onCheck}
defaultChecked={
editFieldVisible !== -1
? props.tableData.fields[editFieldVisible].unique
: undefined
}
>
Unique
</Checkbox>
<Checkbox
value="notNull"
onChange={onCheck}
defaultChecked={
editFieldVisible !== -1
? props.tableData.fields[editFieldVisible].notNull
: undefined
}
>
Not null
</Checkbox>
<Checkbox
value="increment"
onChange={onCheck}
defaultChecked={
editFieldVisible !== -1
? props.tableData.fields[editFieldVisible].increment
: undefined
}
>
Increment
</Checkbox>
</div>
</Col>
</Row>
</Form>
</Modal>
</g>
);
}

View File

@ -39,7 +39,7 @@ const tableThemes = [
"#ff9159",
];
const defaultTableTheme = "#9e9e9e";
const defaultTableTheme = "#175e7a";
const bgBlue = "#124559";
const Cardinality = {