Change move to batch move only (#508)

* add notDragging constant

* change move to only bulk move
This commit is contained in:
Karen Mkrtumyan
2025-07-01 17:49:35 +04:00
committed by GitHub
parent 550cc78000
commit e609003b25
4 changed files with 107 additions and 178 deletions

View File

@@ -37,8 +37,12 @@ export default function Area({
const { settings } = useSettings(); const { settings } = useSettings();
const { setSaveState } = useSaveState(); const { setSaveState } = useSaveState();
const { updateArea } = useAreas(); const { updateArea } = useAreas();
const { selectedElement, setSelectedElement, bulkSelectedElements } = const {
useSelect(); selectedElement,
setSelectedElement,
bulkSelectedElements,
setBulkSelectedElements,
} = useSelect();
const handleResize = (e, dir) => { const handleResize = (e, dir) => {
setResize({ id: data.id, dir: dir }); setResize({ id: data.id, dir: dir });
@@ -53,6 +57,9 @@ export default function Area({
}; };
const lockUnlockArea = () => { const lockUnlockArea = () => {
setBulkSelectedElements((prev) =>
prev.filter((el) => el.id !== data.id || el.type !== ObjectType.AREA),
);
updateArea(data.id, { locked: !data.locked }); updateArea(data.id, { locked: !data.locked });
}; };

View File

@@ -56,13 +56,14 @@ export default function Canvas() {
bulkSelectedElements, bulkSelectedElements,
setBulkSelectedElements, setBulkSelectedElements,
} = useSelect(); } = useSelect();
const [dragging, setDragging] = useState({ const notDragging = {
element: ObjectType.NONE, element: ObjectType.NONE,
id: null, id: null,
prevX: 0, prevX: 0,
prevY: 0, prevY: 0,
initialPositions: [], initialPositions: [],
}); };
const [dragging, setDragging] = useState(notDragging);
const [linking, setLinking] = useState(false); const [linking, setLinking] = useState(false);
const [linkingLine, setLinkingLine] = useState({ const [linkingLine, setLinkingLine] = useState({
startTableId: -1, startTableId: -1,
@@ -181,7 +182,7 @@ export default function Canvas() {
case ObjectType.NOTE: case ObjectType.NOTE:
return notes[element.id]; return notes[element.id];
default: default:
return { x: 0, y: 0 }; return { x: 0, y: 0, locked: false };
} }
}; };
@@ -195,67 +196,45 @@ export default function Canvas() {
if (!e.isPrimary) return; if (!e.isPrimary) return;
let locked = false; const element = getElement({ id, type });
let prevCoords = { prevX: 0, prevY: 0 };
if (type === ObjectType.TABLE) { setSelectedElement((prev) => ({
const table = tables.find((t) => t.id === id); ...prev,
locked = table.locked; element: type,
id: id,
open: false,
}));
setGrabOffset({ if (element.locked) {
x: table.x - pointer.spaces.diagram.x, setBulkSelectedElements([]);
y: table.y - pointer.spaces.diagram.y, return;
});
prevCoords = { prevX: table.x, prevY: table.y };
} else if (type === ObjectType.AREA) {
const area = areas.find((t) => t.id === id);
locked = area.locked;
setGrabOffset({
x: area.x - pointer.spaces.diagram.x,
y: area.y - pointer.spaces.diagram.y,
});
prevCoords = { prevX: area.x, prevY: area.y };
} else if (type === ObjectType.NOTE) {
const note = notes.find((t) => t.id === id);
locked = note.locked;
setGrabOffset({
x: note.x - pointer.spaces.diagram.x,
y: note.y - pointer.spaces.diagram.y,
});
prevCoords = { prevX: note.x, prevY: note.y };
} }
if (!locked) { let prevCoords = { prevX: element.x, prevY: element.y };
setDragging((prev) => ({ setGrabOffset({
...prev, x: element.x - pointer.spaces.diagram.x,
id, y: element.y - pointer.spaces.diagram.y,
element: type, });
...prevCoords,
})); let newBulkSelectedElements;
setSelectedElement((prev) => ({ if (bulkSelectedElements.some((el) => el.id === id && el.type === type)) {
...prev, newBulkSelectedElements = bulkSelectedElements;
element: type, } else {
id: id, newBulkSelectedElements = [{ id, type }];
open: false, setBulkSelectedElements(newBulkSelectedElements);
}));
} }
if (bulkSelectedElements.length) { setDragging((prev) => ({
setDragging((prev) => ({ ...prev,
...prev, id,
initialPositions: bulkSelectedElements.map((element) => ({ element: type,
...element, ...prevCoords,
undo: { initialPositions: newBulkSelectedElements.map((el) => {
x: getElement(element).x, const { x, y } = getElement(el);
y: getElement(element).y, return { ...el, undo: { x, y } };
}, }),
})), }));
}));
}
}; };
/** /**
* @param {PointerEvent} e * @param {PointerEvent} e
*/ */
@@ -302,39 +281,30 @@ export default function Canvas() {
endX: pointer.spaces.diagram.x, endX: pointer.spaces.diagram.x,
endY: pointer.spaces.diagram.y, endY: pointer.spaces.diagram.y,
}); });
} else if ( return;
dragging.element !== ObjectType.NONE && }
dragging.id !== null &&
bulkSelectedElements.length && if (isDragging) {
bulkSelectedElements.some( for (const el of bulkSelectedElements) {
(element) => const element = getElement(el);
element.id === dragging.id && element.type === dragging.element, const { type } = el;
) if (element.locked) continue;
) { const { x, y } = element;
for (const element of bulkSelectedElements) {
if (element.type === ObjectType.TABLE) { if (type === ObjectType.TABLE) {
const table = tables.find((e) => e.id === element.id); updateTable(el.id, {
if (table.locked) continue;
const { x, y } = table;
updateTable(element.id, {
x: x + deltaX, x: x + deltaX,
y: y + deltaY, y: y + deltaY,
}); });
} }
if (element.type === ObjectType.AREA) { if (type === ObjectType.AREA) {
const area = areas[element.id]; updateArea(el.id, {
if (area.locked) continue;
const { x, y } = area;
updateArea(element.id, {
x: x + deltaX, x: x + deltaX,
y: y + deltaY, y: y + deltaY,
}); });
} }
if (element.type === ObjectType.NOTE) { if (type === ObjectType.NOTE) {
const note = notes[element.id]; updateNote(el.id, {
if (note.locked) continue;
const { x, y } = note;
updateNote(element.id, {
x: x + deltaX, x: x + deltaX,
y: y + deltaY, y: y + deltaY,
}); });
@@ -346,35 +316,10 @@ export default function Canvas() {
prevX: finalX, prevX: finalX,
prevY: finalY, prevY: finalY,
})); }));
} else if (dragging.element === ObjectType.TABLE && dragging.id !== null) { return;
const table = tables.find((t) => t.id === dragging.id); }
if (table.locked) return;
updateTable(dragging.id, { if (areaResize.id !== -1) {
x: finalX,
y: finalY,
});
} else if (
dragging.element === ObjectType.AREA &&
dragging.id !== null &&
areaResize.id === -1
) {
const area = areas.find((t) => t.id === dragging.id);
if (area.locked) return;
updateArea(dragging.id, {
x: finalX,
y: finalY,
});
} 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: finalX,
y: finalY,
});
} else if (areaResize.id !== -1) {
if (areaResize.dir === "none") return; if (areaResize.dir === "none") return;
let newDims = { ...initCoords }; let newDims = { ...initCoords };
delete newDims.pointerX; delete newDims.pointerX;
@@ -405,7 +350,10 @@ export default function Canvas() {
} }
updateArea(areaResize.id, { ...newDims }); updateArea(areaResize.id, { ...newDims });
} else if (bulkSelectRectPts.show) { return;
}
if (bulkSelectRectPts.show) {
setBulkSelectRectPts((prev) => ({ setBulkSelectRectPts((prev) => ({
...prev, ...prev,
x2: finalX, x2: finalX,
@@ -452,7 +400,8 @@ export default function Canvas() {
} }
}; };
const coordsDidUpdate = (element) => { const coordsDidUpdate = () => {
const element = { id: dragging.id, type: dragging.element };
const elementData = getElement(element); const elementData = getElement(element);
const updated = !( const updated = !(
dragging.prevX === elementData.x && dragging.prevY === elementData.y dragging.prevX === elementData.x && dragging.prevY === elementData.y
@@ -489,60 +438,24 @@ export default function Canvas() {
if (!e.isPrimary) return; if (!e.isPrimary) return;
let bulkMoved = false; const coordinatesDidUpdate = coordsDidUpdate();
if (coordsDidUpdate({ id: dragging.id, type: dragging.element })) { if (coordinatesDidUpdate) {
if (bulkSelectedElements.length) { setUndoStack((prev) => [
setUndoStack((prev) => [ ...prev,
...prev, {
{ action: Action.MOVE,
action: Action.MOVE, bulk: true,
bulk: true, message: t("bulk_update"),
message: t("bulk_update"), elements: dragging.initialPositions.map((element) => {
elements: dragging.initialPositions.map((element) => ({ const { x, y } = getElement(element);
...element, return { ...element, redo: { x, y } };
redo: { }),
x: getElement(element).x, },
y: getElement(element).y, ]);
},
})),
},
]);
bulkMoved = true;
} else {
const element = getElement({
id: dragging.id,
type: dragging.element,
});
setUndoStack((prev) => [
...prev,
{
action: Action.MOVE,
element: dragging.element,
x: dragging.prevX,
y: dragging.prevY,
toX: element.x,
toY: element.y,
id: dragging.id,
message: t("move_element", {
coords: `(${element.x}, ${element.y})`,
name: getElement({
id: dragging.id,
type: dragging.element,
}).name,
}),
},
]);
}
setRedoStack([]); setRedoStack([]);
} }
setDragging({ setDragging(notDragging);
element: ObjectType.NONE,
id: null,
prevX: 0,
prevY: 0,
initialPositions: [],
});
if (bulkSelectRectPts.show) { if (bulkSelectRectPts.show) {
setBulkSelectRectPts((prev) => ({ setBulkSelectRectPts((prev) => ({
@@ -551,7 +464,7 @@ export default function Canvas() {
y2: pointer.spaces.diagram.y, y2: pointer.spaces.diagram.y,
show: false, show: false,
})); }));
if (!bulkMoved) { if (!coordinatesDidUpdate) {
collectSelectedElements(); collectSelectedElements();
} }
} }
@@ -601,13 +514,7 @@ export default function Canvas() {
const handleGripField = () => { const handleGripField = () => {
setPanning((old) => ({ ...old, isPanning: false })); setPanning((old) => ({ ...old, isPanning: false }));
setDragging({ setDragging(notDragging);
element: ObjectType.NONE,
id: null,
prevX: 0,
prevY: 0,
initialPositions: [],
});
setLinking(true); setLinking(true);
}; };

View File

@@ -26,8 +26,12 @@ export default function Note({ data, onPointerDown }) {
const { setSaveState } = useSaveState(); const { setSaveState } = useSaveState();
const { updateNote, deleteNote } = useNotes(); const { updateNote, deleteNote } = useNotes();
const { setUndoStack, setRedoStack } = useUndoRedo(); const { setUndoStack, setRedoStack } = useUndoRedo();
const { selectedElement, setSelectedElement, bulkSelectedElements } = const {
useSelect(); selectedElement,
setSelectedElement,
bulkSelectedElements,
setBulkSelectedElements,
} = useSelect();
const initialColorRef = useRef(data.color); const initialColorRef = useRef(data.color);
const handleColorPick = (color) => { const handleColorPick = (color) => {
@@ -97,6 +101,9 @@ export default function Note({ data, onPointerDown }) {
}; };
const lockUnlockNote = () => { const lockUnlockNote = () => {
setBulkSelectedElements((prev) =>
prev.filter((el) => el.id !== data.id || el.type !== ObjectType.NOTE),
);
updateNote(data.id, { locked: !data.locked }); updateNote(data.id, { locked: !data.locked });
}; };

View File

@@ -38,8 +38,12 @@ export default function Table(props) {
const { deleteTable, deleteField, updateTable } = useDiagram(); const { deleteTable, deleteField, updateTable } = useDiagram();
const { settings } = useSettings(); const { settings } = useSettings();
const { t } = useTranslation(); const { t } = useTranslation();
const { selectedElement, setSelectedElement, bulkSelectedElements } = const {
useSelect(); selectedElement,
setSelectedElement,
bulkSelectedElements,
setBulkSelectedElements,
} = useSelect();
const borderColor = useMemo( const borderColor = useMemo(
() => (settings.mode === "light" ? "border-zinc-300" : "border-zinc-600"), () => (settings.mode === "light" ? "border-zinc-300" : "border-zinc-600"),
@@ -58,8 +62,12 @@ export default function Table(props) {
); );
}, [selectedElement, tableData, bulkSelectedElements]); }, [selectedElement, tableData, bulkSelectedElements]);
const lockUnlockTable = () => const lockUnlockTable = () => {
setBulkSelectedElements((prev) =>
prev.filter((el) => el.id !== tableData.id || el.type !== ObjectType.TABLE),
);
updateTable(tableData.id, { locked: !tableData.locked }); updateTable(tableData.id, { locked: !tableData.locked });
};
const openEditor = () => { const openEditor = () => {
if (!layout.sidebar) { if (!layout.sidebar) {