Skip to content

Commit 479d60b

Browse files
authored
Merge pull request #66 from lethalSopaper/feat-fk-relationship-color
Foreign key visual identifier
2 parents ee4b707 + 0e35a6f commit 479d60b

7 files changed

Lines changed: 112 additions & 50 deletions

File tree

src/components/EditorCanvas/Table.jsx

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,10 @@ export default function Table(props) {
266266
<div
267267
className={`overflow-hidden font-bold h-[40px] flex justify-between items-center border-b border-gray-400 ${
268268
settings.notation !== Notation.DEFAULT
269-
? "bg-transparent"
270-
: settings.mode === "light"
271-
? "bg-zinc-200"
272-
: "bg-zinc-900"
269+
? "bg-transparent"
270+
: settings.mode === "light"
271+
? "bg-zinc-200"
272+
: "bg-zinc-900"
273273
}`}
274274
onContextMenu={handleTableContextMenu}
275275
>
@@ -377,7 +377,14 @@ export default function Table(props) {
377377
className="flex justify-between items-center pb-2"
378378
style={{ direction: "ltr" }}
379379
>
380-
<p className="me-4 font-bold">{e.name}</p>
380+
<p
381+
className={`me-4 font-bold`}
382+
style={{
383+
color: e.foreignK ? settings.defaultFkColor : 'inherit'
384+
}}
385+
>
386+
{e.name}
387+
</p>
381388
<p className="ms-4">
382389
{e.type +
383390
((dbToTypes[database][e.type].isSized ||
@@ -409,6 +416,11 @@ export default function Table(props) {
409416
{t("autoincrement")}
410417
</Tag>
411418
)}
419+
{e.foreignK && (
420+
<Tag color="blue" className="me-2 my-2">
421+
{t("foreign_key")}
422+
</Tag>
423+
)}
412424
<p>
413425
<strong>{t("default_value")}: </strong>
414426
{e.default === "" ? t("not_set") : e.default}
@@ -593,7 +605,14 @@ export default function Table(props) {
593605
}));
594606
}}
595607
/>
596-
<span className="overflow-hidden text-ellipsis whitespace-nowrap">
608+
<span
609+
className={`overflow-hidden text-ellipsis whitespace-nowrap ${
610+
fieldData.foreignK ? "font-medium" : ""
611+
}`}
612+
style={{
613+
color: fieldData.foreignK ? settings.defaultFkColor : 'inherit'
614+
}}
615+
>
597616
{fieldData.name}
598617
</span>
599618
</div>

src/components/EditorHeader/Modal/Defaults.jsx

Lines changed: 76 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,97 @@
1-
import { Form, Tabs, TabPane } from "@douyinfe/semi-ui";
1+
import { Form, Tabs, TabPane, Popover, Button } from "@douyinfe/semi-ui";
22
import { useSettings, useDiagram } from "../../../hooks";
33
import { useTranslation } from "react-i18next";
44
import { dbToTypes } from "../../../data/datatypes";
55
import DefaultTypeSizes from "./DefaultTypeSizes";
6+
import ColorPicker from "../../ColorPicker";
67

78
export default function Defaults() {
89
const { settings, setSettings } = useSettings();
910
const { database } = useDiagram();
1011
const { t } = useTranslation();
1112

1213
const handleChange = (field, value) => {
13-
setSettings(prev => ({
14-
...prev, [field]: value
15-
}
16-
));
14+
setSettings((prev) => ({
15+
...prev,
16+
[field]: value,
17+
}));
1718
};
1819

1920
return (
2021
<Tabs defaultActiveKey="1" type="line">
2122
<TabPane tab={t("field_defaults")} itemKey="1">
22-
<Form initValues={{
23-
defaultFieldType: settings.defaultFieldType,
24-
upperCaseFields: settings.upperCaseFields,
25-
defaultNotNull: settings.defaultNotNull
26-
}}>
27-
<Form.Section text={t("field_defaults")}>
28-
<Form.Select
29-
field="defaultFieldType"
30-
label={t("default_field_type")}
31-
defaultValue={settings.defaultFieldType}
32-
onChange={(value) => handleChange('defaultFieldType', value)}
33-
>
34-
{Object.keys(dbToTypes[database]).map(type => (
35-
<Form.Select.Option key={type} value={type}>
36-
{type}
37-
</Form.Select.Option>
38-
))}
39-
</Form.Select>
23+
<Form
24+
initValues={{
25+
defaultFieldType: settings.defaultFieldType,
26+
upperCaseFields: settings.upperCaseFields,
27+
defaultNotNull: settings.defaultNotNull,
28+
defaultFkColor: settings.defaultFkColor,
29+
}}
30+
>
31+
<Form.Section text={t("field_defaults")}>
32+
<Form.Select
33+
field="defaultFieldType"
34+
label={t("default_field_type")}
35+
defaultValue={settings.defaultFieldType}
36+
onChange={(value) => handleChange("defaultFieldType", value)}
37+
>
38+
{Object.keys(dbToTypes[database]).map((type) => (
39+
<Form.Select.Option key={type} value={type}>
40+
{type}
41+
</Form.Select.Option>
42+
))}
43+
</Form.Select>
4044

41-
<Form.Switch
42-
field="upperCaseFields"
43-
label={t("uppercase_fields")}
44-
defaultChecked={settings.upperCaseFields}
45-
onChange={(checked) => handleChange('upperCaseFields', checked)}
46-
/>
45+
<Form.Switch
46+
field="upperCaseFields"
47+
label={t("uppercase_fields")}
48+
defaultChecked={settings.upperCaseFields}
49+
onChange={(checked) => handleChange("upperCaseFields", checked)}
50+
/>
4751

48-
<Form.Switch
49-
field="defaultNotNull"
50-
label={t("default_not_null")}
51-
defaultChecked={settings.defaultNotNull}
52-
onChange={(checked) => handleChange('defaultNotNull', checked)}
53-
/>
54-
</Form.Section>
55-
</Form>
52+
<Form.Switch
53+
field="defaultNotNull"
54+
label={t("default_not_null")}
55+
defaultChecked={settings.defaultNotNull}
56+
onChange={(checked) => handleChange("defaultNotNull", checked)}
57+
/>
58+
59+
<div className="flex flex-col gap-2">
60+
<label className="text-sm font-bold">
61+
{t("default_fk_color")}
62+
</label>
63+
<div className="flex justify-start">
64+
<Popover
65+
content={
66+
<div className="popover-theme">
67+
<ColorPicker
68+
currentColor={settings.defaultFkColor}
69+
onClearColor={() =>
70+
handleChange("defaultFkColor", "#2563eb")
71+
}
72+
onPickColor={(color) =>
73+
handleChange("defaultFkColor", color)
74+
}
75+
/>
76+
</div>
77+
}
78+
position="bottomLeft"
79+
trigger="click"
80+
>
81+
<Button
82+
style={{
83+
backgroundColor: settings.defaultFkColor,
84+
width: "40px",
85+
height: "32px",
86+
padding: 0,
87+
border: "2px solid #ccc",
88+
}}
89+
></Button>
90+
</Popover>
91+
</div>
92+
</div>
93+
</Form.Section>
94+
</Form>
5695
</TabPane>
5796
<TabPane tab={t("default_type_sizes")} itemKey="2">
5897
<DefaultTypeSizes />

src/components/EditorSidePanel/TablesTab/TableField.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,8 @@ export default function TableField({ data, tid, index }) {
252252
const mustSetNotNull = !data.primary && !data.notNull;
253253
const changes = { primary: !data.primary };
254254

255-
const undo = { primary: data.primary, notNull: data.notNull };
256-
const redo = { primary: newStatePK, notNull: stateNull };
255+
const undo = { primary: data.primary, notNull: data.notNull };
256+
const redo = { primary: newStatePK, notNull: stateNull };
257257

258258
if (mustSetNotNull) {
259259
undo.notNull = data.notNull;

src/context/SettingsContext.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const defaultSettings = {
1616
defaultTextSize: 40,
1717
upperCaseFields: false,
1818
defaultNotNull: false,
19+
defaultFkColor: '#2563eb', // blue-600
1920
defaultTypeSizes: {
2021
mysql: {
2122
VARCHAR: 255,

src/data/schemas.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,13 @@ export const jsonSchema = {
136136
endTableId: { type: "integer" },
137137
endFieldId: { type: "integer" },
138138
// For subtype relationships, support multiple child tables
139-
endTableIds: {
140-
type: "array",
139+
endTableIds: {
140+
type: "array",
141141
items: { type: "integer" },
142142
description: "Array of child table IDs for subtype relationships"
143143
},
144-
endFieldIds: {
145-
type: "array",
144+
endFieldIds: {
145+
type: "array",
146146
items: { type: "integer" },
147147
description: "Array of child field IDs corresponding to endTableIds"
148148
},

src/i18n/locales/en.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ const en = {
150150
default_field_type: "Default field type",
151151
uppercase_fields: "Uppercase fields",
152152
default_not_null: "Default not null",
153+
default_fk_color: "Default foreign key color",
153154
default_type_sizes: "Default type sizes",
154155
default_size: "Default size",
155156
default_precision: "Default precision",

src/i18n/locales/es.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ const es = {
141141
default_field_type: "Tipo de campo predeterminado",
142142
uppercase_fields: "Campos en mayúsculas",
143143
default_not_null: "No nulo por defecto",
144+
default_fk_color: "Color predeterminado de clave foránea",
144145
default_type_sizes: "Tamaños de tipo predeterminados",
145146
default_size: "Tamaño predeterminado",
146147
default_precision: "Precisión predeterminada",
@@ -259,7 +260,8 @@ const es = {
259260
readme: "README",
260261
Null_not_allowed:
261262
"No se permite una fk nula para relaciones identificativas",
262-
No_primary_key_in_table: "No se puede intercambiar: no existe clave primaria",
263+
No_primary_key_in_table:
264+
"No se puede intercambiar: no existe clave primaria",
263265
Swap_successful: "Relación intercambiada con éxito",
264266
},
265267
};

0 commit comments

Comments
 (0)