|
1 | 1 | import { useState, useRef } from "react";
|
2 |
| -import { Collapse, Input, TextArea, Button, Card } from "@douyinfe/semi-ui"; |
| 2 | +import { |
| 3 | + Collapse, |
| 4 | + Input, |
| 5 | + TextArea, |
| 6 | + Button, |
| 7 | + Card, |
| 8 | + Select, |
| 9 | +} from "@douyinfe/semi-ui"; |
3 | 10 | import ColorPicker from "../ColorPicker";
|
4 | 11 | import { IconDeleteStroked } from "@douyinfe/semi-icons";
|
5 | 12 | import { useDiagram, useSaveState, useUndoRedo } from "../../../hooks";
|
6 |
| -import { Action, ObjectType, State } from "../../../data/constants"; |
| 13 | +import { Action, ObjectType, State, DB } from "../../../data/constants"; |
7 | 14 | import TableField from "./TableField";
|
8 | 15 | import IndexDetails from "./IndexDetails";
|
9 | 16 | import { useTranslation } from "react-i18next";
|
10 | 17 | import { SortableList } from "../../SortableList/SortableList";
|
11 | 18 | import { nanoid } from "nanoid";
|
12 | 19 |
|
13 | 20 | export default function TableInfo({ data }) {
|
| 21 | + const { tables, database } = useDiagram(); |
14 | 22 | const { t } = useTranslation();
|
15 | 23 | const [indexActiveKey, setIndexActiveKey] = useState("");
|
16 | 24 | const { deleteTable, updateTable, setTables } = useDiagram();
|
@@ -56,10 +64,20 @@ export default function TableInfo({ data }) {
|
56 | 64 | };
|
57 | 65 | undefined;
|
58 | 66 |
|
| 67 | + const inheritedFieldNames = |
| 68 | + Array.isArray(data.inherits) && data.inherits.length > 0 |
| 69 | + ? data.inherits |
| 70 | + .map((parentName) => { |
| 71 | + const parent = tables.find((t) => t.name === parentName); |
| 72 | + return parent ? parent.fields.map((f) => f.name) : []; |
| 73 | + }) |
| 74 | + .flat() |
| 75 | + : []; |
| 76 | + |
59 | 77 | return (
|
60 | 78 | <div>
|
61 | 79 | <div className="flex items-center mb-2.5">
|
62 |
| - <div className="text-md font-semibold break-keep">{t("name")}: </div> |
| 80 | + <div className="text-md font-semibold break-keep">{t("name")}:</div> |
63 | 81 | <Input
|
64 | 82 | value={data.name}
|
65 | 83 | validateStatus={data.name.trim() === "" ? "error" : "default"}
|
@@ -88,21 +106,64 @@ export default function TableInfo({ data }) {
|
88 | 106 | }}
|
89 | 107 | />
|
90 | 108 | </div>
|
| 109 | + |
91 | 110 | <SortableList
|
92 | 111 | items={data.fields}
|
93 | 112 | keyPrefix={`table-${data.id}`}
|
94 |
| - onChange={(newFields) => { |
95 |
| - setTables((prev) => { |
96 |
| - return prev.map((t) => |
| 113 | + onChange={(newFields) => |
| 114 | + setTables((prev) => |
| 115 | + prev.map((t) => |
97 | 116 | t.id === data.id ? { ...t, fields: newFields } : t,
|
98 |
| - ); |
99 |
| - }); |
100 |
| - }} |
| 117 | + ), |
| 118 | + ) |
| 119 | + } |
101 | 120 | afterChange={() => setSaveState(State.SAVING)}
|
102 | 121 | renderItem={(item, i) => (
|
103 |
| - <TableField data={item} tid={data.id} index={i} /> |
| 122 | + <TableField |
| 123 | + data={item} |
| 124 | + tid={data.id} |
| 125 | + index={i} |
| 126 | + inherited={inheritedFieldNames.includes(item.name)} |
| 127 | + /> |
104 | 128 | )}
|
105 | 129 | />
|
| 130 | + |
| 131 | + {database === DB.POSTGRES && ( |
| 132 | + <div className="mb-2"> |
| 133 | + <div className="text-md font-semibold break-keep"> |
| 134 | + {t("inherits")}: |
| 135 | + </div> |
| 136 | + <Select |
| 137 | + multiple |
| 138 | + value={data.inherits || []} |
| 139 | + optionList={tables |
| 140 | + .filter((t) => t.id !== data.id) |
| 141 | + .map((t) => ({ label: t.name, value: t.name }))} |
| 142 | + onChange={(value) => { |
| 143 | + setUndoStack((prev) => [ |
| 144 | + ...prev, |
| 145 | + { |
| 146 | + action: Action.EDIT, |
| 147 | + element: ObjectType.TABLE, |
| 148 | + component: "self", |
| 149 | + tid: data.id, |
| 150 | + undo: { inherits: data.inherits }, |
| 151 | + redo: { inherits: value }, |
| 152 | + message: t("edit_table", { |
| 153 | + tableName: data.name, |
| 154 | + extra: "[inherits]", |
| 155 | + }), |
| 156 | + }, |
| 157 | + ]); |
| 158 | + setRedoStack([]); |
| 159 | + updateTable(data.id, { inherits: value }); |
| 160 | + }} |
| 161 | + placeholder={t("inherits")} |
| 162 | + className="w-full" |
| 163 | + /> |
| 164 | + </div> |
| 165 | + )} |
| 166 | + |
106 | 167 | {data.indices.length > 0 && (
|
107 | 168 | <Card
|
108 | 169 | bodyStyle={{ padding: "4px" }}
|
@@ -133,6 +194,7 @@ export default function TableInfo({ data }) {
|
133 | 194 | </Collapse>
|
134 | 195 | </Card>
|
135 | 196 | )}
|
| 197 | + |
136 | 198 | <Card
|
137 | 199 | bodyStyle={{ padding: "4px" }}
|
138 | 200 | style={{ marginTop: "12px", marginBottom: "12px" }}
|
@@ -173,6 +235,7 @@ export default function TableInfo({ data }) {
|
173 | 235 | </Collapse.Panel>
|
174 | 236 | </Collapse>
|
175 | 237 | </Card>
|
| 238 | + |
176 | 239 | <div className="flex justify-between items-center gap-1 mb-2">
|
177 | 240 | <ColorPicker
|
178 | 241 | usePopover={true}
|
|
0 commit comments