brrr
This commit is contained in:
parent
d1a372d40b
commit
157634a0eb
@ -1,13 +1,33 @@
|
||||
import { React, useContext, useState } from "react";
|
||||
import { Button } from "@douyinfe/semi-ui";
|
||||
import { IconEdit } from "@douyinfe/semi-icons";
|
||||
import { Tab } from "../data/data";
|
||||
import { LayoutContext, TabContext } from "../pages/editor";
|
||||
import { Button, Popover, Input, Toast } from "@douyinfe/semi-ui";
|
||||
import {
|
||||
IconEdit,
|
||||
IconCheckboxTick,
|
||||
IconDeleteStroked,
|
||||
} from "@douyinfe/semi-icons";
|
||||
import {
|
||||
Tab,
|
||||
Action,
|
||||
ObjectType,
|
||||
tableThemes,
|
||||
defaultTableTheme,
|
||||
} from "../data/data";
|
||||
import {
|
||||
AreaContext,
|
||||
LayoutContext,
|
||||
TabContext,
|
||||
UndoRedoContext,
|
||||
} from "../pages/editor";
|
||||
|
||||
export default function Area(props) {
|
||||
const [hovered, setHovered] = useState(false);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [saved, setSaved] = useState(false);
|
||||
const [editField, setEditField] = useState("");
|
||||
const { layout } = useContext(LayoutContext);
|
||||
const { tab, setTab } = useContext(TabContext);
|
||||
const { updateArea, deleteArea } = useContext(AreaContext);
|
||||
const { setUndoStack, setRedoStack } = useContext(UndoRedoContext);
|
||||
|
||||
const handleMouseDown = (e, dir) => {
|
||||
props.setResize({ id: props.areaData.id, dir: dir });
|
||||
@ -24,7 +44,11 @@ export default function Area(props) {
|
||||
return (
|
||||
<g
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
onMouseLeave={() => {
|
||||
setHovered(false);
|
||||
setVisible(false);
|
||||
setSaved(false);
|
||||
}}
|
||||
>
|
||||
<foreignObject
|
||||
key={props.areaData.id}
|
||||
@ -51,24 +75,204 @@ export default function Area(props) {
|
||||
</div>
|
||||
{hovered && (
|
||||
<div className="absolute top-2 right-3">
|
||||
<Button
|
||||
icon={<IconEdit />}
|
||||
size="small"
|
||||
theme="solid"
|
||||
style={{
|
||||
backgroundColor: "#2f68ad",
|
||||
opacity: "0.7",
|
||||
}}
|
||||
onClick={() => {
|
||||
if (layout.sidebar) {
|
||||
setTab(Tab.subject_areas);
|
||||
if (tab !== Tab.subject_areas) return;
|
||||
document
|
||||
.getElementById(`scroll_area_${props.areaData.id}`)
|
||||
.scrollIntoView({ behavior: "smooth" });
|
||||
}
|
||||
}}
|
||||
></Button>
|
||||
<Popover
|
||||
visible={visible}
|
||||
content={
|
||||
<div>
|
||||
<div className="font-semibold mb-2 ms-1">
|
||||
Edit subject area
|
||||
</div>
|
||||
<div className="w-[280px] flex items-center mb-2">
|
||||
<Input
|
||||
value={props.areaData.name}
|
||||
placeholder="Name"
|
||||
className="me-2"
|
||||
onChange={(value) =>
|
||||
updateArea(props.areaData.id, { name: value })
|
||||
}
|
||||
onFocus={(e) => setEditField({ name: e.target.value })}
|
||||
onBlur={(e) => {
|
||||
setSaved(true);
|
||||
if (e.target.value === editField.name) return;
|
||||
setUndoStack((prev) => [
|
||||
...prev,
|
||||
{
|
||||
action: Action.EDIT,
|
||||
element: ObjectType.AREA,
|
||||
aid: props.areaData.id,
|
||||
undo: editField,
|
||||
redo: { name: e.target.value },
|
||||
},
|
||||
]);
|
||||
setRedoStack([]);
|
||||
}}
|
||||
/>
|
||||
<Popover
|
||||
content={
|
||||
<div>
|
||||
<div className="flex justify-between items-center p-2">
|
||||
<div className="font-medium">Theme</div>
|
||||
<Button
|
||||
type="tertiary"
|
||||
size="small"
|
||||
onClick={() =>
|
||||
updateArea(props.areaData.id, {
|
||||
color: defaultTableTheme,
|
||||
})
|
||||
}
|
||||
>
|
||||
Clear
|
||||
</Button>
|
||||
</div>
|
||||
<hr />
|
||||
<div className="py-3">
|
||||
<div>
|
||||
{tableThemes
|
||||
.slice(0, Math.ceil(tableThemes.length / 2))
|
||||
.map((c) => (
|
||||
<button
|
||||
key={c}
|
||||
style={{ backgroundColor: c }}
|
||||
className="p-3 rounded-full mx-1"
|
||||
onClick={() => {
|
||||
setUndoStack((prev) => [
|
||||
...prev,
|
||||
{
|
||||
action: Action.EDIT,
|
||||
element: ObjectType.AREA,
|
||||
aid: props.areaData.id,
|
||||
undo: { color: props.areaData.color },
|
||||
redo: { color: c },
|
||||
},
|
||||
]);
|
||||
setRedoStack([]);
|
||||
updateArea(props.areaData.id, {
|
||||
color: c,
|
||||
});
|
||||
}}
|
||||
>
|
||||
{props.areaData.color === c ? (
|
||||
<IconCheckboxTick
|
||||
style={{ color: "white" }}
|
||||
/>
|
||||
) : (
|
||||
<IconCheckboxTick style={{ color: c }} />
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
{tableThemes
|
||||
.slice(Math.ceil(tableThemes.length / 2))
|
||||
.map((c) => (
|
||||
<button
|
||||
key={c}
|
||||
style={{ backgroundColor: c }}
|
||||
className="p-3 rounded-full mx-1"
|
||||
onClick={() => {
|
||||
setUndoStack((prev) => [
|
||||
...prev,
|
||||
{
|
||||
action: Action.EDIT,
|
||||
element: ObjectType.AREA,
|
||||
aid: props.areaData.id,
|
||||
undo: { color: props.areaData.color },
|
||||
redo: { color: c },
|
||||
},
|
||||
]);
|
||||
setRedoStack([]);
|
||||
updateArea(props.areaData.id, {
|
||||
color: c,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<IconCheckboxTick
|
||||
style={{
|
||||
color:
|
||||
props.areaData.color === c
|
||||
? "white"
|
||||
: c,
|
||||
}}
|
||||
/>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
trigger="click"
|
||||
position="bottomLeft"
|
||||
showArrow
|
||||
>
|
||||
<div
|
||||
className="h-[32px] w-[32px] rounded"
|
||||
style={{ backgroundColor: props.areaData.color }}
|
||||
/>
|
||||
</Popover>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<Button
|
||||
icon={<IconDeleteStroked />}
|
||||
type="danger"
|
||||
block
|
||||
onClick={() => {
|
||||
Toast.success(`Area deleted!`);
|
||||
deleteArea(props.areaData.id, true);
|
||||
}}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
<Button
|
||||
block
|
||||
style={{ marginLeft: "8px" }}
|
||||
onClick={() => {
|
||||
if (!saved) {
|
||||
if (props.areaData.name === editField.name) return;
|
||||
setUndoStack((prev) => [
|
||||
...prev,
|
||||
{
|
||||
action: Action.EDIT,
|
||||
element: ObjectType.AREA,
|
||||
aid: props.areaData.id,
|
||||
undo: editField,
|
||||
redo: { name: props.areaData.name },
|
||||
},
|
||||
]);
|
||||
setRedoStack([]);
|
||||
setSaved(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
trigger="custom"
|
||||
position="rightTop"
|
||||
showArrow
|
||||
>
|
||||
<Button
|
||||
icon={<IconEdit />}
|
||||
size="small"
|
||||
theme="solid"
|
||||
style={{
|
||||
backgroundColor: "#2f68ad",
|
||||
opacity: "0.7",
|
||||
}}
|
||||
onClick={() => {
|
||||
if (layout.sidebar) {
|
||||
setTab(Tab.subject_areas);
|
||||
if (tab !== Tab.subject_areas) return;
|
||||
document
|
||||
.getElementById(`scroll_area_${props.areaData.id}`)
|
||||
.scrollIntoView({ behavior: "smooth" });
|
||||
} else {
|
||||
setVisible(true);
|
||||
}
|
||||
}}
|
||||
></Button>
|
||||
</Popover>
|
||||
</div>
|
||||
)}
|
||||
</foreignObject>
|
||||
|
@ -222,8 +222,7 @@ export default function AreaOverview(props) {
|
||||
<Button
|
||||
icon={<IconDeleteStroked />}
|
||||
type="danger"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onClick={() => {
|
||||
Toast.success(`Area deleted!`);
|
||||
deleteArea(i, true);
|
||||
}}
|
||||
|
@ -161,14 +161,7 @@ export default function ControlPanel(props) {
|
||||
setRedoStack((prev) => [...prev, a]);
|
||||
} else if (a.action === Action.EDIT) {
|
||||
if (a.element === ObjectType.AREA) {
|
||||
setAreas((prev) =>
|
||||
prev.map((n) => {
|
||||
if (n.id === a.aid) {
|
||||
return { ...n, ...a.undo };
|
||||
}
|
||||
return n;
|
||||
})
|
||||
);
|
||||
updateArea(a.aid, a.undo);
|
||||
} else if (a.element === ObjectType.NOTE) {
|
||||
updateNote(a.nid, a.undo);
|
||||
} else if (a.element === ObjectType.TABLE) {
|
||||
@ -293,14 +286,7 @@ export default function ControlPanel(props) {
|
||||
setUndoStack((prev) => [...prev, a]);
|
||||
} else if (a.action === Action.EDIT) {
|
||||
if (a.element === ObjectType.AREA) {
|
||||
setAreas((prev) =>
|
||||
prev.map((n) => {
|
||||
if (n.id === a.aid) {
|
||||
return { ...n, ...a.redo };
|
||||
}
|
||||
return n;
|
||||
})
|
||||
);
|
||||
updateArea(a.aid, a.redo);
|
||||
} else if (a.element === ObjectType.NOTE) {
|
||||
updateNote(a.nid, a.redo);
|
||||
} else if (a.element === ObjectType.TABLE) {
|
||||
|
@ -102,8 +102,6 @@ export default function NotesOverview(props) {
|
||||
>
|
||||
<div className="flex justify-between align-top">
|
||||
<TextArea
|
||||
field="content"
|
||||
label="Content"
|
||||
placeholder="Add content"
|
||||
value={n.content}
|
||||
autosize
|
||||
|
@ -22,7 +22,6 @@ import {
|
||||
Input,
|
||||
TextArea,
|
||||
Card,
|
||||
Form,
|
||||
Checkbox,
|
||||
Row,
|
||||
Col,
|
||||
@ -42,12 +41,10 @@ import {
|
||||
|
||||
export default function Table(props) {
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const [indexActiveKey, setIndexActiveKey] = useState("");
|
||||
const [hoveredField, setHoveredField] = useState(-1);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { layout } = useContext(LayoutContext);
|
||||
const { setTables, deleteTable, updateTable, updateField } =
|
||||
useContext(TableContext);
|
||||
const { deleteTable, updateTable, updateField } = useContext(TableContext);
|
||||
const { tab, setTab } = useContext(TabContext);
|
||||
const { settings } = useContext(SettingsContext);
|
||||
|
||||
@ -813,7 +810,6 @@ export default function Table(props) {
|
||||
<Button
|
||||
block
|
||||
onClick={() => {
|
||||
setIndexActiveKey("1");
|
||||
setUndoStack((prev) => [
|
||||
...prev,
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user