import { useState } from "react"; import { Action, ObjectType, defaultBlue, sqlDataTypes, tableThemes, } from "../data/constants"; import { Collapse, Row, Col, Input, TextArea, Button, Card, TagInput, InputNumber, Popover, Checkbox, Select, AutoComplete, Toast, } from "@douyinfe/semi-ui"; import { IconMore, IconKeyStroked, IconDeleteStroked, IconCheckboxTick, IconPlus, IconSearch, } from "@douyinfe/semi-icons"; import { getSize, hasCheck, hasPrecision, isSized } from "../utils/toSQL"; import useTables from "../hooks/useTables"; import useUndoRedo from "../hooks/useUndoRedo"; import useSelect from "../hooks/useSelect"; import useTypes from "../hooks/useTypes"; import NoElements from "./NoElements"; export default function TablesOverview() { const [searchText, setSearchText] = useState(""); const { tables, addTable } = useTables(); const { selectedElement, setSelectedElement } = useSelect(); const [filteredResult, setFilteredResult] = useState( tables.map((t) => t.name) ); const handleStringSearch = (value) => { setFilteredResult( tables.map((t) => t.name).filter((i) => i.includes(value)) ); }; return ( <> } placeholder="Search..." onSearch={(v) => handleStringSearch(v)} emptyContent={
No tables found
} onChange={(v) => setSearchText(v)} onSelect={(v) => { const { id } = tables.find((t) => t.name === v); setSelectedElement((prev) => ({ ...prev, id: id, open: true, })); document .getElementById(`scroll_table_${id}`) .scrollIntoView({ behavior: "smooth" }); }} className="w-full" />
{tables.length === 0 ? ( ) : ( setSelectedElement((prev) => ({ ...prev, id: parseInt(k), open: true, })) } accordion > {tables.map((t) => ( ))} )} ); } function TablePanel({ data }) { const [indexActiveKey, setIndexActiveKey] = useState(""); const { deleteTable, updateField, updateTable, setRelationships } = useTables(); const { types } = useTypes(); const { setUndoStack, setRedoStack } = useUndoRedo(); const [editField, setEditField] = useState({}); const deleteField = (field) => { setUndoStack((prev) => [ ...prev, { action: Action.EDIT, element: ObjectType.TABLE, component: "field_delete", tid: data.id, data: field, message: `Delete field`, }, ]); setRedoStack([]); // delete relationships that are connected to this field setRelationships((prev) => prev .filter( (e) => !( (e.startTableId === data.id && e.startFieldId === field.id) || (e.endTableId === data.id && e.endFieldId === field.id) ) ) .map((e, i) => ({ ...e, id: i })) ); // reassign relationship end and start field ids to match the ids after deleting setRelationships((prev) => { return prev.map((e) => { if (e.startTableId === data.id && e.startFieldId > field.id) { return { ...e, startFieldId: e.startFieldId - 1, startX: data.x + 15, startY: data.y + (e.startFieldId - 1) * 36 + 50 + 19, }; } if (e.endTableId === data.id && e.endFieldId > field.id) { return { ...e, endFieldId: e.endFieldId - 1, endX: data.x + 15, endY: data.y + (e.endFieldId - 1) * 36 + 50 + 19, }; } return e; }); }); // delete field and update ids updateTable(data.id, { fields: data.fields .filter((f) => f.id !== field.id) .map((e, i) => ({ ...e, id: i })), }); }; return (
{data.name}
} itemKey={`${data.id}`}>
Name:
updateTable(data.id, { name: value })} onFocus={(e) => setEditField({ name: e.target.value })} onBlur={(e) => { if (e.target.value === editField.name) return; setUndoStack((prev) => [ ...prev, { action: Action.EDIT, element: ObjectType.TABLE, component: "self", tid: data.id, undo: editField, redo: { name: e.target.value }, message: `Edit table name to ${e.target.value}`, }, ]); setRedoStack([]); }} />
{data.fields.map((f, j) => ( updateField(data.id, j, { name: value })} onFocus={(e) => setEditField({ name: e.target.value })} onBlur={(e) => { if (e.target.value === editField.name) return; setUndoStack((prev) => [ ...prev, { action: Action.EDIT, element: ObjectType.TABLE, component: "field", tid: data.id, fid: j, undo: editField, redo: { name: e.target.value }, message: `Edit table field name to ${e.target.value}`, }, ]); setRedoStack([]); }} /> updateField(data.id, j, { default: value }) } onFocus={(e) => setEditField({ default: e.target.value })} onBlur={(e) => { if (e.target.value === editField.default) return; setUndoStack((prev) => [ ...prev, { action: Action.EDIT, element: ObjectType.TABLE, component: "field", tid: data.id, fid: j, undo: editField, redo: { default: e.target.value }, message: `Edit table field default to ${e.target.value}`, }, ]); setRedoStack([]); }} /> {(f.type === "ENUM" || f.type === "SET") && ( <>
{f.type} values
updateField(data.id, j, { values: v }) } onFocus={() => setEditField({ values: f.values })} onBlur={() => { if ( JSON.stringify(editField.values) === JSON.stringify(f.values) ) return; setUndoStack((prev) => [ ...prev, { action: Action.EDIT, element: ObjectType.TABLE, component: "field", tid: data.id, fid: j, undo: editField, redo: { values: f.values }, message: `Edit table field values to "${JSON.stringify( f.values )}"`, }, ]); setRedoStack([]); }} /> )} {isSized(f.type) && ( <>
Size
updateField(data.id, j, { size: value }) } onFocus={(e) => setEditField({ size: e.target.value }) } onBlur={(e) => { if (e.target.value === editField.size) return; setUndoStack((prev) => [ ...prev, { action: Action.EDIT, element: ObjectType.TABLE, component: "field", tid: data.id, fid: j, undo: editField, redo: { size: e.target.value }, message: `Edit table field size to ${e.target.value}`, }, ]); setRedoStack([]); }} /> )} {hasPrecision(f.type) && ( <>
Precision
updateField(data.id, j, { size: value }) } onFocus={(e) => setEditField({ size: e.target.value }) } onBlur={(e) => { if (e.target.value === editField.size) return; setUndoStack((prev) => [ ...prev, { action: Action.EDIT, element: ObjectType.TABLE, component: "field", tid: data.id, fid: j, undo: editField, redo: { size: e.target.value }, message: `Edit table field precision to ${e.target.value}`, }, ]); setRedoStack([]); }} /> )} {hasCheck(f.type) && ( <>
Check Expression
updateField(data.id, j, { check: value }) } onFocus={(e) => setEditField({ check: e.target.value }) } onBlur={(e) => { if (e.target.value === editField.check) return; setUndoStack((prev) => [ ...prev, { action: Action.EDIT, element: ObjectType.TABLE, component: "field", tid: data.id, fid: j, undo: editField, redo: { check: e.target.value }, message: `Edit table field check expression to ${e.target.value}`, }, ]); setRedoStack([]); }} />
*This will be in the script as is.
)}
Unique
{ setUndoStack((prev) => [ ...prev, { action: Action.EDIT, element: ObjectType.TABLE, component: "field", tid: data.id, fid: j, undo: { [checkedValues.target.value]: !checkedValues.target.checked, }, redo: { [checkedValues.target.value]: checkedValues.target.checked, }, }, ]); setRedoStack([]); updateField(data.id, j, { [checkedValues.target.value]: checkedValues.target.checked, }); }} >
Autoincrement
{ setUndoStack((prev) => [ ...prev, { action: Action.EDIT, element: ObjectType.TABLE, component: "field", tid: data.id, fid: j, undo: { [checkedValues.target.value]: !checkedValues.target.checked, }, redo: { [checkedValues.target.value]: checkedValues.target.checked, }, message: `Edit table field to${ f.increment ? " not" : "" } auto increment`, }, ]); setRedoStack([]); updateField(data.id, j, { increment: !f.increment, check: f.increment ? f.check : "", }); }} >
Comment