diff --git a/src/components/ColorPallete.jsx b/src/components/ColorPallete.jsx new file mode 100644 index 0000000..b822d1c --- /dev/null +++ b/src/components/ColorPallete.jsx @@ -0,0 +1,55 @@ +import { Button } from "@douyinfe/semi-ui"; +import { IconCheckboxTick } from "@douyinfe/semi-icons"; +import { tableThemes } from "../data/constants"; + +export default function ColorPallete({ + currentColor, + onClearColor, + onPickColor, +}) { + return ( +
+
+
Theme
+ +
+
+
+
+ {tableThemes.slice(0, Math.ceil(tableThemes.length / 2)).map((c) => ( + + ))} +
+
+ {tableThemes.slice(Math.ceil(tableThemes.length / 2)).map((c) => ( + + ))} +
+
+
+ ); +} diff --git a/src/components/EditorCanvas/Table.jsx b/src/components/EditorCanvas/Table.jsx index 2d28f99..1b9fc4c 100644 --- a/src/components/EditorCanvas/Table.jsx +++ b/src/components/EditorCanvas/Table.jsx @@ -45,8 +45,13 @@ export default function Table(props) { const [hoveredField, setHoveredField] = useState(-1); const [editField, setEditField] = useState({}); const { layout } = useLayout(); - const { deleteTable, updateTable, updateField, setRelationships } = - useTables(); + const { + deleteTable, + updateTable, + updateField, + deleteField, + setRelationships, + } = useTables(); const { settings } = useSettings(); const { types } = useTypes(); const { setUndoStack, setRedoStack } = useUndoRedo(); @@ -1269,63 +1274,7 @@ export default function Table(props) { backgroundColor: "#d42020", }} icon={} - onClick={() => { - setUndoStack((prev) => [ - ...prev, - { - action: Action.EDIT, - element: ObjectType.TABLE, - component: "field_delete", - tid: props.tableData.id, - data: fieldData, - message: `Delete field`, - }, - ]); - setRedoStack([]); - setRelationships((prev) => - prev - .filter( - (e) => - !( - (e.startTableId === props.tableData.id && - e.startFieldId === index) || - (e.endTableId === props.tableData.id && - e.endFieldId === index) - ) - ) - .map((e, i) => ({ ...e, id: i })) - ); - setRelationships((prev) => { - return prev.map((e) => { - if ( - e.startTableId === props.tableData.id && - e.startFieldId > fieldData.id - ) { - return { - ...e, - startFieldId: e.startFieldId - 1, - }; - } - if ( - e.endTableId === props.tableData.id && - e.endFieldId > fieldData.id - ) { - return { - ...e, - endFieldId: e.endFieldId - 1, - }; - } - return e; - }); - }); - updateTable(props.tableData.id, { - fields: props.tableData.fields - .filter((e) => e.id !== fieldData.id) - .map((t, i) => { - return { ...t, id: i }; - }), - }); - }} + onClick={() => deleteField(fieldData, props.tableData.id)} /> ) : (
diff --git a/src/components/EditorSidePanel/AreasOverview.jsx b/src/components/EditorSidePanel/AreasOverview.jsx deleted file mode 100644 index d1a59e2..0000000 --- a/src/components/EditorSidePanel/AreasOverview.jsx +++ /dev/null @@ -1,227 +0,0 @@ -import { useState } from "react"; -import { - Row, - Col, - AutoComplete, - Button, - Input, - Popover, - Toast, -} from "@douyinfe/semi-ui"; -import { - IconPlus, - IconSearch, - IconCheckboxTick, - IconDeleteStroked, -} from "@douyinfe/semi-icons"; -import { - defaultBlue, - tableThemes, - Action, - ObjectType, - State, -} from "../../data/constants"; -import { useUndoRedo, useAreas, useSaveState } from "../../hooks"; -import Empty from "./Empty"; - -export default function AreasOverview() { - const { setSaveState } = useSaveState(); - const { areas, addArea, deleteArea, updateArea } = useAreas(); - const { setUndoStack, setRedoStack } = useUndoRedo(); - const [editField, setEditField] = useState({}); - const [searchText, setSearchText] = useState(""); - const [filteredResult, setFilteredResult] = useState( - areas.map((t) => t.name) - ); - - const handleStringSearch = (value) => { - setFilteredResult( - areas.map((t) => t.name).filter((i) => i.includes(value)) - ); - }; - - return ( -
- - - } - placeholder="Search..." - emptyContent={ -
No areas found
- } - onSearch={(v) => handleStringSearch(v)} - onChange={(v) => setSearchText(v)} - onSelect={(v) => { - const { id } = areas.find((t) => t.name === v); - document - .getElementById(`scroll_area_${id}`) - .scrollIntoView({ behavior: "smooth" }); - }} - className="w-full" - /> - - - - -
- {areas.length <= 0 ? ( - - ) : ( -
- {areas.map((a, i) => ( - - - updateArea(a.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.AREA, - aid: i, - undo: editField, - redo: { name: e.target.value }, - message: `Edit area name to ${e.target.value}`, - }, - ]); - setRedoStack([]); - }} - /> - - - -
-
Theme
- -
-
-
-
- {tableThemes - .slice(0, Math.ceil(tableThemes.length / 2)) - .map((c) => ( - - ))} -
-
- {tableThemes - .slice(Math.ceil(tableThemes.length / 2)) - .map((c) => ( - - ))} -
-
-
- } - trigger="click" - position="bottomLeft" - showArrow - > -
- - - -
- )} -
- ); -} diff --git a/src/components/EditorSidePanel/AreasTab/AreaDetails.jsx b/src/components/EditorSidePanel/AreasTab/AreaDetails.jsx new file mode 100644 index 0000000..3c9802b --- /dev/null +++ b/src/components/EditorSidePanel/AreasTab/AreaDetails.jsx @@ -0,0 +1,101 @@ +import { useState } from "react"; +import { Row, Col, Button, Input, Popover, Toast } from "@douyinfe/semi-ui"; +import { IconDeleteStroked } from "@douyinfe/semi-icons"; +import { useAreas, useSaveState, useUndoRedo } from "../../../hooks"; +import { + Action, + ObjectType, + State, + defaultBlue, +} from "../../../data/constants"; +import ColorPallete from "../../ColorPallete"; + +export default function AreaInfo({ data, i }) { + const { setSaveState } = useSaveState(); + const { deleteArea, updateArea } = useAreas(); + const { setUndoStack, setRedoStack } = useUndoRedo(); + const [editField, setEditField] = useState({}); + + return ( + + + updateArea(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.AREA, + aid: i, + undo: editField, + redo: { name: e.target.value }, + message: `Edit area name to ${e.target.value}`, + }, + ]); + setRedoStack([]); + }} + /> + + + + { + updateArea(i, { color: defaultBlue }); + setSaveState(State.SAVING); + }} + onPickColor={(c) => { + setUndoStack((prev) => [ + ...prev, + { + action: Action.EDIT, + element: ObjectType.AREA, + aid: i, + undo: { color: data.color }, + redo: { color: c }, + message: `Edit area color to ${c}`, + }, + ]); + setRedoStack([]); + updateArea(i, { color: c }); + }} + /> +
+ } + trigger="click" + position="bottomLeft" + showArrow + > +
+ + + + + + + {areas.length <= 0 ? ( + + ) : ( +
+ {areas.map((a, i) => ( + + ))} +
+ )} +
+ ); +} diff --git a/src/components/EditorSidePanel/AreasTab/SearchBar.jsx b/src/components/EditorSidePanel/AreasTab/SearchBar.jsx new file mode 100644 index 0000000..c42191a --- /dev/null +++ b/src/components/EditorSidePanel/AreasTab/SearchBar.jsx @@ -0,0 +1,39 @@ +import { useState } from "react"; +import { useAreas } from "../../../hooks"; +import { AutoComplete } from "@douyinfe/semi-ui"; +import { IconSearch } from "@douyinfe/semi-icons"; + +export default function SearchBar() { + const { areas } = useAreas(); + const [searchText, setSearchText] = useState(""); + + const [filteredResult, setFilteredResult] = useState( + areas.map((t) => t.name) + ); + + const handleStringSearch = (value) => { + setFilteredResult( + areas.map((t) => t.name).filter((i) => i.includes(value)) + ); + }; + + return ( + } + placeholder="Search..." + emptyContent={
No areas found
} + onSearch={(v) => handleStringSearch(v)} + onChange={(v) => setSearchText(v)} + onSelect={(v) => { + const { id } = areas.find((t) => t.name === v); + document + .getElementById(`scroll_area_${id}`) + .scrollIntoView({ behavior: "smooth" }); + }} + className="w-full" + /> + ); +} diff --git a/src/components/EditorSidePanel/NotesOverview.jsx b/src/components/EditorSidePanel/NotesOverview.jsx deleted file mode 100644 index df8a912..0000000 --- a/src/components/EditorSidePanel/NotesOverview.jsx +++ /dev/null @@ -1,212 +0,0 @@ -import { useState } from "react"; -import { - Row, - Col, - Button, - Collapse, - AutoComplete, - TextArea, - Popover, - Input, - Toast, -} from "@douyinfe/semi-ui"; -import { - IconDeleteStroked, - IconPlus, - IconSearch, - IconCheckboxTick, -} from "@douyinfe/semi-icons"; -import { noteThemes, Action, ObjectType } from "../../data/constants"; -import { useUndoRedo, useNotes } from "../../hooks"; -import Empty from "./Empty"; - -export default function NotesOverview() { - const { notes, updateNote, addNote, deleteNote } = useNotes(); - const { setUndoStack, setRedoStack } = useUndoRedo(); - const [searchText, setSearchText] = useState(""); - const [editField, setEditField] = useState({}); - const [activeKey, setActiveKey] = useState(""); - const [filteredResult, setFilteredResult] = useState( - notes.map((t) => t.title) - ); - - const handleStringSearch = (value) => { - setFilteredResult( - notes.map((t) => t.title).filter((i) => i.includes(value)) - ); - }; - - return ( -
- - - } - placeholder="Search..." - emptyContent={ -
No notes found
- } - onSearch={(v) => handleStringSearch(v)} - onChange={(v) => setSearchText(v)} - onSelect={(v) => { - const { id } = notes.find((t) => t.title === v); - setActiveKey(`${id}`); - document - .getElementById(`scroll_note_${id}`) - .scrollIntoView({ behavior: "smooth" }); - }} - className="w-full" - /> - - - - -
- {notes.length <= 0 ? ( - - ) : ( - setActiveKey(k)} - accordion - > - {notes.map((n, i) => ( - - {n.title} -
- } - itemKey={`${n.id}`} - id={`scroll_note_${n.id}`} - key={n.id} - > -
-
Title:
- updateNote(n.id, { title: value })} - onFocus={(e) => setEditField({ title: e.target.value })} - onBlur={(e) => { - if (e.target.value === editField.title) return; - setUndoStack((prev) => [ - ...prev, - { - action: Action.EDIT, - element: ObjectType.NOTE, - nid: n.id, - undo: editField, - redo: { title: e.target.value }, - message: `Edit note title to "${e.target.name}"`, - }, - ]); - setRedoStack([]); - }} - /> -
-
-