Skip to content

Commit d76a9e9

Browse files
committed
Import tables from dbml
1 parent 5bd6f93 commit d76a9e9

File tree

9 files changed

+131
-59
lines changed

9 files changed

+131
-59
lines changed

src/components/EditorHeader/ControlPanel.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1444,7 +1444,7 @@ export default function ControlPanel({
14441444
function toolbar() {
14451445
return (
14461446
<div
1447-
className="py-1.5 px-5 flex justify-between items-center rounded-xl my-1 sm:mx-1 xl:mx-6 select-none overflow-hidden toolbar-theme"
1447+
className="py-1.5 px-5 flex justify-between items-center rounded-lg my-1 sm:mx-1 xl:mx-6 select-none overflow-hidden toolbar-theme"
14481448
style={isRtl(i18n.language) ? { direction: "rtl" } : {}}
14491449
>
14501450
<div className="flex justify-start items-center">

src/components/EditorSidePanel/DBMLEditor/DBMLEditor.jsx

+8-8
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,28 @@ import { useEffect, useState } from "react";
22
import CodeMirror from "@uiw/react-codemirror";
33
import { vscodeDark, vscodeLight } from "@uiw/codemirror-theme-vscode";
44
import { languageExtension } from "../../../data/editorExtensions";
5-
import { useSettings } from "../../../hooks";
5+
import { useDiagram, useSettings } from "../../../hooks";
66
import { useDebounceValue } from "usehooks-ts";
7-
import { Parser } from "@dbml/core";
87
import "./styles.css";
9-
10-
const parser = new Parser();
8+
import { fromDBML } from "../../../utils/dbml/fromDBML";
119

1210
export default function DBMLEditor() {
1311
const { settings } = useSettings();
12+
const { setTables } = useDiagram();
1413
const [value, setValue] = useState("");
1514
const [debouncedValue] = useDebounceValue(value, 1000);
1615

1716
useEffect(() => {
1817
if (debouncedValue) {
1918
try {
20-
const database = parser.parse(debouncedValue, "dbml");
21-
console.log(database);
19+
const { tables } = fromDBML(debouncedValue);
20+
console.log(tables);
21+
setTables(tables);
2222
} catch (e) {
23-
console.log(e);
23+
console.log("error: ", e);
2424
}
2525
}
26-
}, [debouncedValue]);
26+
}, [debouncedValue, setTables]);
2727

2828
return (
2929
<div>

src/components/EditorSidePanel/DBMLEditor/styles.css

+12
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,15 @@
99
.ͼ1o .cm-gutters {
1010
background-color: var(--semi-color-bg-0);
1111
}
12+
13+
.ͼ1.cm-focused {
14+
outline: none;
15+
}
16+
17+
.ͼ16 {
18+
background-color: #1e1e1e00;
19+
}
20+
21+
.ͼ16 .cm-gutters {
22+
background-color: rgba(var(--semi-grey-1), 0.3);
23+
}

src/components/EditorSidePanel/SidePanel.jsx

+1-21
Original file line numberDiff line numberDiff line change
@@ -92,31 +92,12 @@ export default function SidePanel({ width, resize, setResize }) {
9292
style={{ width: `${width}px` }}
9393
>
9494
<div className="h-full flex-1 overflow-y-auto">
95-
<<<<<<< HEAD
96-
<Tabs
97-
type="card"
98-
activeKey={selectedElement.currentTab}
99-
lazyRender
100-
keepDOM={false}
101-
onChange={(key) =>
102-
setSelectedElement((prev) => ({ ...prev, currentTab: key }))
103-
}
104-
collapsible
105-
tabBarStyle={{ direction: "ltr" }}
106-
>
107-
{tabList.length &&
108-
tabList.map((tab) => (
109-
<TabPane tab={tab.tab} itemKey={tab.itemKey} key={tab.itemKey}>
110-
<div className="p-2">{tab.component}</div>
111-
</TabPane>
112-
))}
113-
</Tabs>
114-
=======
11595
{layout.dbmlEditor ? (
11696
<Tabs
11797
type="card"
11898
activeKey={selectedElement.currentTab}
11999
lazyRender
100+
keepDOM={false}
120101
onChange={(key) =>
121102
setSelectedElement((prev) => ({ ...prev, currentTab: key }))
122103
}
@@ -137,7 +118,6 @@ export default function SidePanel({ width, resize, setResize }) {
137118
) : (
138119
<DBMLEditor />
139120
)}
140-
>>>>>>> feb41e8 (Add dbml editor to sidepanel)
141121
</div>
142122
{layout.issues && (
143123
<div className="mt-auto border-t-2 border-color shadow-inner">

src/i18n/locales/en.js

-3
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,8 @@ const en = {
243243
failed_to_load: "Failed to load. Make sure the link is correct.",
244244
share_info:
245245
"* Sharing this link will not create a live real-time collaboration session.",
246-
<<<<<<< HEAD
247246
show_relationship_labels: "Show relationship labels",
248-
=======
249247
dbml_editor: "DBML editor",
250-
>>>>>>> feb41e8 (Add dbml editor to sidepanel)
251248
},
252249
};
253250

src/index.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105
}
106106

107107
.toolbar-theme {
108-
background-color: rgba(var(--semi-grey-1), 1);
108+
background-color: rgba(var(--semi-grey-1), 0.7);
109109
}
110110

111111
.hover-1:hover {

src/utils/arrangeTables.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import {
2+
tableColorStripHeight,
3+
tableFieldHeight,
4+
tableHeaderHeight,
5+
} from "../data/constants";
6+
7+
export function arrangeTables(diagram) {
8+
let maxHeight = -1;
9+
const tableWidth = 200;
10+
const gapX = 54;
11+
const gapY = 40;
12+
diagram.tables.forEach((table, i) => {
13+
if (i < diagram.tables.length / 2) {
14+
table.x = i * tableWidth + (i + 1) * gapX;
15+
table.y = gapY;
16+
const height =
17+
table.fields.length * tableFieldHeight +
18+
tableHeaderHeight +
19+
tableColorStripHeight;
20+
maxHeight = Math.max(height, maxHeight);
21+
} else {
22+
const index = diagram.tables.length - i - 1;
23+
table.x = index * tableWidth + (index + 1) * gapX;
24+
table.y = maxHeight + 2 * gapY;
25+
}
26+
});
27+
}

src/utils/dbml/fromDBML.js

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { Parser } from "@dbml/core";
2+
import { arrangeTables } from "../arrangeTables";
3+
4+
const parser = new Parser();
5+
6+
/**
7+
8+
{
9+
"id": 0,
10+
"name": "some_table",
11+
"x": 812.9083754222163,
12+
"y": 400.3451698134321,
13+
"fields": [
14+
{
15+
"name": "id",
16+
"type": "INT",
17+
"default": "",
18+
"check": "",
19+
"primary": true,
20+
"unique": true,
21+
"notNull": true,
22+
"increment": true,
23+
"comment": "",
24+
"id": 0
25+
}
26+
],
27+
"comment": "",
28+
"indices": [],
29+
"color": "#175e7a",
30+
"key": 1737222753837
31+
}
32+
*/
33+
34+
export function fromDBML(src) {
35+
const ast = parser.parse(src, "dbml");
36+
37+
const tables = [];
38+
39+
for (const schema of ast.schemas) {
40+
for (const table of schema.tables) {
41+
let parsedTable = {};
42+
parsedTable.id = tables.length;
43+
parsedTable.name = table.name;
44+
parsedTable.comment = "";
45+
parsedTable.color = "#175e7a";
46+
parsedTable.fields = [];
47+
parsedTable.indices = [];
48+
49+
for (const column of table.fields) {
50+
const field = {};
51+
field.id = parsedTable.fields.length;
52+
field.name = column.name;
53+
field.type = column.type.type_name.toUpperCase();
54+
field.default = column.dbdefault ?? "";
55+
field.check = "";
56+
field.primary = !!column.pk;
57+
field.unique = true;
58+
field.notNull = !!column.not_null;
59+
field.increment = !!column.increment;
60+
field.comment = column.note ?? "";
61+
62+
parsedTable.fields.push(field);
63+
}
64+
65+
console.log(table);
66+
67+
tables.push(parsedTable);
68+
}
69+
}
70+
71+
console.log(ast);
72+
73+
const diagram = { tables };
74+
75+
arrangeTables(diagram);
76+
77+
return diagram;
78+
}

src/utils/importSQL/index.js

+3-25
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
import {
2-
DB,
3-
tableColorStripHeight,
4-
tableFieldHeight,
5-
tableHeaderHeight,
6-
} from "../../data/constants";
1+
import { DB } from "../../data/constants";
2+
import { arrangeTables } from "../arrangeTables";
73
import { fromMariaDB } from "./mariadb";
84
import { fromMSSQL } from "./mssql";
95
import { fromMySQL } from "./mysql";
@@ -33,25 +29,7 @@ export function importSQL(ast, toDb = DB.MYSQL, diagramDb = DB.GENERIC) {
3329
break;
3430
}
3531

36-
let maxHeight = -1;
37-
const tableWidth = 200;
38-
const gapX = 54;
39-
const gapY = 40;
40-
diagram.tables.forEach((table, i) => {
41-
if (i < diagram.tables.length / 2) {
42-
table.x = i * tableWidth + (i + 1) * gapX;
43-
table.y = gapY;
44-
const height =
45-
table.fields.length * tableFieldHeight +
46-
tableHeaderHeight +
47-
tableColorStripHeight;
48-
maxHeight = Math.max(height, maxHeight);
49-
} else {
50-
const index = diagram.tables.length - i - 1;
51-
table.x = index * tableWidth + (index + 1) * gapX;
52-
table.y = maxHeight + 2 * gapY;
53-
}
54-
});
32+
arrangeTables(diagram);
5533

5634
return diagram;
5735
}

0 commit comments

Comments
 (0)