Skip to content

Commit 7d8846c

Browse files
committed
changes by gpt5, most of which I don't understand yet
1 parent 21a68e9 commit 7d8846c

File tree

4 files changed

+213
-25
lines changed

4 files changed

+213
-25
lines changed

src/components/CodeEditor/index.jsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Editor } from "@monaco-editor/react";
2+
import { useEffect, useRef } from "react";
23
import { useDiagram, useSettings } from "../../hooks";
34
import { Button, Toast } from "@douyinfe/semi-ui";
45
import { useTranslation } from "react-i18next";
@@ -9,6 +10,7 @@ import "./styles.css";
910
export default function CodeEditor({
1011
showCopyButton,
1112
extraControls,
13+
markers = [],
1214
...props
1315
}) {
1416
const { settings } = useSettings();
@@ -24,14 +26,49 @@ export default function CodeEditor({
2426
});
2527
};
2628

29+
const editorRef = useRef(null);
30+
const monacoRef = useRef(null);
31+
2732
const handleEditorMount = (editor, monaco) => {
2833
setUpDBML(monaco, database);
2934

3035
setTimeout(() => {
3136
editor.getAction("editor.action.formatDocument").run();
3237
}, 300);
38+
39+
editorRef.current = editor;
40+
monacoRef.current = monaco;
41+
42+
// Apply existing markers after mount
43+
try {
44+
const model = editor.getModel();
45+
if (model) {
46+
const normalized = markers.map((m) => ({
47+
severity: m.severity ?? monaco.MarkerSeverity.Error,
48+
...m,
49+
}));
50+
monaco.editor.setModelMarkers(model, "dbml", normalized);
51+
}
52+
} catch (err) {
53+
console.warn("Failed to set initial markers", err);
54+
}
3355
};
3456

57+
useEffect(() => {
58+
if (!editorRef.current || !monacoRef.current) return;
59+
try {
60+
const model = editorRef.current.getModel();
61+
if (!model) return;
62+
const normalized = markers.map((m) => ({
63+
severity: m.severity ?? monacoRef.current.MarkerSeverity.Error,
64+
...m,
65+
}));
66+
monacoRef.current.editor.setModelMarkers(model, "dbml", normalized);
67+
} catch (err) {
68+
console.warn("Failed to update markers", err);
69+
}
70+
}, [markers]);
71+
3572
return (
3673
<div className="relative h-full">
3774
<Editor

src/components/EditorSidePanel/DBMLEditor.jsx

Lines changed: 141 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,161 @@
11
import { useEffect, useState } from "react";
22
import { useDiagram, useEnums, useLayout } from "../../hooks";
33
import { toDBML } from "../../utils/exportAs/dbml";
4+
import { fromDBML } from "../../utils/importFrom/dbml";
45
import { Button, Tooltip } from "@douyinfe/semi-ui";
56
import { IconTemplate } from "@douyinfe/semi-icons";
67
import { useTranslation } from "react-i18next";
78
import CodeEditor from "../CodeEditor";
89

910
export default function DBMLEditor() {
10-
const { tables: currentTables, relationships } = useDiagram();
1111
const diagram = useDiagram();
12-
const { enums } = useEnums();
12+
const {
13+
tables: currentTables,
14+
relationships,
15+
setTables,
16+
setRelationships,
17+
database,
18+
externalIssues,
19+
} = diagram;
20+
const { enums, setEnums } = useEnums();
1321
const [value, setValue] = useState(() => toDBML({ ...diagram, enums }));
1422
const { setLayout } = useLayout();
23+
const { setExternalIssues } = diagram;
1524
const { t } = useTranslation();
1625

26+
// Translate DBML parse errors to issues and Monaco markers
27+
const [markers, setMarkers] = useState([]);
28+
1729
const toggleDBMLEditor = () => {
1830
setLayout((prev) => ({ ...prev, dbmlEditor: !prev.dbmlEditor }));
1931
};
2032

2133
useEffect(() => {
22-
setValue(toDBML({ tables: currentTables, enums, relationships }));
23-
}, [currentTables, enums, relationships]);
34+
const normalized = toDBML({
35+
tables: currentTables,
36+
enums,
37+
relationships,
38+
database,
39+
});
40+
setValue(normalized);
41+
}, [currentTables, enums, relationships, database]);
42+
43+
useEffect(() => {
44+
const currentDbml = toDBML({
45+
tables: currentTables,
46+
enums,
47+
relationships,
48+
database,
49+
});
50+
51+
if (value === currentDbml) {
52+
// If editor content already matches diagram state,
53+
// ensure any lingering external issues/markers are cleared
54+
if (externalIssues?.length) setExternalIssues([]);
55+
if (markers.length) setMarkers([]);
56+
return;
57+
}
58+
59+
const handle = setTimeout(() => {
60+
try {
61+
const parsed = fromDBML(value);
62+
// Preserve coordinates when table names match existing ones
63+
const nameToExisting = new Map(
64+
currentTables.map((t) => [t.name, { x: t.x, y: t.y }]),
65+
);
66+
parsed.tables = parsed.tables.map((t) => {
67+
const coords = nameToExisting.get(t.name);
68+
return coords ? { ...t, ...coords } : t;
69+
});
70+
setTables(parsed.tables);
71+
setRelationships(parsed.relationships);
72+
setEnums(parsed.enums);
73+
// Clear any previous external issues on success
74+
setExternalIssues([]);
75+
setMarkers([]);
76+
} catch (err) {
77+
const { issues: parsedIssues, markers: parsedMarkers } =
78+
produceDiagnostics(err);
79+
setExternalIssues(parsedIssues);
80+
setMarkers(parsedMarkers);
81+
}
82+
}, 700);
83+
84+
return () => clearTimeout(handle);
85+
}, [
86+
value,
87+
currentTables,
88+
enums,
89+
relationships,
90+
database,
91+
setTables,
92+
setRelationships,
93+
setEnums,
94+
setExternalIssues,
95+
externalIssues?.length,
96+
markers.length,
97+
]);
98+
99+
const produceDiagnostics = (err) => {
100+
// Prefer diagnostics from @dbml/core if present
101+
if (Array.isArray(err?.diags) && err.diags.length > 0) {
102+
const issues = err.diags.map((d) => {
103+
const ln = d?.location?.start?.line;
104+
const col = d?.location?.start?.column;
105+
const code = d?.code ? ` [${d.code}]` : "";
106+
if (ln && col) return `line ${ln}, col ${col}: ${d.message}${code}`;
107+
return d.message + code;
108+
});
109+
110+
const markers = err.diags.map((d) => {
111+
const start = d?.location?.start || {};
112+
const end = d?.location?.end || {};
113+
const startLineNumber = start.line || 1;
114+
const startColumn = start.column || 1;
115+
const endLineNumber = end.line || startLineNumber;
116+
const endColumn = end.column || startColumn + 1;
117+
return {
118+
startLineNumber,
119+
startColumn,
120+
endLineNumber,
121+
endColumn,
122+
message: d.message,
123+
};
124+
});
125+
return { issues, markers };
126+
}
127+
128+
// Fallbacks
129+
const message =
130+
(typeof err?.message === "string" && err.message) ||
131+
(typeof err?.description === "string" && err.description) ||
132+
(() => {
133+
try {
134+
return JSON.stringify(err);
135+
} catch {
136+
return String(err);
137+
}
138+
})();
139+
140+
// Try to extract line/column from string messages
141+
const m =
142+
/line\s+(\d+)\s*,\s*column\s*(\d+)/i.exec(message) ||
143+
/\((\d+)\s*[:|,]\s*(\d+)\)/.exec(message);
144+
const ln = m ? parseInt(m[1], 10) : 1;
145+
const col = m ? parseInt(m[2], 10) : 1;
146+
return {
147+
issues: [message],
148+
markers: [
149+
{
150+
startLineNumber: ln,
151+
startColumn: col,
152+
endLineNumber: ln,
153+
endColumn: col + 1,
154+
message,
155+
},
156+
],
157+
};
158+
};
24159

25160
return (
26161
<CodeEditor
@@ -29,8 +164,9 @@ export default function DBMLEditor() {
29164
language="dbml"
30165
onChange={setValue}
31166
height="100%"
167+
markers={markers}
32168
options={{
33-
readOnly: true,
169+
readOnly: false,
34170
minimap: { enabled: false },
35171
}}
36172
extraControls={

src/components/EditorSidePanel/Issues.jsx

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,24 @@ export default function Issues() {
1010
const { t } = useTranslation();
1111
const { settings } = useSettings();
1212
const { enums } = useEnums();
13-
const { tables, relationships, database } = useDiagram();
13+
const { tables, relationships, database, externalIssues } = useDiagram();
1414
const [issues, setIssues] = useState([]);
1515

1616
useEffect(() => {
17-
const findIssues = async () => {
18-
const newIssues = getIssues({
19-
tables: tables,
20-
relationships: relationships,
21-
types: types,
22-
database: database,
23-
enums: enums,
24-
});
17+
const newIssues = getIssues({
18+
tables: tables,
19+
relationships: relationships,
20+
types: types,
21+
database: database,
22+
enums: enums,
23+
});
2524

26-
if (!arrayIsEqual(newIssues, issues)) {
27-
setIssues(newIssues);
28-
}
29-
};
25+
const combined = [...externalIssues, ...newIssues];
3026

31-
findIssues();
32-
}, [tables, relationships, issues, types, database, enums]);
27+
if (!arrayIsEqual(combined, issues)) {
28+
setIssues(combined);
29+
}
30+
}, [tables, relationships, issues, types, database, enums, externalIssues]);
3331

3432
return (
3533
<Collapse lazyRender keepDOM={false} style={{ width: "100%" }}>
@@ -54,11 +52,25 @@ export default function Issues() {
5452
<div className="mb-1">{t("strict_mode_is_on_no_issues")}</div>
5553
) : issues.length > 0 ? (
5654
<>
57-
{issues.map((e, i) => (
58-
<div key={i} className="py-2">
59-
{e}
60-
</div>
61-
))}
55+
{issues.map((e, i) => {
56+
const text =
57+
typeof e === "string"
58+
? e
59+
: typeof e?.message === "string"
60+
? e.message
61+
: (() => {
62+
try {
63+
return JSON.stringify(e);
64+
} catch {
65+
return String(e);
66+
}
67+
})();
68+
return (
69+
<div key={i} className="py-2">
70+
{text}
71+
</div>
72+
);
73+
})}
6274
</>
6375
) : (
6476
<div>{t("no_issues")}</div>

src/context/DiagramContext.jsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export default function DiagramContextProvider({ children }) {
1212
const [database, setDatabase] = useState(DB.GENERIC);
1313
const [tables, setTables] = useState([]);
1414
const [relationships, setRelationships] = useState([]);
15+
const [externalIssues, setExternalIssues] = useState([]);
1516
const { transform } = useTransform();
1617
const { setUndoStack, setRedoStack } = useUndoRedo();
1718
const { selectedElement, setSelectedElement } = useSelect();
@@ -244,6 +245,8 @@ export default function DiagramContextProvider({ children }) {
244245
setDatabase,
245246
tablesCount: tables.length,
246247
relationshipsCount: relationships.length,
248+
externalIssues,
249+
setExternalIssues,
247250
}}
248251
>
249252
{children}

0 commit comments

Comments
 (0)