feat: Integrate undo/redo functionality for aisle and line creation; enhance selection controls for better state management
This commit is contained in:
@@ -22,7 +22,7 @@ import MoveControls2D from "./moveControls2D";
|
||||
// import { upsertZoneApi } from "../../../../../services/factoryBuilder/zone/upsertZoneApi";
|
||||
|
||||
const SelectionControls2D: React.FC = () => {
|
||||
const { camera, controls, gl, scene, raycaster, pointer } = useThree();
|
||||
const { camera, controls, gl, scene, pointer } = useThree();
|
||||
const { toggleView } = useToggleView();
|
||||
const { selectedPoints, setSelectedPoints, clearSelectedPoints } = useSelectedPoints();
|
||||
const [movedObjects, setMovedObjects] = useState<THREE.Object3D[]>([]);
|
||||
@@ -38,11 +38,12 @@ const SelectionControls2D: React.FC = () => {
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { projectId } = useParams();
|
||||
const { hoveredLine, hoveredPoint } = useBuilderStore();
|
||||
const { aisleStore, wallStore, floorStore, zoneStore } = useSceneContext();
|
||||
const { aisleStore, wallStore, floorStore, zoneStore, undoRedo2DStore } = useSceneContext();
|
||||
const { push2D } = undoRedo2DStore();
|
||||
const { removePoint: removeAislePoint } = aisleStore();
|
||||
const { removePoint: removeWallPoint } = wallStore();
|
||||
const { removePoint: removeFloorPoint } = floorStore();
|
||||
const { removePoint: removeZonePoint } = zoneStore();
|
||||
const { removePoint: removeFloorPoint, getFloorsByPointId, getFloorById } = floorStore();
|
||||
const { removePoint: removeZonePoint, getZonesByPointId, getZoneById } = zoneStore();
|
||||
|
||||
const isDragging = useRef(false);
|
||||
const isLeftMouseDown = useRef(false);
|
||||
@@ -223,6 +224,12 @@ const SelectionControls2D: React.FC = () => {
|
||||
const deleteSelection = () => {
|
||||
if (selectedPoints.length > 0 && duplicatedObjects.length === 0) {
|
||||
|
||||
const deletedPoints: UndoRedo2DDataTypeSchema[] = [];
|
||||
const updatedPoints: UndoRedo2DDataTypeSchema[] = [];
|
||||
|
||||
const processedFloors: UndoRedo2DDataTypeSchema[] = [];
|
||||
const processedZones: UndoRedo2DDataTypeSchema[] = [];
|
||||
|
||||
selectedPoints.forEach((selectedPoint) => {
|
||||
if (selectedPoint.userData.pointUuid) {
|
||||
const point: Point = selectedPoint.userData as Point;
|
||||
@@ -249,6 +256,14 @@ const SelectionControls2D: React.FC = () => {
|
||||
socket.emit('v1:model-aisle:delete', data);
|
||||
}
|
||||
});
|
||||
|
||||
const removedAislesData = removedAisles.map((aisle) => ({
|
||||
type: "Aisle" as const,
|
||||
lineData: aisle,
|
||||
timeStamp: new Date().toISOString(),
|
||||
}));
|
||||
|
||||
deletedPoints.push(...removedAislesData);
|
||||
}
|
||||
}
|
||||
if (point.pointType === 'Wall') {
|
||||
@@ -274,9 +289,18 @@ const SelectionControls2D: React.FC = () => {
|
||||
socket.emit('v1:model-Wall:delete', data);
|
||||
}
|
||||
});
|
||||
|
||||
const removedWallsData = removedWalls.map((wall) => ({
|
||||
type: "Wall" as const,
|
||||
lineData: wall,
|
||||
timeStamp: new Date().toISOString(),
|
||||
}));
|
||||
|
||||
deletedPoints.push(...removedWallsData);
|
||||
}
|
||||
}
|
||||
if (point.pointType === 'Floor') {
|
||||
const Floors = getFloorsByPointId(point.pointUuid);
|
||||
const { removedFloors, updatedFloors } = removeFloorPoint(point.pointUuid);
|
||||
if (removedFloors.length > 0) {
|
||||
removedFloors.forEach(floor => {
|
||||
@@ -299,6 +323,14 @@ const SelectionControls2D: React.FC = () => {
|
||||
socket.emit('v1:model-Floor:delete', data);
|
||||
}
|
||||
});
|
||||
|
||||
const removedFloorsData = removedFloors.map((floor) => ({
|
||||
type: "Floor" as const,
|
||||
lineData: floor,
|
||||
timeStamp: new Date().toISOString(),
|
||||
}));
|
||||
|
||||
processedFloors.push(...removedFloorsData);
|
||||
}
|
||||
if (updatedFloors.length > 0) {
|
||||
updatedFloors.forEach(floor => {
|
||||
@@ -321,9 +353,19 @@ const SelectionControls2D: React.FC = () => {
|
||||
socket.emit('v1:model-Floor:add', data);
|
||||
}
|
||||
});
|
||||
|
||||
const updatedFloorsData = updatedFloors.map((floor) => ({
|
||||
type: "Floor" as const,
|
||||
lineData: Floors.find(f => f.floorUuid === floor.floorUuid) || floor,
|
||||
newData: floor,
|
||||
timeStamp: new Date().toISOString(),
|
||||
}));
|
||||
|
||||
processedFloors.push(...updatedFloorsData);
|
||||
}
|
||||
}
|
||||
if (point.pointType === 'Zone') {
|
||||
const Zones = getZonesByPointId(point.pointUuid);
|
||||
const { removedZones, updatedZones } = removeZonePoint(point.pointUuid);
|
||||
if (removedZones.length > 0) {
|
||||
removedZones.forEach(zone => {
|
||||
@@ -346,6 +388,14 @@ const SelectionControls2D: React.FC = () => {
|
||||
socket.emit('v1:zone:delete', data);
|
||||
}
|
||||
});
|
||||
|
||||
const removedZonesData = removedZones.map((zone) => ({
|
||||
type: "Zone" as const,
|
||||
lineData: zone,
|
||||
timeStamp: new Date().toISOString(),
|
||||
}));
|
||||
|
||||
processedZones.push(...removedZonesData);
|
||||
}
|
||||
if (updatedZones.length > 0) {
|
||||
updatedZones.forEach(zone => {
|
||||
@@ -368,11 +418,129 @@ const SelectionControls2D: React.FC = () => {
|
||||
socket.emit('v1:zone:add', data);
|
||||
}
|
||||
});
|
||||
|
||||
const updatedZonesData = updatedZones.map((zone) => ({
|
||||
type: "Zone" as const,
|
||||
lineData: Zones.find(z => z.zoneUuid === zone.zoneUuid) || zone,
|
||||
newData: zone,
|
||||
timeStamp: new Date().toISOString(),
|
||||
}));
|
||||
|
||||
processedZones.push(...updatedZonesData);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
if (processedFloors.length > 0) {
|
||||
const floorMap = new Map<string, UndoRedo2DDataTypeSchema[]>();
|
||||
|
||||
for (const floor of processedFloors) {
|
||||
if (floor.type !== 'Floor' || !floor.lineData.floorUuid) return;
|
||||
const uuid = floor.lineData.floorUuid;
|
||||
if (!floorMap.has(uuid)) {
|
||||
floorMap.set(uuid, []);
|
||||
}
|
||||
floorMap.get(uuid)!.push(floor);
|
||||
}
|
||||
|
||||
floorMap.forEach((actions, uuid) => {
|
||||
const hasDelete = actions.some(action => !('newData' in action));
|
||||
const hasUpdate = actions.some(action => 'newData' in action);
|
||||
|
||||
if (hasDelete) {
|
||||
deletedPoints.push({
|
||||
type: 'Floor',
|
||||
lineData: actions[0].lineData as Floor,
|
||||
timeStamp: new Date().toISOString()
|
||||
});
|
||||
} else if (!hasDelete && hasUpdate) {
|
||||
const floorData = getFloorById(uuid);
|
||||
if (floorData) {
|
||||
updatedPoints.push({
|
||||
type: 'Floor',
|
||||
lineData: actions[0].lineData as Floor,
|
||||
newData: floorData as Floor,
|
||||
timeStamp: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (processedZones.length > 0) {
|
||||
const zoneMap = new Map<string, UndoRedo2DDataTypeSchema[]>();
|
||||
|
||||
for (const zone of processedZones) {
|
||||
if (zone.type !== 'Zone' || !zone.lineData.zoneUuid) return;
|
||||
const uuid = zone.lineData.zoneUuid;
|
||||
if (!zoneMap.has(uuid)) {
|
||||
zoneMap.set(uuid, []);
|
||||
}
|
||||
zoneMap.get(uuid)!.push(zone);
|
||||
}
|
||||
|
||||
zoneMap.forEach((actions, uuid) => {
|
||||
const hasDelete = actions.some(action => !('newData' in action));
|
||||
const hasUpdate = actions.some(action => 'newData' in action);
|
||||
|
||||
if (hasDelete) {
|
||||
deletedPoints.push({
|
||||
type: 'Zone',
|
||||
lineData: actions[0].lineData as Zone,
|
||||
timeStamp: new Date().toISOString()
|
||||
});
|
||||
} else if (!hasDelete && hasUpdate) {
|
||||
const zoneData = getZoneById(uuid);
|
||||
if (zoneData) {
|
||||
updatedPoints.push({
|
||||
type: 'Zone',
|
||||
lineData: actions[0].lineData as Zone,
|
||||
newData: zoneData as Zone,
|
||||
timeStamp: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (deletedPoints.length > 0 && updatedPoints.length > 0) {
|
||||
push2D({
|
||||
type: 'Draw',
|
||||
actions: [
|
||||
{
|
||||
actionType: 'Lines-Delete',
|
||||
points: deletedPoints
|
||||
},
|
||||
{
|
||||
actionType: 'Lines-Update',
|
||||
points: updatedPoints
|
||||
}
|
||||
]
|
||||
});
|
||||
} else if (deletedPoints.length > 0 && updatedPoints.length === 0) {
|
||||
push2D({
|
||||
type: 'Draw',
|
||||
actions: [
|
||||
{
|
||||
actionType: 'Lines-Delete',
|
||||
points: deletedPoints
|
||||
}
|
||||
]
|
||||
});
|
||||
} else if (updatedPoints.length > 0 && deletedPoints.length === 0) {
|
||||
push2D({
|
||||
type: 'Draw',
|
||||
actions: [
|
||||
{
|
||||
actionType: 'Lines-Update',
|
||||
points: updatedPoints
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
echo.success("Selected points removed!");
|
||||
clearSelection();
|
||||
@@ -380,6 +548,7 @@ const SelectionControls2D: React.FC = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
<MoveControls2D movedObjects={movedObjects} setMovedObjects={setMovedObjects} pastedObjects={pastedObjects} setpastedObjects={setpastedObjects} duplicatedObjects={duplicatedObjects} setDuplicatedObjects={setDuplicatedObjects} rotatedObjects={rotatedObjects} setRotatedObjects={setRotatedObjects} />
|
||||
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user