Lock notes and subject areas (#480)

This commit is contained in:
1ilit
2025-06-07 22:24:01 +04:00
committed by GitHub
parent 8bbe4da899
commit 938ad7c01d
6 changed files with 68 additions and 15 deletions

View File

@@ -1,6 +1,11 @@
import { useMemo, useRef, useState } from "react";
import { Button, Popover, Input, ColorPicker } from "@douyinfe/semi-ui";
import { IconEdit, IconDeleteStroked } from "@douyinfe/semi-icons";
import {
IconEdit,
IconDeleteStroked,
IconLock,
IconUnlock,
} from "@douyinfe/semi-icons";
import { Tab, Action, ObjectType, State } from "../../data/constants";
import {
useCanvas,
@@ -30,6 +35,7 @@ export default function Area({
const { layout } = useLayout();
const { settings } = useSettings();
const { setSaveState } = useSaveState();
const { updateArea } = useAreas();
const { selectedElement, setSelectedElement, bulkSelectedElements } =
useSelect();
@@ -45,6 +51,10 @@ export default function Area({
});
};
const lockUnlockArea = () => {
updateArea(data.id, { locked: !data.locked });
};
const edit = () => {
if (layout.sidebar) {
setSelectedElement((prev) => ({
@@ -123,25 +133,36 @@ export default function Area({
{data.name}
</div>
{(isHovered || (areaIsOpen() && !layout.sidebar)) && (
<Popover
visible={areaIsOpen() && !layout.sidebar}
onClickOutSide={onClickOutSide}
stopPropagation
content={<EditPopoverContent data={data} />}
trigger="custom"
position="rightTop"
showArrow
>
<div className="flex items-center gap-1.5">
<Button
icon={<IconEdit />}
icon={data.locked ? <IconLock /> : <IconUnlock />}
size="small"
theme="solid"
style={{
backgroundColor: "#2F68ADB3",
}}
onClick={edit}
onClick={lockUnlockArea}
/>
</Popover>
<Popover
visible={areaIsOpen() && !layout.sidebar}
onClickOutSide={onClickOutSide}
stopPropagation
content={<EditPopoverContent data={data} />}
trigger="custom"
position="rightTop"
showArrow
>
<Button
icon={<IconEdit />}
size="small"
theme="solid"
style={{
backgroundColor: "#2F68ADB3",
}}
onClick={edit}
/>
</Popover>
</div>
)}
</div>
</div>

View File

@@ -126,6 +126,8 @@ export default function Canvas() {
});
areas.forEach((area) => {
if (area.locked) return;
if (
isInsideRect(
{
@@ -145,6 +147,8 @@ export default function Canvas() {
});
notes.forEach((note) => {
if (note.locked) return;
if (
isInsideRect(
{
@@ -333,11 +337,17 @@ export default function Canvas() {
dragging.id !== null &&
areaResize.id === -1
) {
const area = areas.find((t) => t.id === dragging.id);
if (area.locked) return;
updateArea(dragging.id, {
x: pointer.spaces.diagram.x + grabOffset.x,
y: pointer.spaces.diagram.y + grabOffset.y,
});
} else if (dragging.element === ObjectType.NOTE && dragging.id !== null) {
const note = notes.find((t) => t.id === dragging.id);
if (note.locked) return;
updateNote(dragging.id, {
x: pointer.spaces.diagram.x + grabOffset.x,
y: pointer.spaces.diagram.y + grabOffset.y,

View File

@@ -1,7 +1,12 @@
import { useMemo, useState } from "react";
import { Action, ObjectType, Tab, State } from "../../data/constants";
import { Input, Button, Popover, ColorPicker } from "@douyinfe/semi-ui";
import { IconEdit, IconDeleteStroked } from "@douyinfe/semi-icons";
import {
IconEdit,
IconDeleteStroked,
IconLock,
IconUnlock,
} from "@douyinfe/semi-icons";
import {
useLayout,
useUndoRedo,
@@ -56,6 +61,10 @@ export default function Note({ data, onPointerDown }) {
setRedoStack([]);
};
const lockUnlockNote = () => {
updateNote(data.id, { locked: !data.locked });
};
const edit = () => {
setSelectedElement((prev) => ({
...prev,
@@ -152,7 +161,16 @@ export default function Note({ data, onPointerDown }) {
selectedElement.id === data.id &&
selectedElement.open &&
!layout.sidebar)) && (
<div>
<div className="flex items-center gap-1.5">
<Button
icon={data.locked ? <IconLock /> : <IconUnlock />}
size="small"
theme="solid"
style={{
backgroundColor: "#2F68ADB3",
}}
onClick={lockUnlockNote}
/>
<Popover
visible={
selectedElement.element === ObjectType.NOTE &&

View File

@@ -33,6 +33,7 @@ export default function AreasContextProvider({ children }) {
width,
height,
color: defaultBlue,
locked: false,
},
]);
}

View File

@@ -30,6 +30,7 @@ export default function NotesContextProvider({ children }) {
y: transform.pan.y - height / 2,
title: `note_${prev.length}`,
content: "",
locked: false,
color: defaultNoteTheme,
height,
},

View File

@@ -68,6 +68,7 @@ export const areaSchema = {
y: { type: "number" },
width: { type: "number" },
height: { type: "number" },
locked: { type: "boolean" },
color: { type: "string", pattern: "^#[0-9a-fA-F]{6}$" },
},
required: ["id", "name", "x", "y", "width", "height", "color"],
@@ -83,6 +84,7 @@ export const noteSchema = {
content: { type: "string" },
color: { type: "string", pattern: "^#[0-9a-fA-F]{6}$" },
height: { type: "number" },
locked: { type: "boolean" },
},
required: ["id", "x", "y", "title", "content", "color", "height"],
};