move table data to the top fix general functionality

This commit is contained in:
1ilit 2023-09-19 15:47:41 +03:00
parent 4447fa2f48
commit 6777abf109
4 changed files with 150 additions and 105 deletions

View File

@ -21,10 +21,10 @@ export default function Canvas(props) {
const handleMouseDownRect = (e, id) => { const handleMouseDownRect = (e, id) => {
const { clientX, clientY } = e; const { clientX, clientY } = e;
const rectangle = props.rectangles.find((rect) => rect.id === id); const table = props.tables.find((t) => t.id === id);
setOffset({ setOffset({
x: clientX - rectangle.x, x: clientX - table.x,
y: clientY - rectangle.y, y: clientY - table.y,
}); });
setDragging(id); setDragging(id);
}; };
@ -47,26 +47,25 @@ export default function Canvas(props) {
const dy = e.clientY - panOffset.y; const dy = e.clientY - panOffset.y;
setPanOffset({ x: e.clientX, y: e.clientY }); setPanOffset({ x: e.clientX, y: e.clientY });
const updatedRectangles = props.rectangles.map((rect) => ({ const updatedTables = props.tables.map((t) => ({
...rect, ...t,
x: rect.x + dx, x: t.x + dx,
y: rect.y + dy, y: t.y + dy,
})); }));
props.setRectangles(updatedRectangles); props.setTables(updatedTables);
} else if (dragging >= 0) { } else if (dragging >= 0) {
const { clientX, clientY } = e; const updatedTables = props.tables.map((t) => {
const updatedRectangles = props.rectangles.map((rect) => { if (t.id === dragging) {
if (rect.id === dragging) { const updatedTable = {
const updatedRect = { ...t,
...rect, x: e.clientX - offset.x,
x: clientX - offset.x, y: e.clientY - offset.y,
y: clientY - offset.y,
}; };
return updatedRect; return updatedTable;
} }
return rect; return t;
}); });
props.setRectangles(updatedRectangles); props.setTables(updatedTables);
} }
}; };
@ -88,17 +87,20 @@ export default function Canvas(props) {
}; };
const deleteTable = (id) => { const deleteTable = (id) => {
const updatedTables = [...props.rectangles]; const updatedTables = [...props.tables];
updatedTables.splice(id, 1); updatedTables.splice(id, 1);
props.setRectangles(updatedTables); props.setTables(updatedTables);
}; };
const handleGripField = (id) => { const handleGripField = (id) => {
setPanning(false); setPanning(false);
setDragging(-1); setDragging(-1);
setLinking(true); setLinking(true);
handleLinking();
}; };
const handleLinking = () => {};
const [, drop] = useDrop( const [, drop] = useDrop(
() => ({ () => ({
accept: "CARD", accept: "CARD",
@ -107,26 +109,35 @@ export default function Canvas(props) {
const canvasRect = canvas.current.getBoundingClientRect(); const canvasRect = canvas.current.getBoundingClientRect();
const x = offset.x - canvasRect.left - 100 * 0.5; const x = offset.x - canvasRect.left - 100 * 0.5;
const y = offset.y - canvasRect.top - 100 * 0.5; const y = offset.y - canvasRect.top - 100 * 0.5;
const newRectangle = { const newTable = {
id: props.rectangles.length + 1, id: props.tables.length + 1,
x, name: `Table ${props.tables.length + 1}`,
y, x: x,
width: 240, y: y,
height: 100, fields: [
label: `rect ${props.rectangles.length + 1}`, {
name: "id",
type: "UUID",
default: "",
primary: true,
unique: true,
notNull: true,
increment: true,
},
],
}; };
props.setRectangles([...props.rectangles, newRectangle]); props.setTables((prev) => [...prev, newTable]);
props.setCode((prev) => props.setCode((prev) =>
prev === "" prev === ""
? `CREATE TABLE \`${newRectangle.label}\`;` ? `CREATE TABLE \`${newTable.name}\`;`
: `${prev}\n\nCREATE TABLE \`${newRectangle.label}\`;` : `${prev}\n\nCREATE TABLE \`${newTable.name}\`;`
); );
}, },
collect: (monitor) => ({ collect: (monitor) => ({
isOver: !!monitor.isOver(), isOver: !!monitor.isOver(),
}), }),
}), }),
[props.rectangles] [props.tables]
); );
return ( return (
<div ref={drop} className="flex-grow" id="canvas"> <div ref={drop} className="flex-grow" id="canvas">
@ -168,20 +179,17 @@ export default function Canvas(props) {
</defs> </defs>
<rect width="100%" height="100%" fill="url(#grid)" /> <rect width="100%" height="100%" fill="url(#grid)" />
{props.rectangles.map((rectangle, i) => ( {props.tables.map((table, i) => (
<Rect <Rect
key={rectangle.id} key={table.id}
id={i} id={i}
x={rectangle.x} tableData={table}
y={rectangle.y} tables={props.tables}
label={rectangle.label} setTables={props.setTables}
width={rectangle.width}
height={rectangle.height}
setOnRect={setOnRect} setOnRect={setOnRect}
handleGripField={handleGripField} handleGripField={handleGripField}
// links={links}
setLine={setLine} setLine={setLine}
onMouseDown={(e) => handleMouseDownRect(e, rectangle.id)} onMouseDown={(e) => handleMouseDownRect(e, table.id)}
onDelete={deleteTable} onDelete={deleteTable}
/> />
))} ))}

View File

@ -48,19 +48,32 @@ export default function EditorPanel(props) {
<br /> <br />
<button <button
onClick={() => { onClick={() => {
const newRectangle = { const newTable = {
id: props.rectangles.length + 1, id: props.tables.length + 1,
name: `Table ${props.tables.length + 1}`,
x: 0, x: 0,
y: 0, y: 0,
width: 240, fields: [
height: 100, {
name: `Table ${props.rectangles.length + 1}`, name: "id",
type: "UUID",
default: "",
primary: true,
unique: true,
notNull: true,
increment: true,
},
],
}; };
props.setRectangles([...props.rectangles, newRectangle]); props.setTables(prev => {
const updatedTables = [...prev, newTable];
console.log(updatedTables);
return updatedTables;
});
props.setCode((prev) => props.setCode((prev) =>
prev === "" prev === ""
? `CREATE TABLE \`${newRectangle.name}\`;` ? `CREATE TABLE \`${newTable.name}\`;`
: `${prev}\n\nCREATE TABLE \`${newRectangle.name}\`;` : `${prev}\n\nCREATE TABLE \`${newTable.name}\`;`
); );
}} }}
> >
@ -91,15 +104,24 @@ export default function EditorPanel(props) {
return; return;
} }
map.current.set(t.table, t); map.current.set(t.table, t);
const newRectangle = { const newTable = {
id: props.rectangles.length + 1, id: props.tables.length + 1,
name: `Table ${props.tables.length + 1}`,
x: 0, x: 0,
y: 0, y: 0,
width: 240, fields: [
height: 100, {
name: `rect ${props.rectangles.length + 1}`, name: "id",
type: "UUID",
default: "",
primary: true,
unique: true,
notNull: true,
increment: true,
},
],
}; };
props.setRectangles([...props.rectangles, newRectangle]); props.setTables((prev)=>[...prev, newTable]);
}); });
}); });
} catch (e) { } catch (e) {

View File

@ -21,20 +21,10 @@ import {
const Rect = (props) => { const Rect = (props) => {
const [isHovered, setIsHovered] = useState(false); const [isHovered, setIsHovered] = useState(false);
const [hoveredField, setHoveredField] = useState(-1); const [hoveredField, setHoveredField] = useState(-1);
const [name, setName] = useState("New Table"); const [name, setName] = useState(props.tableData.name);
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const [editFieldVisible, setEditFieldVisible] = useState(-1); const [editFieldVisible, setEditFieldVisible] = useState(-1);
const [fields, setFields] = useState([
{
name: "id",
type: "UUID",
default: "",
primary: true,
unique: true,
notNull: true,
increment: true,
},
]);
const [field, setField] = useState({ const [field, setField] = useState({
name: "", name: "",
type: "", type: "",
@ -45,12 +35,13 @@ const Rect = (props) => {
increment: false, increment: false,
}); });
const handleOkEdit = () => { const handleEditField = () => {
setFields((prev) => { props.setTables((prev) => {
const updatedFields = [...prev]; const updatedTables = [...prev];
updatedFields[editFieldVisible] = { ...field }; updatedTables[props.id].fields[editFieldVisible] = { ...field };
return updatedFields; return updatedTables;
}); });
setField({ setField({
name: "", name: "",
type: "", type: "",
@ -63,8 +54,15 @@ const Rect = (props) => {
setEditFieldVisible(-1); setEditFieldVisible(-1);
}; };
const handleOk = () => { const handleAddField = () => {
setFields((prev) => [...prev, field]); props.setTables((prev) => {
const updatedTables = [...prev];
updatedTables[props.id].fields = [
...updatedTables[props.id].fields,
{ ...field },
];
return updatedTables;
});
setField({ setField({
name: "", name: "",
type: "", type: "",
@ -77,7 +75,7 @@ const Rect = (props) => {
setVisible(false); setVisible(false);
}; };
const height = fields.length * 36 + 40 + 4; const height = props.tableData.fields.length * 36 + 40 + 4;
const onCheck = (checkedValues) => { const onCheck = (checkedValues) => {
setField({ setField({
@ -90,9 +88,9 @@ const Rect = (props) => {
<g> <g>
<foreignObject <foreignObject
key={props.id} key={props.id}
x={props.x} x={props.tableData.x}
y={props.y} y={props.tableData.y}
width={props.width} width={240}
height={height} height={height}
style={{ cursor: "move" }} style={{ cursor: "move" }}
onMouseDown={props.onMouseDown} onMouseDown={props.onMouseDown}
@ -154,7 +152,7 @@ const Rect = (props) => {
</div> </div>
)} )}
</div> </div>
{fields.map((e, i) => { {props.tableData.fields.map((e, i) => {
return ( return (
<Popover <Popover
key={i} key={i}
@ -196,7 +194,9 @@ const Rect = (props) => {
> >
<div <div
className={`${ className={`${
i === fields.length - 1 ? "" : "border-b-2 border-gray-400" i === props.tableData.fields.length - 1
? ""
: "border-b-2 border-gray-400"
} h-[36px] p-2 flex justify-between`} } h-[36px] p-2 flex justify-between`}
onMouseEnter={() => { onMouseEnter={() => {
setHoveredField(i); setHoveredField(i);
@ -205,17 +205,18 @@ const Rect = (props) => {
setHoveredField(-1); setHoveredField(-1);
}} }}
> >
<div> <div
className={`${hoveredField === i ? "text-slate-600" : ""}`}
>
<button <button
className="w-[10px] h-[10px] bg-green-600 rounded-full me-2" className={`w-[10px] h-[10px] bg-green-600 rounded-full me-2`}
onMouseDown={(ev) => { onMouseDown={(ev) => {
console.log("mouse down");
props.handleGripField(i); props.handleGripField(i);
props.setLine({ props.setLine({
startX: props.x + 15, startX: props.tableData.x + 15,
startY: props.y + i * 36 + 40 + 19, startY: props.tableData.y + i * 36 + 40 + 19,
endX: props.x + 15, endX: props.tableData.x + 15,
endY: props.y + i * 36 + 40 + 19, endY: props.tableData.y + i * 36 + 40 + 19,
}); });
}} }}
></button> ></button>
@ -235,10 +236,18 @@ const Rect = (props) => {
</button> </button>
<button <button
className="btn bg-red-800 text-white text-xs py-1 px-2 opacity-80" className="btn bg-red-800 text-white text-xs py-1 px-2 opacity-80"
onClick={(e) => { onClick={(ev) => {
const updatedFields = [...fields]; props.setTables((prev) => {
updatedFields.splice(i, 1); const updatedTables = [...prev];
setFields(updatedFields); const updatedFields = [
...updatedTables[props.id].fields,
];
updatedFields.splice(i, 1);
updatedTables[props.id].fields = [
...updatedFields,
];
return updatedTables;
});
}} }}
> >
<IconMinus /> <IconMinus />
@ -258,7 +267,7 @@ const Rect = (props) => {
<Modal <Modal
title="Add new field" title="Add new field"
visible={visible} visible={visible}
onOk={handleOk} onOk={handleAddField}
onCancel={() => setVisible(false)} onCancel={() => setVisible(false)}
centered centered
closeOnEsc={true} closeOnEsc={true}
@ -331,10 +340,12 @@ const Rect = (props) => {
</Modal> </Modal>
<Modal <Modal
title={`Edit field ${ title={`Edit field ${
editFieldVisible !== -1 ? fields[editFieldVisible].name : "" editFieldVisible !== -1
? props.tableData.fields[editFieldVisible].name
: ""
}`} }`}
visible={editFieldVisible !== -1} visible={editFieldVisible !== -1}
onOk={handleOkEdit} onOk={handleEditField}
onCancel={() => setEditFieldVisible(-1)} onCancel={() => setEditFieldVisible(-1)}
centered centered
closeOnEsc={true} closeOnEsc={true}
@ -353,7 +364,9 @@ const Rect = (props) => {
label="Name" label="Name"
trigger="blur" trigger="blur"
initValue={ initValue={
editFieldVisible !== -1 ? fields[editFieldVisible].name : "" editFieldVisible !== -1
? props.tableData.fields[editFieldVisible].name
: ""
} }
/> />
</Col> </Col>
@ -365,7 +378,7 @@ const Rect = (props) => {
trigger="blur" trigger="blur"
initValue={ initValue={
editFieldVisible !== -1 editFieldVisible !== -1
? fields[editFieldVisible].default ? props.tableData.fields[editFieldVisible].default
: "" : ""
} }
/> />
@ -385,7 +398,9 @@ const Rect = (props) => {
})} })}
filter filter
initValue={ initValue={
editFieldVisible !== -1 ? fields[editFieldVisible].type : "" editFieldVisible !== -1
? props.tableData.fields[editFieldVisible].type
: ""
} }
></Form.Select> ></Form.Select>
<div className="flex justify-around mt-2"> <div className="flex justify-around mt-2">
@ -394,7 +409,7 @@ const Rect = (props) => {
onChange={onCheck} onChange={onCheck}
defaultChecked={ defaultChecked={
editFieldVisible !== -1 editFieldVisible !== -1
? fields[editFieldVisible].primary ? props.tableData.fields[editFieldVisible].primary
: undefined : undefined
} }
> >
@ -405,7 +420,7 @@ const Rect = (props) => {
onChange={onCheck} onChange={onCheck}
defaultChecked={ defaultChecked={
editFieldVisible !== -1 editFieldVisible !== -1
? fields[editFieldVisible].unique ? props.tableData.fields[editFieldVisible].unique
: undefined : undefined
} }
> >
@ -416,7 +431,7 @@ const Rect = (props) => {
onChange={onCheck} onChange={onCheck}
defaultChecked={ defaultChecked={
editFieldVisible !== -1 editFieldVisible !== -1
? fields[editFieldVisible].notNull ? props.tableData.fields[editFieldVisible].notNull
: undefined : undefined
} }
> >
@ -427,7 +442,7 @@ const Rect = (props) => {
onChange={onCheck} onChange={onCheck}
defaultChecked={ defaultChecked={
editFieldVisible !== -1 editFieldVisible !== -1
? fields[editFieldVisible].increment ? props.tableData.fields[editFieldVisible].increment
: undefined : undefined
} }
> >

View File

@ -9,7 +9,7 @@ import EditorPanel from "../components/editor_panel";
export default function Editor(props) { export default function Editor(props) {
const [code, setCode] = useState(""); const [code, setCode] = useState("");
const [rectangles, setRectangles] = useState([]); const [tables, setTables] = useState([]);
return ( return (
<> <>
@ -18,14 +18,14 @@ export default function Editor(props) {
<div className="flex h-full"> <div className="flex h-full">
<DndProvider backend={HTML5Backend}> <DndProvider backend={HTML5Backend}>
<EditorPanel <EditorPanel
rectangles={rectangles} tables={tables}
setRectangles={setRectangles} setTables={setTables}
code={code} code={code}
setCode={setCode} setCode={setCode}
/> />
<Canvas <Canvas
rectangles={rectangles} tables={tables}
setRectangles={setRectangles} setTables={setTables}
code={code} code={code}
setCode={setCode} setCode={setCode}
/> />