Undo redo parsing for references

This commit is contained in:
1ilit 2023-09-19 15:50:46 +03:00
parent ab0dc2c44e
commit 2b2e4840c9
4 changed files with 197 additions and 135 deletions

View File

@ -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) {
return {
...table,
indices: table.indices
.filter((e) => e.id !== tables[a.tid].indices.length - 1) .filter((e) => e.id !== tables[a.tid].indices.length - 1)
.map((t, i) => ({ ...t, id: i })), .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>

View File

@ -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,48 +100,35 @@ 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) =>
setRelationships((prev) =>
prev.map((e, idx) =>
idx === i ? { ...e, ...value.values } : e
)
)
}
>
<div className="flex justify-between items-center my-1">
<div className="me-3"> <div className="me-3">
<strong>Primary: </strong> <span className="font-semibold">Primary: </span>
{tables[r.endTableId].name} {tables[r.endTableId].name}
</div> </div>
<div className="mx-1"> <div className="mx-1">
<strong>Foreign: </strong> <span className="font-semibold">Foreign: </span>
{tables[r.startTableId].name} {tables[r.startTableId].name}
</div> </div>
<div className="ms-1"> <div className="ms-1">
<Popover <Popover
content={ content={
<div className="p-2 w-[260px]"> <div className="p-2">
<Table <Table
columns={columns} columns={columns}
dataSource={[ dataSource={[
{ {
key: "1", key: "1",
foreign: tables[r.startTableId].name, foreign: `${tables[r.startTableId].name}(${
primary: tables[r.endTableId].name, tables[r.startTableId].fields[r.startFieldId]
}, .name
{ })`,
key: "2", primary: `${tables[r.endTableId].name}(${
foreign: tables[r.endTableId].fields[r.endFieldId].name
tables[r.startTableId].fields[ })`,
r.startFieldId
].name,
primary:
tables[r.endTableId].fields[r.endFieldId]
.name,
}, },
]} ]}
pagination={false} pagination={false}
size="small"
bordered bordered
/> />
<div className="mt-2"> <div className="mt-2">
@ -158,51 +146,116 @@ export default function ReferenceOverview(props) {
</Popover> </Popover>
</div> </div>
</div> </div>
<Form.Input initValue={r.name} field="name" label="Name" /> <div className="font-semibold my-1">Cardinality</div>
<Form.Select <Select
optionList={Object.values(Cardinality).map((v) => ({ optionList={Object.values(Cardinality).map((v) => ({
label: v, label: v,
value: v, value: v,
}))} }))}
field="cardinality" value={r.cardinality}
label="Cardinality"
initValue={r.cardinality}
className="w-full" className="w-full"
></Form.Select> onChange={(value) => {
<Row gutter={6}> setUndoStack((prev) => [
...prev,
{
action: Action.EDIT,
element: ObjectType.RELATIONSHIP,
rid: i,
undo: { cardinality: r.cardinality },
redo: { cardinality: value },
},
]);
setRedoStack([]);
setRelationships((prev) =>
prev.map((e, idx) =>
idx === i ? { ...e, cardinality: value } : e
)
);
}}
></Select>
<Row gutter={6} className="my-3">
<Col span={12}> <Col span={12}>
<Form.Select <div className="font-semibold">On update: </div>
<Select
optionList={Object.values(Constraint).map((v) => ({ optionList={Object.values(Constraint).map((v) => ({
label: v, label: v,
value: v, value: v,
}))} }))}
field="updateConstraint" value={r.updateConstraint}
label="On update"
initValue={r.updateConstraint}
className="w-full" className="w-full"
></Form.Select> onChange={(value) => {
setUndoStack((prev) => [
...prev,
{
action: Action.EDIT,
element: ObjectType.RELATIONSHIP,
rid: i,
undo: { updateConstraint: r.updateConstraint },
redo: { updateConstraint: value },
},
]);
setRedoStack([]);
setRelationships((prev) =>
prev.map((e, idx) =>
idx === i ? { ...e, updateConstraint: value } : e
)
);
}}
></Select>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Select <div className="font-semibold">On delete: </div>
<Select
optionList={Object.values(Constraint).map((v) => ({ optionList={Object.values(Constraint).map((v) => ({
label: v, label: v,
value: v, value: v,
}))} }))}
field="deleteConstraint" value={r.deleteConstraint}
label="On delete"
initValue={r.deleteConstraint}
className="w-full" className="w-full"
></Form.Select> 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> </Col>
</Row> </Row>
<div className="flex justify-between items-center my-3"> <div className="flex justify-between items-center my-3">
<label htmlFor="unique" className="font-medium text-black"> <div className="font-semibold">Mandetory</div>
Mandetory
</label>
<Checkbox <Checkbox
value="mandetory" value="mandetory"
checked={r.mandetory} checked={r.mandetory}
onChange={(checkedValues) => 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) => setRelationships((prev) =>
prev.map((e, idx) => prev.map((e, idx) =>
idx === i idx === i
@ -213,12 +266,11 @@ export default function ReferenceOverview(props) {
} }
: e : e
) )
) );
} }}
></Checkbox> ></Checkbox>
</div> </div>
</Form> <Row gutter={6} className="mt-3">
<Row gutter={6} className="mt-1">
<Col span={12}> <Col span={12}>
<Button <Button
icon={<IconRowsStroked />} icon={<IconRowsStroked />}

View File

@ -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",

View File

@ -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 {