Merge remote-tracking branch 'origin/main-dev' into main-demo
This commit is contained in:
@@ -14,6 +14,7 @@ import TransformControl from "./transformControls/transformControls";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { getUserData } from "../../../functions/getUserData";
|
||||
import SelectionControls2D from "./selectionControls/selection2D/selectionControls2D";
|
||||
import UndoRedo2DControls from "./undoRedoControls/undoRedo2D/undoRedo2DControls";
|
||||
|
||||
export default function Controls() {
|
||||
const controlsRef = useRef<CameraControls>(null);
|
||||
@@ -142,6 +143,8 @@ export default function Controls() {
|
||||
|
||||
<SelectionControls2D />
|
||||
|
||||
<UndoRedo2DControls />
|
||||
|
||||
<TransformControl />
|
||||
|
||||
</>
|
||||
|
||||
@@ -36,11 +36,12 @@ function MoveControls2D({
|
||||
const { projectId } = useParams();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { aisleStore, wallStore, floorStore, zoneStore } = useSceneContext();
|
||||
const { setPosition: setAislePosition, getAislesByPointId } = aisleStore();
|
||||
const { setPosition: setWallPosition, getWallsByPointId } = wallStore();
|
||||
const { setPosition: setFloorPosition, getFloorsByPointId } = floorStore();
|
||||
const { setPosition: setZonePosition, getZonesByPointId } = zoneStore();
|
||||
const { aisleStore, wallStore, floorStore, zoneStore, undoRedo2DStore } = useSceneContext();
|
||||
const { push2D } = undoRedo2DStore();
|
||||
const { setPosition: setAislePosition, getAislesByPointId, getAisleById } = aisleStore();
|
||||
const { setPosition: setWallPosition, getWallsByPointId, getWallById } = wallStore();
|
||||
const { setPosition: setFloorPosition, getFloorsByPointId, getFloorById } = floorStore();
|
||||
const { setPosition: setZonePosition, getZonesByPointId, getZoneById } = zoneStore();
|
||||
const [dragOffset, setDragOffset] = useState<THREE.Vector3 | null>(null);
|
||||
const [initialPositions, setInitialPositions] = useState<Record<string, THREE.Vector3>>({});
|
||||
const [initialStates, setInitialStates] = useState<Record<string, { position: THREE.Vector3; rotation?: THREE.Euler; }>>({});
|
||||
@@ -223,6 +224,12 @@ function MoveControls2D({
|
||||
const placeMovedAssets = () => {
|
||||
if (movedObjects.length === 0) return;
|
||||
|
||||
const undoPoints: UndoRedo2DDataTypeSchema[] = [];
|
||||
const processedAisles: UndoRedo2DDataTypeSchema[] = [];
|
||||
const processedWalls: UndoRedo2DDataTypeSchema[] = [];
|
||||
const processedFloors: UndoRedo2DDataTypeSchema[] = [];
|
||||
const processedZones: UndoRedo2DDataTypeSchema[] = [];
|
||||
|
||||
movedObjects.forEach((movedObject: THREE.Object3D) => {
|
||||
if (movedObject.userData.pointUuid) {
|
||||
const point: Point = movedObject.userData as Point;
|
||||
@@ -236,45 +243,84 @@ function MoveControls2D({
|
||||
|
||||
// upsertAisleApi(updatedAisle.aisleUuid, updatedAisle.points, updatedAisle.type, projectId, selectedVersion?.versionId || '');
|
||||
|
||||
// SOCKET
|
||||
// SOCKET
|
||||
|
||||
socket.emit('v1:model-aisle:add', {
|
||||
projectId: projectId,
|
||||
projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization,
|
||||
userId,
|
||||
organization,
|
||||
aisleUuid: updatedAisle.aisleUuid,
|
||||
points: updatedAisle.points,
|
||||
type: updatedAisle.type
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
const old = initialStates[movedObject.uuid];
|
||||
if (old) {
|
||||
processedAisles.push({
|
||||
type: 'Aisle',
|
||||
lineData: {
|
||||
...updatedAisle,
|
||||
points: [
|
||||
updatedAisle.points[0].pointUuid === point.pointUuid
|
||||
? { ...updatedAisle.points[0], position: [old.position.x, old.position.y, old.position.z] }
|
||||
: updatedAisle.points[0],
|
||||
updatedAisle.points[1].pointUuid === point.pointUuid
|
||||
? { ...updatedAisle.points[1], position: [old.position.x, old.position.y, old.position.z] }
|
||||
: updatedAisle.points[1]
|
||||
] as [Point, Point],
|
||||
},
|
||||
newData: updatedAisle,
|
||||
timeStamp: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (point.pointType === 'Wall') {
|
||||
const updatedWalls = getWallsByPointId(point.pointUuid);
|
||||
if (updatedWalls && updatedWalls.length > 0 && projectId) {
|
||||
updatedWalls.forEach((updatedWall) => {
|
||||
if (updatedWalls?.length && projectId) {
|
||||
updatedWalls.forEach(updatedWall => {
|
||||
|
||||
// API
|
||||
|
||||
// upsertWallApi(projectId, selectedVersion?.versionId || '', updatedWall);
|
||||
|
||||
// SOCKET
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
socket.emit('v1:model-Wall:add', {
|
||||
wallData: updatedWall,
|
||||
projectId: projectId,
|
||||
projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
userId,
|
||||
organization
|
||||
});
|
||||
|
||||
socket.emit('v1:model-Wall:add', data);
|
||||
const old = initialStates[movedObject.uuid];
|
||||
if (old) {
|
||||
processedWalls.push({
|
||||
type: 'Wall',
|
||||
lineData: {
|
||||
...updatedWall,
|
||||
points: [
|
||||
updatedWall.points[0].pointUuid === point.pointUuid
|
||||
? { ...updatedWall.points[0], position: [old.position.x, old.position.y, old.position.z] }
|
||||
: updatedWall.points[0],
|
||||
updatedWall.points[1].pointUuid === point.pointUuid
|
||||
? { ...updatedWall.points[1], position: [old.position.x, old.position.y, old.position.z] }
|
||||
: updatedWall.points[1]
|
||||
] as [Point, Point],
|
||||
},
|
||||
newData: updatedWall,
|
||||
timeStamp: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (point.pointType === 'Floor') {
|
||||
const Floors = getFloorsByPointId(point.pointUuid);
|
||||
const updatedFloors = getFloorsByPointId(point.pointUuid);
|
||||
if (updatedFloors && updatedFloors.length > 0 && projectId) {
|
||||
updatedFloors.forEach((updatedFloor) => {
|
||||
if (updatedFloors?.length && projectId) {
|
||||
updatedFloors.forEach(updatedFloor => {
|
||||
|
||||
// API
|
||||
|
||||
@@ -282,21 +328,38 @@ function MoveControls2D({
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
socket.emit('v1:model-Floor:add', {
|
||||
floorData: updatedFloor,
|
||||
projectId: projectId,
|
||||
projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
userId,
|
||||
organization
|
||||
});
|
||||
|
||||
socket.emit('v1:model-Floor:add', data);
|
||||
const updatedFloorsData = updatedFloors.map((floor) => {
|
||||
const originalFloor = Floors.find(f => f.floorUuid === floor.floorUuid) || floor;
|
||||
|
||||
const updatedPoints = originalFloor.points.map((pt: Point) => {
|
||||
const init = initialStates[pt.pointUuid];
|
||||
return init ? { ...pt, position: [init.position.x, init.position.y, init.position.z] } : pt;
|
||||
}) as [Point, Point];
|
||||
|
||||
return {
|
||||
type: "Floor" as const,
|
||||
lineData: { ...originalFloor, points: updatedPoints },
|
||||
newData: floor,
|
||||
timeStamp: new Date().toISOString(),
|
||||
};
|
||||
});
|
||||
|
||||
processedFloors.push(...updatedFloorsData);
|
||||
});
|
||||
}
|
||||
} else if (point.pointType === 'Zone') {
|
||||
const Zones = getZonesByPointId(point.pointUuid);
|
||||
const updatedZones = getZonesByPointId(point.pointUuid);
|
||||
if (updatedZones && updatedZones.length > 0 && projectId) {
|
||||
updatedZones.forEach((updatedZone) => {
|
||||
if (updatedZones?.length && projectId) {
|
||||
updatedZones.forEach(updatedZone => {
|
||||
|
||||
// API
|
||||
|
||||
@@ -304,23 +367,160 @@ function MoveControls2D({
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
socket.emit('v1:zone:add', {
|
||||
zoneData: updatedZone,
|
||||
projectId: projectId,
|
||||
projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
userId,
|
||||
organization
|
||||
});
|
||||
|
||||
socket.emit('v1:zone:add', data);
|
||||
const updatedZonesData = updatedZones.map((zone) => {
|
||||
const originalZone = Zones.find(z => z.zoneUuid === zone.zoneUuid) || zone;
|
||||
|
||||
const updatedPoints = originalZone.points.map((pt: Point) => {
|
||||
const init = initialStates[pt.pointUuid];
|
||||
return init ? { ...pt, position: [init.position.x, init.position.y, init.position.z] } : pt;
|
||||
}) as [Point, Point];
|
||||
|
||||
return {
|
||||
type: "Zone" as const,
|
||||
lineData: { ...originalZone, points: updatedPoints },
|
||||
newData: zone,
|
||||
timeStamp: new Date().toISOString(),
|
||||
};
|
||||
});
|
||||
|
||||
processedZones.push(...updatedZonesData);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
if (processedWalls.length > 0) {
|
||||
const wallMap = new Map<string, UndoRedo2DDataTypeSchema[]>();
|
||||
|
||||
for (const wall of processedWalls) {
|
||||
if (wall.type !== 'Wall' || !wall.lineData.wallUuid) continue;
|
||||
const uuid = wall.lineData.wallUuid;
|
||||
if (!wallMap.has(uuid)) wallMap.set(uuid, []);
|
||||
wallMap.get(uuid)!.push(wall);
|
||||
}
|
||||
|
||||
wallMap.forEach((actions, uuid) => {
|
||||
const hasUpdate = actions.some(action => 'newData' in action);
|
||||
if (hasUpdate) {
|
||||
const wallData = getWallById(uuid);
|
||||
if (wallData) {
|
||||
undoPoints.push({
|
||||
type: 'Wall',
|
||||
lineData: actions[0].lineData as Wall,
|
||||
newData: wallData as Wall,
|
||||
timeStamp: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (processedAisles.length > 0) {
|
||||
const aisleMap = new Map<string, UndoRedo2DDataTypeSchema[]>();
|
||||
|
||||
for (const aisle of processedAisles) {
|
||||
if (aisle.type !== 'Aisle' || !aisle.lineData.aisleUuid) continue;
|
||||
const uuid = aisle.lineData.aisleUuid;
|
||||
if (!aisleMap.has(uuid)) aisleMap.set(uuid, []);
|
||||
aisleMap.get(uuid)!.push(aisle);
|
||||
}
|
||||
|
||||
aisleMap.forEach((actions, uuid) => {
|
||||
const hasUpdate = actions.some(action => 'newData' in action);
|
||||
if (hasUpdate) {
|
||||
const aisleData = getAisleById(uuid);
|
||||
if (aisleData) {
|
||||
undoPoints.push({
|
||||
type: 'Aisle',
|
||||
lineData: actions[0].lineData as Aisle,
|
||||
newData: aisleData as Aisle,
|
||||
timeStamp: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (processedFloors.length > 0) {
|
||||
const floorMap = new Map<string, UndoRedo2DDataTypeSchema[]>();
|
||||
|
||||
for (const floor of processedFloors) {
|
||||
if (floor.type !== 'Floor' || !floor.lineData.floorUuid) continue;
|
||||
const uuid = floor.lineData.floorUuid;
|
||||
if (!floorMap.has(uuid)) {
|
||||
floorMap.set(uuid, []);
|
||||
}
|
||||
floorMap.get(uuid)!.push(floor);
|
||||
}
|
||||
|
||||
floorMap.forEach((actions, uuid) => {
|
||||
const hasUpdate = actions.some(action => 'newData' in action);
|
||||
if (hasUpdate) {
|
||||
const floorData = getFloorById(uuid);
|
||||
if (floorData) {
|
||||
undoPoints.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) continue;
|
||||
const uuid = zone.lineData.zoneUuid;
|
||||
if (!zoneMap.has(uuid)) {
|
||||
zoneMap.set(uuid, []);
|
||||
}
|
||||
zoneMap.get(uuid)!.push(zone);
|
||||
}
|
||||
|
||||
zoneMap.forEach((actions, uuid) => {
|
||||
const hasUpdate = actions.some(action => 'newData' in action);
|
||||
if (hasUpdate) {
|
||||
const zoneData = getZoneById(uuid);
|
||||
if (zoneData) {
|
||||
undoPoints.push({
|
||||
type: 'Zone',
|
||||
lineData: actions[0].lineData as Zone,
|
||||
newData: zoneData as Zone,
|
||||
timeStamp: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (undoPoints.length > 0) {
|
||||
push2D({
|
||||
type: 'Draw',
|
||||
actions: [
|
||||
{
|
||||
actionType: 'Lines-Update',
|
||||
points: undoPoints
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
}, 0);
|
||||
|
||||
echo.success("Object moved!");
|
||||
|
||||
clearSelection();
|
||||
};
|
||||
|
||||
|
||||
@@ -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,13 @@ const SelectionControls2D: React.FC = () => {
|
||||
const deleteSelection = () => {
|
||||
if (selectedPoints.length > 0 && duplicatedObjects.length === 0) {
|
||||
|
||||
const deletedPoints: UndoRedo2DDataTypeSchema[] = [];
|
||||
const updatedPoints: UndoRedo2DDataTypeSchema[] = [];
|
||||
const processedAisles: UndoRedo2DDataTypeSchema[] = [];
|
||||
const processedWalls: UndoRedo2DDataTypeSchema[] = [];
|
||||
const processedFloors: UndoRedo2DDataTypeSchema[] = [];
|
||||
const processedZones: UndoRedo2DDataTypeSchema[] = [];
|
||||
|
||||
selectedPoints.forEach((selectedPoint) => {
|
||||
if (selectedPoint.userData.pointUuid) {
|
||||
const point: Point = selectedPoint.userData as Point;
|
||||
@@ -249,6 +257,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(),
|
||||
}));
|
||||
|
||||
processedAisles.push(...removedAislesData);
|
||||
}
|
||||
}
|
||||
if (point.pointType === 'Wall') {
|
||||
@@ -274,9 +290,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(),
|
||||
}));
|
||||
|
||||
processedWalls.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 +324,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 +354,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 +389,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 +419,173 @@ 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 (processedWalls.length > 0) {
|
||||
const wallMap = new Map<string, UndoRedo2DDataTypeSchema[]>();
|
||||
|
||||
for (const wall of processedWalls) {
|
||||
if (wall.type !== 'Wall' || !wall.lineData.wallUuid) continue;
|
||||
const uuid = wall.lineData.wallUuid;
|
||||
if (!wallMap.has(uuid)) wallMap.set(uuid, []);
|
||||
wallMap.get(uuid)!.push(wall);
|
||||
}
|
||||
|
||||
wallMap.forEach((actions) => {
|
||||
const hasDelete = actions.some(action => !('newData' in action));
|
||||
if (hasDelete) {
|
||||
deletedPoints.push({
|
||||
type: 'Wall',
|
||||
lineData: actions[0].lineData as Wall,
|
||||
timeStamp: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (processedAisles.length > 0) {
|
||||
const aisleMap = new Map<string, UndoRedo2DDataTypeSchema[]>();
|
||||
|
||||
for (const aisle of processedAisles) {
|
||||
if (aisle.type !== 'Aisle' || !aisle.lineData.aisleUuid) continue;
|
||||
const uuid = aisle.lineData.aisleUuid;
|
||||
if (!aisleMap.has(uuid)) aisleMap.set(uuid, []);
|
||||
aisleMap.get(uuid)!.push(aisle);
|
||||
}
|
||||
|
||||
aisleMap.forEach((actions) => {
|
||||
const hasDelete = actions.some(action => !('newData' in action));
|
||||
if (hasDelete) {
|
||||
deletedPoints.push({
|
||||
type: 'Aisle',
|
||||
lineData: actions[0].lineData as Aisle,
|
||||
timeStamp: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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 +593,7 @@ const SelectionControls2D: React.FC = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
<MoveControls2D movedObjects={movedObjects} setMovedObjects={setMovedObjects} pastedObjects={pastedObjects} setpastedObjects={setpastedObjects} duplicatedObjects={duplicatedObjects} setDuplicatedObjects={setDuplicatedObjects} rotatedObjects={rotatedObjects} setRotatedObjects={setRotatedObjects} />
|
||||
|
||||
</>
|
||||
|
||||
@@ -213,7 +213,7 @@ const CopyPasteControls3D = ({
|
||||
modelUuid: pastedAsset.userData.modelUuid,
|
||||
modelName: pastedAsset.userData.modelName,
|
||||
assetId: pastedAsset.userData.assetId,
|
||||
position: asset.position,
|
||||
position: [position.x, position.y, position.z],
|
||||
rotation: { x: asset.rotation[0], y: asset.rotation[1], z: asset.rotation[2] },
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
|
||||
@@ -214,7 +214,7 @@ const DuplicationControls3D = ({
|
||||
modelUuid: duplicatedAsset.userData.modelUuid,
|
||||
modelName: duplicatedAsset.userData.modelName,
|
||||
assetId: duplicatedAsset.userData.assetId,
|
||||
position: asset.position,
|
||||
position: [position.x, position.y, position.z],
|
||||
rotation: { x: asset.rotation[0], y: asset.rotation[1], z: asset.rotation[2] },
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
|
||||
@@ -0,0 +1,355 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import { getUserData } from "../../../../../functions/getUserData";
|
||||
import { useVersionContext } from "../../../../builder/version/versionContext";
|
||||
import { useSceneContext } from "../../../sceneContext";
|
||||
import { useSocketStore } from "../../../../../store/builder/store";
|
||||
|
||||
// import { upsertWallApi } from "../../../../../services/factoryBuilder/wall/upsertWallApi";
|
||||
// import { deleteWallApi } from "../../../../../services/factoryBuilder/wall/deleteWallApi";
|
||||
|
||||
// import { upsertZoneApi } from "../../../../../services/factoryBuilder/zone/upsertZoneApi";
|
||||
// import { deleteZoneApi } from "../../../../../services/factoryBuilder/zone/deleteZoneApi";
|
||||
|
||||
// import { upsertFloorApi } from "../../../../../services/factoryBuilder/floor/upsertFloorApi";
|
||||
// import { deleteFloorApi } from "../../../../../services/factoryBuilder/floor/deleteFloorApi";
|
||||
|
||||
// import { upsertAisleApi } from "../../../../../services/factoryBuilder/aisle/upsertAisleApi";
|
||||
// import { deleteAisleApi } from "../../../../../services/factoryBuilder/aisle/deleteAisleApi";
|
||||
|
||||
function useRedoHandler() {
|
||||
const { undoRedo2DStore, wallStore, floorStore, zoneStore, aisleStore } = useSceneContext();
|
||||
const { redo2D, peekRedo2D } = undoRedo2DStore();
|
||||
const { addWall, removeWall, updateWall } = wallStore();
|
||||
const { addFloor, removeFloor, updateFloor } = floorStore();
|
||||
const { addZone, removeZone, updateZone } = zoneStore();
|
||||
const { addAisle, removeAisle, updateAisle } = aisleStore();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { userId, organization } = getUserData();
|
||||
const { projectId } = useParams();
|
||||
const { socket } = useSocketStore();
|
||||
|
||||
const handleRedo = () => {
|
||||
const redoData = peekRedo2D();
|
||||
if (!redoData) return;
|
||||
|
||||
if (redoData.type === 'Draw') {
|
||||
const { actions } = redoData;
|
||||
|
||||
actions.forEach(action => {
|
||||
const { actionType } = action;
|
||||
|
||||
if ('point' in action) {
|
||||
const point = action.point;
|
||||
|
||||
if (actionType === 'Line-Create') {
|
||||
handleCreate(point);
|
||||
} else if (actionType === 'Line-Update') {
|
||||
handleUpdate(point);
|
||||
} else if (actionType === 'Line-Delete') {
|
||||
handleRemove(point);
|
||||
}
|
||||
|
||||
} else if ('points' in action) {
|
||||
const points = action.points;
|
||||
|
||||
if (actionType === 'Lines-Create') {
|
||||
points.forEach(handleCreate);
|
||||
} else if (actionType === 'Lines-Update') {
|
||||
points.forEach(handleUpdate);
|
||||
} else if (actionType === 'Lines-Delete') {
|
||||
points.forEach(handleRemove);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (redoData.type === 'UI') {
|
||||
// Handle UI actions if needed
|
||||
}
|
||||
|
||||
redo2D();
|
||||
};
|
||||
|
||||
const handleCreate = (point: UndoRedo2DDataTypeSchema) => {
|
||||
switch (point.type) {
|
||||
case 'Wall': createWallFromBackend(point.lineData); break;
|
||||
case 'Floor': createFloorFromBackend(point.lineData); break;
|
||||
case 'Zone': createZoneFromBackend(point.lineData); break;
|
||||
case 'Aisle': createAisleFromBackend(point.lineData); break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemove = (point: UndoRedo2DDataTypeSchema) => {
|
||||
switch (point.type) {
|
||||
case 'Wall': removeWallFromBackend(point.lineData.wallUuid); break;
|
||||
case 'Floor': removeFloorFromBackend(point.lineData.floorUuid); break;
|
||||
case 'Zone': removeZoneFromBackend(point.lineData.zoneUuid); break;
|
||||
case 'Aisle': removeAisleFromBackend(point.lineData.aisleUuid); break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdate = (point: UndoRedo2DDataTypeSchema) => {
|
||||
if (!point.newData) return;
|
||||
switch (point.type) {
|
||||
case 'Wall': updateWallFromBackend(point.newData.wallUuid, point.newData); break;
|
||||
case 'Floor': updateFloorFromBackend(point.newData.floorUuid, point.newData); break;
|
||||
case 'Zone': updateZoneFromBackend(point.newData.zoneUuid, point.newData); break;
|
||||
case 'Aisle': updateAisleFromBackend(point.newData.aisleUuid, point.newData); break;
|
||||
}
|
||||
};
|
||||
|
||||
const createWallFromBackend = (wallData: Wall) => {
|
||||
addWall(wallData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertWallApi(projectId, selectedVersion?.versionId || '', wallData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
wallData: wallData,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Wall:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
const removeWallFromBackend = (wallUuid: string) => {
|
||||
removeWall(wallUuid);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// deleteWallApi(projectId, selectedVersion?.versionId || '', wallUuid);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
wallUuid: wallUuid,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Wall:delete', data);
|
||||
}
|
||||
};
|
||||
|
||||
const updateWallFromBackend = (wallUuid: string, updatedData: Wall) => {
|
||||
updateWall(wallUuid, updatedData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertWallApi(projectId, selectedVersion?.versionId || '', updatedData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
wallData: updatedData,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Wall:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
const createFloorFromBackend = (floorData: Floor) => {
|
||||
addFloor(floorData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertFloorApi(projectId, selectedVersion?.versionId || '', floorData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
floorData: floorData,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Floor:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
const removeFloorFromBackend = (floorUuid: string) => {
|
||||
removeFloor(floorUuid);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// deleteFloorApi(projectId, selectedVersion?.versionId || '', floorUuid);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
floorUuid: floorUuid,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Floor:delete', data);
|
||||
}
|
||||
};
|
||||
|
||||
const updateFloorFromBackend = (floorUuid: string, updatedData: Floor) => {
|
||||
updateFloor(floorUuid, updatedData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertFloorApi(projectId, selectedVersion?.versionId || '', updatedData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
floorData: updatedData,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Floor:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
const createZoneFromBackend = (zoneData: Zone) => {
|
||||
addZone(zoneData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertZoneApi(projectId, selectedVersion?.versionId || '', zoneData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
zoneData: zoneData,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:zone:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
const removeZoneFromBackend = (zoneUuid: string) => {
|
||||
removeZone(zoneUuid);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// deleteZoneApi(projectId, selectedVersion?.versionId || '', zoneUuid);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
zoneUuid,
|
||||
projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId,
|
||||
organization
|
||||
};
|
||||
|
||||
socket.emit('v1:zone:delete', data);
|
||||
}
|
||||
};
|
||||
|
||||
const updateZoneFromBackend = (zoneUuid: string, updatedData: Zone) => {
|
||||
updateZone(zoneUuid, updatedData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertZoneApi(projectId, selectedVersion?.versionId || '', updatedData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
zoneData: updatedData,
|
||||
projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId,
|
||||
organization
|
||||
};
|
||||
|
||||
socket.emit('v1:zone:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
const createAisleFromBackend = (aisleData: Aisle) => {
|
||||
addAisle(aisleData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertAisleApi(projectId, selectedVersion?.versionId || '', aisleData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
...aisleData,
|
||||
projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId,
|
||||
organization
|
||||
};
|
||||
|
||||
socket.emit('v1:model-aisle:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
const removeAisleFromBackend = (aisleUuid: string) => {
|
||||
removeAisle(aisleUuid);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// deleteAisleApi(projectId, selectedVersion?.versionId || '', aisleUuid);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
aisleUuid,
|
||||
projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId,
|
||||
organization
|
||||
};
|
||||
|
||||
socket.emit('v1:model-aisle:delete', data);
|
||||
}
|
||||
};
|
||||
|
||||
const updateAisleFromBackend = (aisleUuid: string, updatedData: Aisle) => {
|
||||
updateAisle(aisleUuid, updatedData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertAisleApi(projectId, selectedVersion?.versionId || '', updatedData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
aisleData: updatedData,
|
||||
projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId,
|
||||
organization
|
||||
};
|
||||
|
||||
socket.emit('v1:model-aisle:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
return { handleRedo };
|
||||
}
|
||||
|
||||
export default useRedoHandler;
|
||||
@@ -0,0 +1,356 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import { getUserData } from "../../../../../functions/getUserData";
|
||||
import { useVersionContext } from "../../../../builder/version/versionContext";
|
||||
import { useSceneContext } from "../../../sceneContext";
|
||||
import { useSocketStore } from "../../../../../store/builder/store";
|
||||
|
||||
// import { upsertWallApi } from "../../../../../services/factoryBuilder/wall/upsertWallApi";
|
||||
// import { deleteWallApi } from "../../../../../services/factoryBuilder/wall/deleteWallApi";
|
||||
|
||||
// import { upsertZoneApi } from "../../../../../services/factoryBuilder/zone/upsertZoneApi";
|
||||
// import { deleteWallApi } from "../../../../../services/factoryBuilder/wall/deleteWallApi";
|
||||
|
||||
// import { upsertFloorApi } from "../../../../../services/factoryBuilder/floor/upsertFloorApi";
|
||||
// import { deleteFloorApi } from "../../../../../services/factoryBuilder/floor/deleteFloorApi";
|
||||
|
||||
// import { upsertAisleApi } from "../../../../../services/factoryBuilder/aisle/upsertAisleApi";
|
||||
// import { deleteAisleApi } from "../../../../../services/factoryBuilder/aisle/deleteAisleApi";
|
||||
|
||||
function useUndoHandler() {
|
||||
const { undoRedo2DStore, wallStore, floorStore, zoneStore, aisleStore } = useSceneContext();
|
||||
const { undo2D, peekUndo2D } = undoRedo2DStore();
|
||||
const { addWall, removeWall, updateWall } = wallStore();
|
||||
const { addFloor, removeFloor, updateFloor } = floorStore();
|
||||
const { addZone, removeZone, updateZone } = zoneStore();
|
||||
const { addAisle, removeAisle, updateAisle } = aisleStore();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { userId, organization } = getUserData();
|
||||
const { projectId } = useParams();
|
||||
const { socket } = useSocketStore();
|
||||
|
||||
const handleUndo = () => {
|
||||
const unDoData = peekUndo2D();
|
||||
if (!unDoData) return;
|
||||
|
||||
if (unDoData.type === 'Draw') {
|
||||
const { actions } = unDoData;
|
||||
|
||||
actions.forEach(action => {
|
||||
const { actionType } = action;
|
||||
|
||||
if ('point' in action) {
|
||||
const point = action.point;
|
||||
|
||||
if (actionType === 'Line-Create') {
|
||||
handleRemove(point);
|
||||
} else if (actionType === 'Line-Update') {
|
||||
handleUpdate(point);
|
||||
} else if (actionType === 'Line-Delete') {
|
||||
handleCreate(point);
|
||||
}
|
||||
|
||||
} else if ('points' in action) {
|
||||
const points = action.points;
|
||||
|
||||
if (actionType === 'Lines-Create') {
|
||||
points.forEach(handleRemove);
|
||||
} else if (actionType === 'Lines-Update') {
|
||||
points.forEach(handleUpdate);
|
||||
} else if (actionType === 'Lines-Delete') {
|
||||
points.forEach(handleCreate);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (unDoData.type === 'UI') {
|
||||
// Handle UI actions if needed
|
||||
}
|
||||
|
||||
undo2D();
|
||||
|
||||
};
|
||||
|
||||
const handleCreate = (point: UndoRedo2DDataTypeSchema) => {
|
||||
switch (point.type) {
|
||||
case 'Wall': createWallFromBackend(point.lineData); break;
|
||||
case 'Floor': createFloorFromBackend(point.lineData); break;
|
||||
case 'Zone': createZoneFromBackend(point.lineData); break;
|
||||
case 'Aisle': createAisleFromBackend(point.lineData); break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemove = (point: UndoRedo2DDataTypeSchema) => {
|
||||
switch (point.type) {
|
||||
case 'Wall': removeWallFromBackend(point.lineData.wallUuid); break;
|
||||
case 'Floor': removeFloorFromBackend(point.lineData.floorUuid); break;
|
||||
case 'Zone': removeZoneFromBackend(point.lineData.zoneUuid); break;
|
||||
case 'Aisle': removeAisleFromBackend(point.lineData.aisleUuid); break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdate = (point: UndoRedo2DDataTypeSchema) => {
|
||||
switch (point.type) {
|
||||
case 'Wall': updateWallFromBackend(point.lineData.wallUuid, point.lineData); break;
|
||||
case 'Floor': updateFloorFromBackend(point.lineData.floorUuid, point.lineData); break;
|
||||
case 'Zone': updateZoneFromBackend(point.lineData.zoneUuid, point.lineData); break;
|
||||
case 'Aisle': updateAisleFromBackend(point.lineData.aisleUuid, point.lineData); break;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const createWallFromBackend = (wallData: Wall) => {
|
||||
addWall(wallData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertWallApi(projectId, selectedVersion?.versionId || '', wallData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
wallData: wallData,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Wall:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
const removeWallFromBackend = (wallUuid: string) => {
|
||||
removeWall(wallUuid);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// deleteWallApi(projectId, selectedVersion?.versionId || '', wallUuid);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
wallUuid: wallUuid,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Wall:delete', data);
|
||||
}
|
||||
};
|
||||
|
||||
const updateWallFromBackend = (wallUuid: string, updatedData: Wall) => {
|
||||
updateWall(wallUuid, updatedData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertWallApi(projectId, selectedVersion?.versionId || '', updatedData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
wallData: updatedData,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Wall:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
const createFloorFromBackend = (floorData: Floor) => {
|
||||
addFloor(floorData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertFloorApi(projectId, selectedVersion?.versionId || '', floorData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
floorData: floorData,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Floor:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
const removeFloorFromBackend = (floorUuid: string) => {
|
||||
removeFloor(floorUuid);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// deleteFloorApi(projectId, selectedVersion?.versionId || '', floorUuid);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
floorUuid: floorUuid,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Floor:delete', data);
|
||||
}
|
||||
};
|
||||
|
||||
const updateFloorFromBackend = (floorUuid: string, updatedData: Floor) => {
|
||||
updateFloor(floorUuid, updatedData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertFloorApi(projectId, selectedVersion?.versionId || '', updatedData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
floorData: updatedData,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Floor:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
const createZoneFromBackend = (zoneData: Zone) => {
|
||||
addZone(zoneData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertZoneApi(projectId, selectedVersion?.versionId || '', zoneData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
zoneData: zoneData,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:zone:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
const removeZoneFromBackend = (zoneUuid: string) => {
|
||||
removeZone(zoneUuid);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// deleteZoneApi(projectId, selectedVersion?.versionId || '', zoneUuid);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
zoneUuid,
|
||||
projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId,
|
||||
organization
|
||||
};
|
||||
|
||||
socket.emit('v1:zone:delete', data);
|
||||
}
|
||||
};
|
||||
|
||||
const updateZoneFromBackend = (zoneUuid: string, updatedData: Zone) => {
|
||||
updateZone(zoneUuid, updatedData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertZoneApi(projectId, selectedVersion?.versionId || '', updatedData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
zoneData: updatedData,
|
||||
projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId,
|
||||
organization
|
||||
};
|
||||
|
||||
socket.emit('v1:zone:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
const createAisleFromBackend = (aisleData: Aisle) => {
|
||||
addAisle(aisleData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertAisleApi(projectId, selectedVersion?.versionId || '', aisleData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
...aisleData,
|
||||
projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId,
|
||||
organization
|
||||
};
|
||||
|
||||
socket.emit('v1:model-aisle:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
const removeAisleFromBackend = (aisleUuid: string) => {
|
||||
removeAisle(aisleUuid);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// deleteAisleApi(projectId, selectedVersion?.versionId || '', aisleUuid);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
aisleUuid,
|
||||
projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId,
|
||||
organization
|
||||
};
|
||||
|
||||
socket.emit('v1:model-aisle:delete', data);
|
||||
}
|
||||
};
|
||||
|
||||
const updateAisleFromBackend = (aisleUuid: string, updatedData: Aisle) => {
|
||||
updateAisle(aisleUuid, updatedData);
|
||||
if (projectId) {
|
||||
// API
|
||||
|
||||
// upsertAisleApi(projectId, selectedVersion?.versionId || '', updatedData);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
aisleData: updatedData,
|
||||
projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId,
|
||||
organization
|
||||
};
|
||||
|
||||
socket.emit('v1:model-aisle:add', data);
|
||||
}
|
||||
};
|
||||
|
||||
return { handleUndo };
|
||||
}
|
||||
|
||||
export default useUndoHandler;
|
||||
@@ -0,0 +1,49 @@
|
||||
import { useEffect } from 'react'
|
||||
import { useSceneContext } from '../../../sceneContext'
|
||||
import { detectModifierKeys } from '../../../../../utils/shortcutkeys/detectModifierKeys';
|
||||
import { useSocketStore, useToggleView } from '../../../../../store/builder/store';
|
||||
import { useVersionContext } from '../../../../builder/version/versionContext';
|
||||
|
||||
import useUndoHandler from '../handlers/useUndoHandler';
|
||||
import useRedoHandler from '../handlers/useRedoHandler';
|
||||
|
||||
function UndoRedo2DControls() {
|
||||
const { undoRedo2DStore } = useSceneContext();
|
||||
const { undoStack, redoStack } = undoRedo2DStore();
|
||||
const { toggleView } = useToggleView();
|
||||
const { handleUndo } = useUndoHandler();
|
||||
const { handleRedo } = useRedoHandler();
|
||||
const { socket } = useSocketStore();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
|
||||
useEffect(() => {
|
||||
console.log(undoStack, redoStack);
|
||||
}, [undoStack, redoStack]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
const keyCombination = detectModifierKeys(event);
|
||||
|
||||
if (keyCombination === 'Ctrl+Z') {
|
||||
handleUndo();
|
||||
}
|
||||
|
||||
if (keyCombination === 'Ctrl+Y') {
|
||||
handleRedo();
|
||||
}
|
||||
};
|
||||
|
||||
if (toggleView) {
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
}
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('keydown', handleKeyDown);
|
||||
};
|
||||
}, [toggleView, undoStack, redoStack, socket, selectedVersion]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export default UndoRedo2DControls;
|
||||
@@ -7,6 +7,8 @@ import { createAisleStore, AisleStoreType } from '../../store/builder/useAisleSt
|
||||
import { createZoneStore, ZoneStoreType } from '../../store/builder/useZoneStore';
|
||||
import { createFloorStore, FloorStoreType } from '../../store/builder/useFloorStore';
|
||||
|
||||
import { createUndoRedo2DStore, UndoRedo2DStoreType } from '../../store/builder/useUndoRedo2DStore';
|
||||
|
||||
import { createEventStore, EventStoreType } from '../../store/simulation/useEventsStore';
|
||||
import { createProductStore, ProductStoreType } from '../../store/simulation/useProductStore';
|
||||
|
||||
@@ -27,6 +29,8 @@ type SceneContextValue = {
|
||||
zoneStore: ZoneStoreType,
|
||||
floorStore: FloorStoreType,
|
||||
|
||||
undoRedo2DStore: UndoRedo2DStoreType,
|
||||
|
||||
eventStore: EventStoreType,
|
||||
productStore: ProductStoreType,
|
||||
|
||||
@@ -62,6 +66,8 @@ export function SceneProvider({
|
||||
const zoneStore = useMemo(() => createZoneStore(), []);
|
||||
const floorStore = useMemo(() => createFloorStore(), []);
|
||||
|
||||
const undoRedo2DStore = useMemo(() => createUndoRedo2DStore(), []);
|
||||
|
||||
const eventStore = useMemo(() => createEventStore(), []);
|
||||
const productStore = useMemo(() => createProductStore(), []);
|
||||
|
||||
@@ -82,6 +88,7 @@ export function SceneProvider({
|
||||
aisleStore.getState().clearAisles();
|
||||
zoneStore.getState().clearZones();
|
||||
floorStore.getState().clearFloors();
|
||||
undoRedo2DStore.getState().clearUndoRedo2D();
|
||||
eventStore.getState().clearEvents();
|
||||
productStore.getState().clearProducts();
|
||||
materialStore.getState().clearMaterials();
|
||||
@@ -92,7 +99,7 @@ export function SceneProvider({
|
||||
storageUnitStore.getState().clearStorageUnits();
|
||||
humanStore.getState().clearHumans();
|
||||
humanEventManagerRef.current.humanStates = [];
|
||||
}, [assetStore, wallAssetStore, wallStore, aisleStore, zoneStore, floorStore, eventStore, productStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, humanStore]);
|
||||
}, [assetStore, wallAssetStore, wallStore, aisleStore, zoneStore, undoRedo2DStore, floorStore, eventStore, productStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, humanStore]);
|
||||
|
||||
const contextValue = useMemo(() => (
|
||||
{
|
||||
@@ -102,6 +109,7 @@ export function SceneProvider({
|
||||
aisleStore,
|
||||
zoneStore,
|
||||
floorStore,
|
||||
undoRedo2DStore,
|
||||
eventStore,
|
||||
productStore,
|
||||
materialStore,
|
||||
@@ -115,7 +123,7 @@ export function SceneProvider({
|
||||
clearStores,
|
||||
layout
|
||||
}
|
||||
), [assetStore, wallAssetStore, wallStore, aisleStore, zoneStore, floorStore, eventStore, productStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, humanStore, clearStores, layout]);
|
||||
), [assetStore, wallAssetStore, wallStore, aisleStore, zoneStore, floorStore, undoRedo2DStore, eventStore, productStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, humanStore, clearStores, layout]);
|
||||
|
||||
return (
|
||||
<SceneContext.Provider value={contextValue}>
|
||||
|
||||
Reference in New Issue
Block a user