diff --git a/src/components/Area.jsx b/src/components/Area.jsx
index 53b1521..04bbe52 100644
--- a/src/components/Area.jsx
+++ b/src/components/Area.jsx
@@ -19,240 +19,109 @@ import useUndoRedo from "../hooks/useUndoRedo";
import useSelect from "../hooks/useSelect";
import useAreas from "../hooks/useAreas";
import useSaveState from "../hooks/useSaveState";
+import useTransform from "../hooks/useTransform";
-export default function Area(props) {
+export default function Area({ data, onMouseDown, setResize, setInitCoords }) {
const [hovered, setHovered] = useState(false);
- const [editField, setEditField] = useState({});
const { layout } = useLayout();
const { settings } = useSettings();
+ const { transform } = useTransform();
const { setSaveState } = useSaveState();
- const { updateArea, deleteArea } = useAreas();
- const { setUndoStack, setRedoStack } = useUndoRedo();
const { selectedElement, setSelectedElement } = useSelect();
- const handleMouseDown = (e, dir) => {
- props.setResize({ id: props.areaData.id, dir: dir });
- props.setInitCoords({
- x: props.areaData.x,
- y: props.areaData.y,
- width: props.areaData.width,
- height: props.areaData.height,
- mouseX: e.clientX / props.zoom,
- mouseY: e.clientY / props.zoom,
+ const handleResize = (e, dir) => {
+ setResize({ id: data.id, dir: dir });
+ setInitCoords({
+ x: data.x,
+ y: data.y,
+ width: data.width,
+ height: data.height,
+ mouseX: e.clientX / transform.zoom,
+ mouseY: e.clientY / transform.zoom,
});
};
+ const edit = () => {
+ if (layout.sidebar) {
+ setSelectedElement((prev) => ({
+ ...prev,
+ element: ObjectType.AREA,
+ id: data.id,
+ currentTab: Tab.AREAS,
+ open: true,
+ }));
+ if (selectedElement.currentTab !== Tab.AREAS) return;
+ document
+ .getElementById(`scroll_area_${data.id}`)
+ .scrollIntoView({ behavior: "smooth" });
+ } else {
+ setSelectedElement((prev) => ({
+ ...prev,
+ element: ObjectType.AREA,
+ id: data.id,
+ open: true,
+ }));
+ }
+ };
+
+ const onClickOutSide = () => {
+ if (selectedElement.editFromToolbar) {
+ setSelectedElement((prev) => ({
+ ...prev,
+ editFromToolbar: false,
+ }));
+ return;
+ }
+ setSelectedElement((prev) => ({
+ ...prev,
+ open: false,
+ }));
+ setSaveState(State.SAVING);
+ };
+
+ const areaIsSelected = () =>
+ selectedElement.element === ObjectType.AREA &&
+ selectedElement.id === data.id &&
+ selectedElement.open;
+
return (
-
- + {d.name} |
@@ -2085,7 +2085,7 @@ export default function ControlPanel({
className="hover-1"
>
-
+
@@ -2166,7 +2166,7 @@ export default function ControlPanel({
setTransform((prev) => ({ ...prev, zoom: prev.zoom * 1.2 }))
}
>
-
+
{e.message}
{parseInt(transform.zoom * 100)}%
@@ -33,7 +33,7 @@ export default function Controls() {
}))
}
>
-
+
-
+
Issues
diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx
index afbd898..fe22aac 100644
--- a/src/components/Navbar.jsx
+++ b/src/components/Navbar.jsx
@@ -48,7 +48,9 @@ export default function Navbar() {
+
+ );
+}
diff --git a/src/components/Note.jsx b/src/components/Note.jsx
index 8a803b9..19da9df 100644
--- a/src/components/Note.jsx
+++ b/src/components/Note.jsx
@@ -28,10 +28,50 @@ export default function Note({ data, onMouseDown }) {
const textarea = document.getElementById(`note_${data.id}`);
textarea.style.height = "0";
textarea.style.height = textarea.scrollHeight + "px";
- const newHeight = textarea.scrollHeight + 41;
+ const newHeight = textarea.scrollHeight + 42;
updateNote(data.id, { content: e.target.value, height: newHeight });
};
+ const handleBlur = (e) => {
+ if (e.target.value === editField.content) return;
+ const textarea = document.getElementById(`note_${data.id}`);
+ textarea.style.height = "0";
+ textarea.style.height = textarea.scrollHeight + "px";
+ const newHeight = textarea.scrollHeight + 16 + 20 + 4;
+ setUndoStack((prev) => [
+ ...prev,
+ {
+ action: Action.EDIT,
+ element: ObjectType.NOTE,
+ nid: data.id,
+ undo: editField,
+ redo: { content: e.target.value, height: newHeight },
+ message: `Edit note content to "${e.target.value}"`,
+ },
+ ]);
+ setRedoStack([]);
+ };
+
+ const edit = () => {
+ if (layout.sidebar) {
+ setSelectedElement((prev) => ({
+ ...prev,
+ currentTab: Tab.NOTES,
+ }));
+ if (selectedElement.currentTab !== Tab.NOTES) return;
+ document
+ .getElementById(`scroll_note_${data.id}`)
+ .scrollIntoView({ behavior: "smooth" });
+ } else {
+ setSelectedElement((prev) => ({
+ ...prev,
+ element: ObjectType.NOTE,
+ id: data.id,
+ open: true,
+ }));
+ }
+ };
+
return (
No notes found
}
onSearch={(v) => handleStringSearch(v)}
- onChange={(v) => setValue(v)}
+ onChange={(v) => setSearchText(v)}
onSelect={(v) => {
const { id } = notes.find((t) => t.title === v);
setActiveKey(`${id}`);
@@ -79,18 +69,7 @@ export default function NotesOverview() {
{notes.length <= 0 ? (
-
-
+ No relationships found
- }
- onSearch={(v) => handleStringSearch(v)}
- onChange={(v) => setValue(v)}
- onSelect={(v) => {
- const { id } = relationships.find((t) => t.name === v);
- setRefActiveIndex(`${id}`);
- document
- .getElementById(`scroll_ref_${id}`)
- .scrollIntoView({ behavior: "smooth" });
- }}
- className="w-full"
- />
-
-
- ) : (
- relationships.map((r, i) => (
-
- } itemKey={`${i}`}>
-
-
-
-
- Primary:
- {tables[r.endTableId].name}
-
-
- Foreign:
- {tables[r.startTableId].name}
-
-
-
- }
- trigger="click"
- position="rightTop"
- showArrow
- >
- } type="tertiary">
-
-
- }
- block
- onClick={() => {
- setUndoStack((prev) => [
- ...prev,
- {
- action: Action.EDIT,
- element: ObjectType.RELATIONSHIP,
- rid: i,
- undo: {
- startTableId: r.startTableId,
- startFieldId: r.startFieldId,
- endTableId: r.endTableId,
- endFieldId: r.endFieldId,
- },
- redo: {
- startTableId: r.endTableId,
- startFieldId: r.endFieldId,
- endTableId: r.startTableId,
- endFieldId: r.startFieldId,
- },
- message: `Swap primary and foreign tables`,
- },
- ]);
- setRedoStack([]);
- setRelationships((prev) =>
- prev.map((e, idx) =>
- idx === i
- ? {
- ...e,
- startTableId: e.endTableId,
- startFieldId: e.endFieldId,
- endTableId: e.startTableId,
- endFieldId: e.startFieldId,
- }
- : e
- )
- );
- }}
- >
- Swap
-
-
- Cardinality
-
- On update:
-
-
- On delete:
-
-
- No relationships found
+ }
+ onSearch={(v) => handleStringSearch(v)}
+ onChange={(v) => setSearchText(v)}
+ onSelect={(v) => {
+ const { id } = relationships.find((t) => t.name === v);
+ setRefActiveIndex(`${id}`);
+ document
+ .getElementById(`scroll_ref_${id}`)
+ .scrollIntoView({ behavior: "smooth" });
+ }}
+ className="w-full"
+ />
+
+
+
+
+
+ Primary:
+ {tables[data.endTableId].name}
+
+
+ Foreign:
+ {tables[data.startTableId].name}
+
+
+
+ }
+ trigger="click"
+ position="rightTop"
+ showArrow
+ >
+ } type="tertiary" />
+
+
+ }
+ block
+ onClick={() => {
+ setUndoStack((prev) => [
+ ...prev,
+ {
+ action: Action.EDIT,
+ element: ObjectType.RELATIONSHIP,
+ rid: data.id,
+ undo: {
+ startTableId: data.startTableId,
+ startFieldId: data.startFieldId,
+ endTableId: data.endTableId,
+ endFieldId: data.endFieldId,
+ },
+ redo: {
+ startTableId: data.endTableId,
+ startFieldId: data.endFieldId,
+ endTableId: data.startTableId,
+ endFieldId: data.startFieldId,
+ },
+ message: `Swap primary and foreign tables`,
+ },
+ ]);
+ setRedoStack([]);
+ setRelationships((prev) =>
+ prev.map((e, idx) =>
+ idx === data.id
+ ? {
+ ...e,
+ startTableId: e.endTableId,
+ startFieldId: e.endFieldId,
+ endTableId: e.startTableId,
+ endFieldId: e.startFieldId,
+ }
+ : e
+ )
+ );
+ }}
+ >
+ Swap
+
+
+ Cardinality
+
+ On update:
+
+
+ On delete:
+
+
+ setResize(true)}
>
diff --git a/src/components/Table.jsx b/src/components/Table.jsx
index 874cd68..1ef895a 100644
--- a/src/components/Table.jsx
+++ b/src/components/Table.jsx
@@ -131,7 +131,7 @@ export default function Table(props) {
.scrollIntoView({ behavior: "smooth" });
}
}}
- >
+ />
)}
@@ -469,7 +469,7 @@ export default function Table(props) {
updateField(props.tableData.id, j, { primary: !f.primary });
}}
icon={ {
setHoveredField(index);
- props.setOnRect({
+ props.setHoveredTable({
tableId: props.tableData.id,
field: index,
});
@@ -1261,7 +1260,7 @@ export default function Table(props) {
className={`w-[10px] h-[10px] bg-[#2f68ad] opacity-80 z-50 rounded-full me-2`}
onMouseDown={() => {
props.handleGripField(index);
- props.setLine((prev) => ({
+ props.setLinkingLine((prev) => ({
...prev,
startFieldId: index,
startTableId: props.tableData.id,
@@ -1271,7 +1270,7 @@ export default function Table(props) {
endY: props.tableData.y + index * 36 + 50 + 19,
}));
}}
- >
+ />
{fieldData.name.length <= 11
? fieldData.name
: fieldData.name.substring(0, 11)}
@@ -1352,7 +1351,7 @@ export default function Table(props) {
}),
});
}}
- >
+ />
) : (
fieldData.type
)}
diff --git a/src/components/TableOverview.jsx b/src/components/TableOverview.jsx
deleted file mode 100644
index 6e15d72..0000000
--- a/src/components/TableOverview.jsx
+++ /dev/null
@@ -1,1130 +0,0 @@
-import { useState } from "react";
-import {
- Action,
- ObjectType,
- defaultBlue,
- sqlDataTypes,
- tableThemes,
-} from "../data/constants";
-import {
- Collapse,
- Row,
- Col,
- Input,
- TextArea,
- Button,
- Card,
- TagInput,
- InputNumber,
- Popover,
- Checkbox,
- Select,
- AutoComplete,
- Toast,
- Empty,
-} from "@douyinfe/semi-ui";
-import {
- IconMore,
- IconKeyStroked,
- IconDeleteStroked,
- IconCheckboxTick,
- IconPlus,
- IconSearch,
-} from "@douyinfe/semi-icons";
-import {
- IllustrationNoContent,
- IllustrationNoContentDark,
-} from "@douyinfe/semi-illustrations";
-import { getSize, hasCheck, hasPrecision, isSized } from "../utils/toSQL";
-import useTables from "../hooks/useTables";
-import useUndoRedo from "../hooks/useUndoRedo";
-import useSelect from "../hooks/useSelect";
-import useTypes from "../hooks/useTypes";
-
-export default function TableOverview() {
- const [indexActiveKey, setIndexActiveKey] = useState("");
- const [value, setValue] = useState("");
- const {
- tables,
- addTable,
- deleteTable,
- updateField,
- updateTable,
- setRelationships,
- } = useTables();
- const { types } = useTypes();
- const { setUndoStack, setRedoStack } = useUndoRedo();
- const { selectedElement, setSelectedElement } = useSelect();
- const [editField, setEditField] = useState({});
- const [filteredResult, setFilteredResult] = useState(
- tables.map((t) => {
- return t.name;
- })
- );
-
- const handleStringSearch = (value) => {
- setFilteredResult(
- tables
- .map((t) => {
- return t.name;
- })
- .filter((i) => i.includes(value))
- );
- };
-
- return (
- <>
-
- }
- trigger="click"
- position="right"
- showArrow
- >
- }>
-
-
-
- ))}
- {t.indices.length > 0 && (
- No tables found
- }
- onChange={(v) => setValue(v)}
- onSelect={(v) => {
- const { id } = tables.find((t) => t.name === v);
- setSelectedElement((prev) => ({
- ...prev,
- id: id,
- open: true,
- }));
- document
- .getElementById(`scroll_table_${id}`)
- .scrollIntoView({ behavior: "smooth" });
- }}
- className="w-full"
- />
-
-
-
- ) : (
- tables.map((t, i) => (
-
- } itemKey={`${t.id}`}>
-
-
- {t.fields.map((f, j) => (
- Name:
- updateTable(t.id, { name: value })}
- onFocus={(e) => setEditField({ name: e.target.value })}
- onBlur={(e) => {
- if (e.target.value === editField.name) return;
- setUndoStack((prev) => [
- ...prev,
- {
- action: Action.EDIT,
- element: ObjectType.TABLE,
- component: "self",
- tid: t.id,
- undo: editField,
- redo: { name: e.target.value },
- message: `Edit table name to ${e.target.value}`,
- },
- ]);
- setRedoStack([]);
- }}
- />
- Default value
-
- updateField(i, j, { default: value })
- }
- onFocus={(e) =>
- setEditField({ default: e.target.value })
- }
- onBlur={(e) => {
- if (e.target.value === editField.default)
- return;
- setUndoStack((prev) => [
- ...prev,
- {
- action: Action.EDIT,
- element: ObjectType.TABLE,
- component: "field",
- tid: i,
- fid: j,
- undo: editField,
- redo: { default: e.target.value },
- message: `Edit table field default to ${e.target.value}`,
- },
- ]);
- setRedoStack([]);
- }}
- />
- {(f.type === "ENUM" || f.type === "SET") && (
- <>
-
- {f.type} values
-
- Size
- Precision
-
- updateField(i, j, { size: value })
- }
- onFocus={(e) =>
- setEditField({ size: e.target.value })
- }
- onBlur={(e) => {
- if (e.target.value === editField.size)
- return;
- setUndoStack((prev) => [
- ...prev,
- {
- action: Action.EDIT,
- element: ObjectType.TABLE,
- component: "field",
- tid: i,
- fid: j,
- undo: editField,
- redo: { size: e.target.value },
- message: `Edit table field precision to ${e.target.value}`,
- },
- ]);
- setRedoStack([]);
- }}
- />
- >
- )}
- {hasCheck(f.type) && (
- <>
-
- Check Expression
-
-
- updateField(i, j, { check: value })
- }
- onFocus={(e) =>
- setEditField({ check: e.target.value })
- }
- onBlur={(e) => {
- if (e.target.value === editField.check)
- return;
- setUndoStack((prev) => [
- ...prev,
- {
- action: Action.EDIT,
- element: ObjectType.TABLE,
- component: "field",
- tid: i,
- fid: j,
- undo: editField,
- redo: { check: e.target.value },
- message: `Edit table field check expression to ${e.target.value}`,
- },
- ]);
- setRedoStack([]);
- }}
- />
-
- *This will be in the script as is.
-
- >
- )}
-
-
- Unique
-
-
- Autoincrement
- Comment
-
-
- }
- trigger="click"
- position="rightTop"
- showArrow
- >
- }
- type="tertiary"
- style={{ marginLeft: "12px" }}
- >
-
-
- ))}
-
-
- Theme
-
- -
-
-
- }
- trigger="click"
- position="bottomLeft"
- showArrow
- >
-
-
- {tableThemes
- .slice(0, Math.ceil(tableThemes.length / 2))
- .map((c) => (
-
- ))}
-
-
- {tableThemes
- .slice(Math.ceil(tableThemes.length / 2))
- .map((c) => (
-
- ))}
-
- No tables found
+ }
+ onChange={(v) => setSearchText(v)}
+ onSelect={(v) => {
+ const { id } = tables.find((t) => t.name === v);
+ setSelectedElement((prev) => ({
+ ...prev,
+ id: id,
+ open: true,
+ }));
+ document
+ .getElementById(`scroll_table_${id}`)
+ .scrollIntoView({ behavior: "smooth" });
+ }}
+ className="w-full"
+ />
+
+
+ } itemKey={`${data.id}`}>
+
+
+ {data.fields.map((f, j) => (
+ Name:
+ updateTable(data.id, { name: value })}
+ onFocus={(e) => setEditField({ name: e.target.value })}
+ onBlur={(e) => {
+ if (e.target.value === editField.name) return;
+ setUndoStack((prev) => [
+ ...prev,
+ {
+ action: Action.EDIT,
+ element: ObjectType.TABLE,
+ component: "self",
+ tid: data.id,
+ undo: editField,
+ redo: { name: e.target.value },
+ message: `Edit table name to ${e.target.value}`,
+ },
+ ]);
+ setRedoStack([]);
+ }}
+ />
+
+
+ }
+ trigger="click"
+ position="rightTop"
+ showArrow
+ >
+
+
+ Theme
+ +
+
+
+ }
+ trigger="click"
+ position="bottomLeft"
+ showArrow
+ >
+
+
+ {tableThemes
+ .slice(0, Math.ceil(tableThemes.length / 2))
+ .map((c) => (
+
+
+ {tableThemes
+ .slice(Math.ceil(tableThemes.length / 2))
+ .map((c) => (
+
+
+
);
}
diff --git a/src/pages/BugReport.jsx b/src/pages/BugReport.jsx
index 58bfc26..18b5bc7 100644
--- a/src/pages/BugReport.jsx
+++ b/src/pages/BugReport.jsx
@@ -183,7 +183,7 @@ export default function BugReport() {
}
theme="borderless"
onClick={changeTheme}
- >
+ />
+ />
+ }
+ showArrow
+ trigger="click"
+ position="right"
+ >
+
-
- }
- showArrow
- trigger="click"
- position="right"
- >
-
-
- ) : (
- types.map((t, i) => (
- Make your own custom data types. }
- />
-
- } itemKey={`${i}`}>
-
-
- {t.fields.map((f, j) => (
- Name:
- updateType(i, { name: value })}
- onFocus={(e) => setEditField({ name: e.target.value })}
- onBlur={(e) => {
- if (e.target.value === editField.name) return;
- setUndoStack((prev) => [
- ...prev,
- {
- action: Action.EDIT,
- element: ObjectType.TYPE,
- component: "self",
- tid: i,
- undo: editField,
- redo: { name: e.target.value },
- message: `Edit type name to ${e.target.value}`,
- },
- ]);
- setRedoStack([]);
- }}
- />
-
- {f.type} values
-
- Size
- Precision
-
- updateType(i, {
- fields: t.fields.map((e, id) =>
- id === j ? { ...f, size: value } : e
- ),
- })
- }
- onFocus={(e) =>
- setEditField({ size: e.target.value })
- }
- onBlur={(e) => {
- if (e.target.value === editField.size)
- return;
- setUndoStack((prev) => [
- ...prev,
- {
- action: Action.EDIT,
- element: ObjectType.TABLE,
- component: "field",
- tid: i,
- fid: j,
- undo: editField,
- redo: { size: e.target.value },
- message: `Edit type field precision to ${e.target.value}`,
- },
- ]);
- setRedoStack([]);
- }}
- />
- >
- )}
- Size
+ Precision
+
+ updateType(index, {
+ fields: data.fields.map((e, id) =>
+ id === j ? { ...f, size: value } : e
+ ),
+ })
+ }
+ onFocus={(e) =>
+ setEditField({ size: e.target.value })
+ }
+ onBlur={(e) => {
+ if (e.target.value === editField.size) return;
+ setUndoStack((prev) => [
+ ...prev,
+ {
+ action: Action.EDIT,
+ element: ObjectType.TABLE,
+ component: "field",
+ tid: index,
+ fid: j,
+ undo: editField,
+ redo: { size: e.target.value },
+ message: `Edit type field precision to ${e.target.value}`,
+ },
+ ]);
+ setRedoStack([]);
+ }}
+ />
+ >
+ )}
+ /> |