Undo redo parsing for references
This commit is contained in:
parent
ab0dc2c44e
commit
2b2e4840c9
@ -195,19 +195,11 @@ export default function ControlPanel(props) {
|
|||||||
} else if (a.component === "comment") {
|
} else if (a.component === "comment") {
|
||||||
updateTable(a.tid, a.undo, false);
|
updateTable(a.tid, a.undo, false);
|
||||||
} else if (a.component === "index_add") {
|
} else if (a.component === "index_add") {
|
||||||
setTables((prev) =>
|
updateTable(a.tid, {
|
||||||
prev.map((table, i) => {
|
indices: tables[a.tid].indices
|
||||||
if (table.id === a.tid) {
|
.filter((e) => e.id !== tables[a.tid].indices.length - 1)
|
||||||
return {
|
.map((t, i) => ({ ...t, id: i })),
|
||||||
...table,
|
});
|
||||||
indices: table.indices
|
|
||||||
.filter((e) => e.id !== tables[a.tid].indices.length - 1)
|
|
||||||
.map((t, i) => ({ ...t, id: i })),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return table;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} else if (a.component === "index") {
|
} else if (a.component === "index") {
|
||||||
updateTable(a.tid, {
|
updateTable(a.tid, {
|
||||||
indices: tables[a.tid].indices.map((index) =>
|
indices: tables[a.tid].indices.map((index) =>
|
||||||
@ -236,6 +228,10 @@ export default function ControlPanel(props) {
|
|||||||
} else if (a.component === "self") {
|
} else if (a.component === "self") {
|
||||||
updateTable(a.tid, a.undo);
|
updateTable(a.tid, a.undo);
|
||||||
}
|
}
|
||||||
|
} else if (a.element === ObjectType.RELATIONSHIP) {
|
||||||
|
setRelationships((prev) =>
|
||||||
|
prev.map((e, idx) => (idx === a.rid ? { ...e, ...a.undo } : e))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
setRedoStack((prev) => [...prev, a]);
|
setRedoStack((prev) => [...prev, a]);
|
||||||
} else if (a.action === Action.PAN) {
|
} else if (a.action === Action.PAN) {
|
||||||
@ -365,6 +361,10 @@ export default function ControlPanel(props) {
|
|||||||
} else if (a.component === "self") {
|
} else if (a.component === "self") {
|
||||||
updateTable(a.tid, a.redo);
|
updateTable(a.tid, a.redo);
|
||||||
}
|
}
|
||||||
|
} else if (a.element === ObjectType.RELATIONSHIP) {
|
||||||
|
setRelationships((prev) =>
|
||||||
|
prev.map((e, idx) => (idx === a.rid ? { ...e, ...a.redo } : e))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
setUndoStack((prev) => [...prev, a]);
|
setUndoStack((prev) => [...prev, a]);
|
||||||
} else if (a.action === Action.PAN) {
|
} else if (a.action === Action.PAN) {
|
||||||
@ -1105,7 +1105,7 @@ export default function ControlPanel(props) {
|
|||||||
!exportData.data),
|
!exportData.data),
|
||||||
}}
|
}}
|
||||||
cancelText="Cancel"
|
cancelText="Cancel"
|
||||||
width={540}
|
width={600}
|
||||||
>
|
>
|
||||||
{visible === MODAL.IMPORT ? (
|
{visible === MODAL.IMPORT ? (
|
||||||
<div>
|
<div>
|
||||||
|
@ -3,9 +3,9 @@ import {
|
|||||||
AutoComplete,
|
AutoComplete,
|
||||||
Collapse,
|
Collapse,
|
||||||
Empty,
|
Empty,
|
||||||
Form,
|
|
||||||
Row,
|
Row,
|
||||||
Col,
|
Col,
|
||||||
|
Select,
|
||||||
Button,
|
Button,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Popover,
|
Popover,
|
||||||
@ -22,8 +22,8 @@ import {
|
|||||||
IllustrationNoContent,
|
IllustrationNoContent,
|
||||||
IllustrationNoContentDark,
|
IllustrationNoContentDark,
|
||||||
} from "@douyinfe/semi-illustrations";
|
} from "@douyinfe/semi-illustrations";
|
||||||
import { Cardinality, Constraint } from "../data/data";
|
import { Cardinality, Constraint, Action, ObjectType } from "../data/data";
|
||||||
import { TableContext } from "../pages/editor";
|
import { TableContext, UndoRedoContext } from "../pages/editor";
|
||||||
|
|
||||||
export default function ReferenceOverview(props) {
|
export default function ReferenceOverview(props) {
|
||||||
const columns = [
|
const columns = [
|
||||||
@ -38,6 +38,7 @@ export default function ReferenceOverview(props) {
|
|||||||
];
|
];
|
||||||
const { tables, relationships, setRelationships, deleteRelationship } =
|
const { tables, relationships, setRelationships, deleteRelationship } =
|
||||||
useContext(TableContext);
|
useContext(TableContext);
|
||||||
|
const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
|
||||||
const [refActiveIndex, setRefActiveIndex] = useState("");
|
const [refActiveIndex, setRefActiveIndex] = useState("");
|
||||||
const [value, setValue] = useState("");
|
const [value, setValue] = useState("");
|
||||||
const [filteredResult, setFilteredResult] = useState(
|
const [filteredResult, setFilteredResult] = useState(
|
||||||
@ -99,126 +100,177 @@ export default function ReferenceOverview(props) {
|
|||||||
relationships.map((r, i) => (
|
relationships.map((r, i) => (
|
||||||
<div id={`scroll_ref_${r.id}`} key={i}>
|
<div id={`scroll_ref_${r.id}`} key={i}>
|
||||||
<Collapse.Panel header={<div>{r.name}</div>} itemKey={`${i}`}>
|
<Collapse.Panel header={<div>{r.name}</div>} itemKey={`${i}`}>
|
||||||
<Form
|
<div className="flex justify-between items-center mb-3">
|
||||||
onChange={(value) =>
|
<div className="me-3">
|
||||||
|
<span className="font-semibold">Primary: </span>
|
||||||
|
{tables[r.endTableId].name}
|
||||||
|
</div>
|
||||||
|
<div className="mx-1">
|
||||||
|
<span className="font-semibold">Foreign: </span>
|
||||||
|
{tables[r.startTableId].name}
|
||||||
|
</div>
|
||||||
|
<div className="ms-1">
|
||||||
|
<Popover
|
||||||
|
content={
|
||||||
|
<div className="p-2">
|
||||||
|
<Table
|
||||||
|
columns={columns}
|
||||||
|
dataSource={[
|
||||||
|
{
|
||||||
|
key: "1",
|
||||||
|
foreign: `${tables[r.startTableId].name}(${
|
||||||
|
tables[r.startTableId].fields[r.startFieldId]
|
||||||
|
.name
|
||||||
|
})`,
|
||||||
|
primary: `${tables[r.endTableId].name}(${
|
||||||
|
tables[r.endTableId].fields[r.endFieldId].name
|
||||||
|
})`,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
pagination={false}
|
||||||
|
size="small"
|
||||||
|
bordered
|
||||||
|
/>
|
||||||
|
<div className="mt-2">
|
||||||
|
<Button icon={<IconLoopTextStroked />} block>
|
||||||
|
Swap
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
trigger="click"
|
||||||
|
position="rightTop"
|
||||||
|
showArrow
|
||||||
|
>
|
||||||
|
<Button icon={<IconMore />} type="tertiary"></Button>
|
||||||
|
</Popover>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="font-semibold my-1">Cardinality</div>
|
||||||
|
<Select
|
||||||
|
optionList={Object.values(Cardinality).map((v) => ({
|
||||||
|
label: v,
|
||||||
|
value: v,
|
||||||
|
}))}
|
||||||
|
value={r.cardinality}
|
||||||
|
className="w-full"
|
||||||
|
onChange={(value) => {
|
||||||
|
setUndoStack((prev) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
action: Action.EDIT,
|
||||||
|
element: ObjectType.RELATIONSHIP,
|
||||||
|
rid: i,
|
||||||
|
undo: { cardinality: r.cardinality },
|
||||||
|
redo: { cardinality: value },
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
setRedoStack([]);
|
||||||
setRelationships((prev) =>
|
setRelationships((prev) =>
|
||||||
prev.map((e, idx) =>
|
prev.map((e, idx) =>
|
||||||
idx === i ? { ...e, ...value.values } : e
|
idx === i ? { ...e, cardinality: value } : e
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
}
|
}}
|
||||||
>
|
></Select>
|
||||||
<div className="flex justify-between items-center my-1">
|
<Row gutter={6} className="my-3">
|
||||||
<div className="me-3">
|
<Col span={12}>
|
||||||
<strong>Primary: </strong>
|
<div className="font-semibold">On update: </div>
|
||||||
{tables[r.endTableId].name}
|
<Select
|
||||||
</div>
|
optionList={Object.values(Constraint).map((v) => ({
|
||||||
<div className="mx-1">
|
label: v,
|
||||||
<strong>Foreign: </strong>
|
value: v,
|
||||||
{tables[r.startTableId].name}
|
}))}
|
||||||
</div>
|
value={r.updateConstraint}
|
||||||
<div className="ms-1">
|
className="w-full"
|
||||||
<Popover
|
onChange={(value) => {
|
||||||
content={
|
setUndoStack((prev) => [
|
||||||
<div className="p-2 w-[260px]">
|
...prev,
|
||||||
<Table
|
{
|
||||||
columns={columns}
|
action: Action.EDIT,
|
||||||
dataSource={[
|
element: ObjectType.RELATIONSHIP,
|
||||||
{
|
rid: i,
|
||||||
key: "1",
|
undo: { updateConstraint: r.updateConstraint },
|
||||||
foreign: tables[r.startTableId].name,
|
redo: { updateConstraint: value },
|
||||||
primary: tables[r.endTableId].name,
|
},
|
||||||
},
|
]);
|
||||||
{
|
setRedoStack([]);
|
||||||
key: "2",
|
|
||||||
foreign:
|
|
||||||
tables[r.startTableId].fields[
|
|
||||||
r.startFieldId
|
|
||||||
].name,
|
|
||||||
primary:
|
|
||||||
tables[r.endTableId].fields[r.endFieldId]
|
|
||||||
.name,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
pagination={false}
|
|
||||||
bordered
|
|
||||||
/>
|
|
||||||
<div className="mt-2">
|
|
||||||
<Button icon={<IconLoopTextStroked />} block>
|
|
||||||
Swap
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
trigger="click"
|
|
||||||
position="rightTop"
|
|
||||||
showArrow
|
|
||||||
>
|
|
||||||
<Button icon={<IconMore />} type="tertiary"></Button>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Form.Input initValue={r.name} field="name" label="Name" />
|
|
||||||
<Form.Select
|
|
||||||
optionList={Object.values(Cardinality).map((v) => ({
|
|
||||||
label: v,
|
|
||||||
value: v,
|
|
||||||
}))}
|
|
||||||
field="cardinality"
|
|
||||||
label="Cardinality"
|
|
||||||
initValue={r.cardinality}
|
|
||||||
className="w-full"
|
|
||||||
></Form.Select>
|
|
||||||
<Row gutter={6}>
|
|
||||||
<Col span={12}>
|
|
||||||
<Form.Select
|
|
||||||
optionList={Object.values(Constraint).map((v) => ({
|
|
||||||
label: v,
|
|
||||||
value: v,
|
|
||||||
}))}
|
|
||||||
field="updateConstraint"
|
|
||||||
label="On update"
|
|
||||||
initValue={r.updateConstraint}
|
|
||||||
className="w-full"
|
|
||||||
></Form.Select>
|
|
||||||
</Col>
|
|
||||||
<Col span={12}>
|
|
||||||
<Form.Select
|
|
||||||
optionList={Object.values(Constraint).map((v) => ({
|
|
||||||
label: v,
|
|
||||||
value: v,
|
|
||||||
}))}
|
|
||||||
field="deleteConstraint"
|
|
||||||
label="On delete"
|
|
||||||
initValue={r.deleteConstraint}
|
|
||||||
className="w-full"
|
|
||||||
></Form.Select>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
<div className="flex justify-between items-center my-3">
|
|
||||||
<label htmlFor="unique" className="font-medium text-black">
|
|
||||||
Mandetory
|
|
||||||
</label>
|
|
||||||
<Checkbox
|
|
||||||
value="mandetory"
|
|
||||||
checked={r.mandetory}
|
|
||||||
onChange={(checkedValues) =>
|
|
||||||
setRelationships((prev) =>
|
setRelationships((prev) =>
|
||||||
prev.map((e, idx) =>
|
prev.map((e, idx) =>
|
||||||
idx === i
|
idx === i ? { ...e, updateConstraint: value } : e
|
||||||
? {
|
|
||||||
...e,
|
|
||||||
[checkedValues.target.value]:
|
|
||||||
checkedValues.target.checked,
|
|
||||||
}
|
|
||||||
: e
|
|
||||||
)
|
)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
></Select>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<div className="font-semibold">On delete: </div>
|
||||||
|
<Select
|
||||||
|
optionList={Object.values(Constraint).map((v) => ({
|
||||||
|
label: v,
|
||||||
|
value: v,
|
||||||
|
}))}
|
||||||
|
value={r.deleteConstraint}
|
||||||
|
className="w-full"
|
||||||
|
onChange={(value) => {
|
||||||
|
setUndoStack((prev) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
action: Action.EDIT,
|
||||||
|
element: ObjectType.RELATIONSHIP,
|
||||||
|
rid: i,
|
||||||
|
undo: { deleteConstraint: r.deleteConstraint },
|
||||||
|
redo: { deleteConstraint: value },
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
setRedoStack([]);
|
||||||
|
setRelationships((prev) =>
|
||||||
|
prev.map((e, idx) =>
|
||||||
|
idx === i ? { ...e, deleteConstraint: value } : e
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
></Select>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<div className="flex justify-between items-center my-3">
|
||||||
|
<div className="font-semibold">Mandetory</div>
|
||||||
|
<Checkbox
|
||||||
|
value="mandetory"
|
||||||
|
checked={r.mandetory}
|
||||||
|
onChange={(checkedValues) => {
|
||||||
|
setUndoStack((prev) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
action: Action.EDIT,
|
||||||
|
element: ObjectType.RELATIONSHIP,
|
||||||
|
rid: i,
|
||||||
|
undo: {
|
||||||
|
[checkedValues.target.value]:
|
||||||
|
!checkedValues.target.checked,
|
||||||
|
},
|
||||||
|
redo: {
|
||||||
|
[checkedValues.target.value]:
|
||||||
|
checkedValues.target.checked,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
setRedoStack([]);
|
||||||
|
setRelationships((prev) =>
|
||||||
|
prev.map((e, idx) =>
|
||||||
|
idx === i
|
||||||
|
? {
|
||||||
|
...e,
|
||||||
|
[checkedValues.target.value]:
|
||||||
|
checkedValues.target.checked,
|
||||||
|
}
|
||||||
|
: e
|
||||||
)
|
)
|
||||||
}
|
);
|
||||||
></Checkbox>
|
}}
|
||||||
</div>
|
></Checkbox>
|
||||||
</Form>
|
</div>
|
||||||
<Row gutter={6} className="mt-1">
|
<Row gutter={6} className="mt-3">
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Button
|
<Button
|
||||||
icon={<IconRowsStroked />}
|
icon={<IconRowsStroked />}
|
||||||
|
@ -48,11 +48,10 @@ const Cardinality = {
|
|||||||
ONE_TO_ONE: "One to one",
|
ONE_TO_ONE: "One to one",
|
||||||
ONE_TO_MANY: "One to many",
|
ONE_TO_MANY: "One to many",
|
||||||
MANY_TO_ONE: "Many to one",
|
MANY_TO_ONE: "Many to one",
|
||||||
MANY_TO_MANY: "Many to many",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const Constraint = {
|
const Constraint = {
|
||||||
none: "None",
|
none: "No action",
|
||||||
restrict: "Restrict",
|
restrict: "Restrict",
|
||||||
cascade: "Cascade",
|
cascade: "Cascade",
|
||||||
setNull: "Set null",
|
setNull: "Set null",
|
||||||
|
@ -48,7 +48,7 @@ function dataURItoBlob(dataUrl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function jsonToSQL(obj) {
|
function jsonToSQL(obj) {
|
||||||
return obj.tables
|
return `${obj.tables
|
||||||
.map(
|
.map(
|
||||||
(table) =>
|
(table) =>
|
||||||
`${
|
`${
|
||||||
@ -86,7 +86,7 @@ function jsonToSQL(obj) {
|
|||||||
: ""
|
: ""
|
||||||
}\n);\n${
|
}\n);\n${
|
||||||
table.indices.length > 0
|
table.indices.length > 0
|
||||||
? `${table.indices.map(
|
? `\n${table.indices.map(
|
||||||
(i) =>
|
(i) =>
|
||||||
`\nCREATE ${i.unique ? "UNIQUE " : ""}INDEX \`${
|
`\nCREATE ${i.unique ? "UNIQUE " : ""}INDEX \`${
|
||||||
i.name
|
i.name
|
||||||
@ -97,7 +97,18 @@ function jsonToSQL(obj) {
|
|||||||
: ""
|
: ""
|
||||||
}`
|
}`
|
||||||
)
|
)
|
||||||
.join("\n\n");
|
.join("\n")}\n${obj.references
|
||||||
|
.map(
|
||||||
|
(r) =>
|
||||||
|
`ALTER TABLE \`${
|
||||||
|
obj.tables[r.startTableId].name
|
||||||
|
}\`\nADD FOREIGN KEY(\`${
|
||||||
|
obj.tables[r.startTableId].fields[r.startFieldId].name
|
||||||
|
}\`) REFERENCES \`${obj.tables[r.endTableId].name}\`(\`${
|
||||||
|
obj.tables[r.endTableId].fields[r.endFieldId].name
|
||||||
|
}\`)\nON UPDATE ${r.updateConstraint.toUpperCase()} ON DELETE ${r.deleteConstraint.toUpperCase()};`
|
||||||
|
)
|
||||||
|
.join("\n")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
Loading…
Reference in New Issue
Block a user