From 4c7b13190c368c7abc0a4ecedf8d8012fa8bf4c6 Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Thu, 18 Sep 2025 15:05:02 +0530 Subject: [PATCH] added wall, wall asset and decal collab response --- .../components/heatMapGenerator/heatMap.tsx | 8 - .../properties/SelectedDecalProperties.tsx | 30 ++- .../properties/SelectedWallProperties.tsx | 113 ++++---- .../components/temporary/SelectFloorPlan.tsx | 228 ++++++++--------- .../Decal/decalCreator/decalCreator.tsx | 60 +++-- .../eventHandler/useDecalEventHandlers.ts | 46 +++- app/src/modules/builder/asset/assetsGroup.tsx | 2 +- .../builder/asset/functions/addAssetModel.ts | 4 + .../eventHandlers/useModelEventHandlers.ts | 2 +- app/src/modules/builder/dfx/LoadBlueprint.tsx | 27 +- .../functions/getWallPointsFromBlueprint.ts | 4 - .../line/eventHandler/useLineEventHandler.ts | 97 ++++++- .../eventHandler/usePointEventHandler.ts | 90 ++++++- app/src/modules/builder/point/point.tsx | 2 +- .../builder/wall/wallCreator/wallCreator.tsx | 241 +++++++----------- .../eventHandler/useWallAssetEventHandler.ts | 53 +++- .../builder/wallAsset/wallAssetCreator.tsx | 34 ++- .../collaboration/camera/collabUserIcon.tsx | 7 +- .../useAssetResponseHandler.ts | 6 +- .../useWallAssetResponseHandler.ts | 47 ++++ .../responseHandler/useWallResponseHandler.ts | 47 ++++ .../collaboration/socket/builderResponses.tsx | 110 +++++++- .../selection2D/moveControls2D.tsx | 49 +++- .../selection2D/selectionControls2D.tsx | 48 +++- .../selection3D/copyPasteControls3D.tsx | 2 +- .../selection3D/duplicationControls3D.tsx | 2 +- .../selection3D/moveControls3D.tsx | 2 +- .../selection3D/rotateControls3D.tsx | 2 +- .../selection3D/selectionControls3D.tsx | 2 +- .../selection3D/transformControls3D.tsx | 2 +- .../transformControls/transformControls.tsx | 2 +- .../handlers/use2DRedoHandler.ts | 60 ++++- .../handlers/use2DUndoHandler.ts | 61 ++++- .../handlers/use3DRedoHandler.ts | 4 +- .../handlers/use3DUndoHandler.ts | 2 +- .../comparison/validateSimulationDataApi.ts | 1 + app/src/store/builder/useWallStore.ts | 212 +++++++++------ 37 files changed, 1148 insertions(+), 561 deletions(-) rename app/src/modules/{builder/asset => collaboration}/responseHandler/useAssetResponseHandler.ts (87%) create mode 100644 app/src/modules/collaboration/responseHandler/useWallAssetResponseHandler.ts create mode 100644 app/src/modules/collaboration/responseHandler/useWallResponseHandler.ts diff --git a/app/src/components/heatMapGenerator/heatMap.tsx b/app/src/components/heatMapGenerator/heatMap.tsx index bda354a..83b987a 100644 --- a/app/src/components/heatMapGenerator/heatMap.tsx +++ b/app/src/components/heatMapGenerator/heatMap.tsx @@ -1,15 +1,7 @@ import RealTimeHeatMap from "./realTime/realTimeHeatMap"; import BakedHeatMap from "./baked/bakedHeatMap"; -import { useEffect } from "react"; -import { useHeatMapStore } from "../../store/simulation/useHeatMapStore"; function HeatMap() { - const { bakedPoints, setBakedPoints } = useHeatMapStore(); - - useEffect(() => { - // console.log("bakedPoints: ", bakedPoints); - }, [bakedPoints]); - return ( <> diff --git a/app/src/components/layout/sidebarRight/properties/SelectedDecalProperties.tsx b/app/src/components/layout/sidebarRight/properties/SelectedDecalProperties.tsx index e688293..465de76 100644 --- a/app/src/components/layout/sidebarRight/properties/SelectedDecalProperties.tsx +++ b/app/src/components/layout/sidebarRight/properties/SelectedDecalProperties.tsx @@ -3,6 +3,7 @@ import { useSceneContext } from "../../../../modules/scene/sceneContext"; import { useBuilderStore } from "../../../../store/builder/useBuilderStore"; import { LayeringBottomIcon, LayeringTopIcon } from "../../../icons/ExportCommonIcons"; import { useSocketStore } from "../../../../store/socket/useSocketStore"; +import useWallResponseHandler from "../../../../modules/collaboration/responseHandler/useWallResponseHandler"; import InputRange from "../../../ui/inputs/InputRange"; import { getUserData } from "../../../../functions/getUserData"; @@ -12,8 +13,9 @@ import { upsertFloorApi } from "../../../../services/factoryBuilder/floor/upsert const SelectedDecalProperties = () => { const { selectedDecal, setSelectedDecal } = useBuilderStore(); const { wallStore, floorStore, versionStore } = useSceneContext(); - const { updateDecal: updateDecalInWall } = wallStore(); + const { peekUpdateDecal: peekDecalInWall } = wallStore(); const { updateDecal: updateDecalInFloor } = floorStore(); + const { updateWallInScene } = useWallResponseHandler(); const { userId, organization } = getUserData(); const { selectedVersion } = versionStore(); const { projectId } = useParams(); @@ -25,7 +27,23 @@ const SelectedDecalProperties = () => { if (!builderSocket?.connected) { // API - upsertWallApi(projectId, selectedVersion?.versionId || "", updatedData); + upsertWallApi(projectId, selectedVersion?.versionId || "", updatedData) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error updating decal`); + return; + } + if (data.message === "Wall Updated Successfully") { + updateWallInScene(updatedData, () => { + echo.log(`Decal Updated`); + }); + } else { + echo.error(`Error updating decal`); + } + }) + .catch(() => { + echo.error(`Error updating decal`); + }); } else { // SOCKET @@ -69,7 +87,7 @@ const SelectedDecalProperties = () => { setSelectedDecal({ ...selectedDecal, decalData: updatedDecal }); if ("wallUuid" in selectedDecal.decalData.decalType) { - const updatedWall = updateDecalInWall(updatedDecal.decalUuid, updatedDecal); + const updatedWall = peekDecalInWall(updatedDecal.decalUuid, updatedDecal); if (updatedWall) updateBackend(updatedWall); } else if ("floorUuid" in selectedDecal.decalData.decalType) { const updatedFloor = updateDecalInFloor(updatedDecal.decalUuid, updatedDecal); @@ -83,7 +101,7 @@ const SelectedDecalProperties = () => { setSelectedDecal({ ...selectedDecal, decalData: updatedDecal }); if ("wallUuid" in selectedDecal.decalData.decalType) { - const updatedWall = updateDecalInWall(updatedDecal.decalUuid, updatedDecal); + const updatedWall = peekDecalInWall(updatedDecal.decalUuid, updatedDecal); if (updatedWall) updateBackend(updatedWall); } else if ("floorUuid" in selectedDecal.decalData.decalType) { const updatedFloor = updateDecalInFloor(updatedDecal.decalUuid, updatedDecal); @@ -97,7 +115,7 @@ const SelectedDecalProperties = () => { setSelectedDecal({ ...selectedDecal, decalData: updatedDecal }); if ("wallUuid" in selectedDecal.decalData.decalType) { - const updatedWall = updateDecalInWall(updatedDecal.decalUuid, updatedDecal); + const updatedWall = peekDecalInWall(updatedDecal.decalUuid, updatedDecal); if (updatedWall) updateBackend(updatedWall); } else if ("floorUuid" in selectedDecal.decalData.decalType) { const updatedFloor = updateDecalInFloor(updatedDecal.decalUuid, updatedDecal); @@ -121,7 +139,7 @@ const SelectedDecalProperties = () => { setSelectedDecal({ ...selectedDecal, decalData: updatedDecal }); if ("wallUuid" in selectedDecal.decalData.decalType) { - const updatedWall = updateDecalInWall(updatedDecal.decalUuid, updatedDecal); + const updatedWall = peekDecalInWall(updatedDecal.decalUuid, updatedDecal); if (updatedWall) updateBackend(updatedWall); } else if ("floorUuid" in selectedDecal.decalData.decalType) { const updatedFloor = updateDecalInFloor(updatedDecal.decalUuid, updatedDecal); diff --git a/app/src/components/layout/sidebarRight/properties/SelectedWallProperties.tsx b/app/src/components/layout/sidebarRight/properties/SelectedWallProperties.tsx index e06f02f..fad93cd 100644 --- a/app/src/components/layout/sidebarRight/properties/SelectedWallProperties.tsx +++ b/app/src/components/layout/sidebarRight/properties/SelectedWallProperties.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; import InputWithDropDown from "../../../ui/inputs/InputWithDropDown"; import defaultTexture from "../../../../assets/textures/floor/wall-tex.png"; @@ -6,9 +7,9 @@ import wallTexture1 from "../../../../assets/textures/floor/factory wall texture import { useBuilderStore } from "../../../../store/builder/useBuilderStore"; import { useSceneContext } from "../../../../modules/scene/sceneContext"; -import { useParams } from "react-router-dom"; import { getUserData } from "../../../../functions/getUserData"; import { useSocketStore } from "../../../../store/socket/useSocketStore"; +import useWallResponseHandler from "../../../../modules/collaboration/responseHandler/useWallResponseHandler"; import { upsertWallApi } from "../../../../services/factoryBuilder/wall/upsertWallApi"; @@ -21,7 +22,8 @@ const SelectedWallProperties = () => { const { builderSocket } = useSocketStore(); const { userId, organization } = getUserData(); const { projectId } = useParams(); - const { getWallById, updateWall } = wallStore(); + const { getWallById, peekUpdateWall } = wallStore(); + const { updateWallInScene } = useWallResponseHandler(); const [activeSide, setActiveSide] = useState<"side1" | "side2">("side1"); @@ -39,69 +41,28 @@ const SelectedWallProperties = () => { } }, [wall, selectedWall]); - const handleHeightChange = (val: string) => { - setHeight(val); - const height = parseFloat(val); - if (!isNaN(height) && wall) { - const updatedWall = updateWall(wall.wallUuid, { wallHeight: height }); - if (updatedWall && projectId) { - if (!builderSocket?.connected) { - // API - - upsertWallApi(projectId, selectedVersion?.versionId || "", updatedWall); - } else { - // SOCKET - - const data = { - wallData: updatedWall, - projectId: projectId, - versionId: selectedVersion?.versionId || "", - userId: userId, - organization: organization, - }; - - builderSocket.emit("v1:model-Wall:add", data); - } - } - } - }; - - const handleThicknessChange = (val: string) => { - setThickness(val); - const thickness = parseFloat(val); - if (!isNaN(thickness) && wall) { - const updatedWall = updateWall(wall.wallUuid, { wallThickness: thickness }); - if (updatedWall && projectId) { - if (!builderSocket?.connected) { - // API - - upsertWallApi(projectId, selectedVersion?.versionId || "", updatedWall); - } else { - // SOCKET - - const data = { - wallData: updatedWall, - projectId: projectId, - versionId: selectedVersion?.versionId || "", - userId: userId, - organization: organization, - }; - - builderSocket.emit("v1:model-Wall:add", data); - } - } - } - }; - - const handleSelectMaterial = (material: { textureId: string; textureName: string }) => { - if (!wall) return; - - const updated = activeSide === "side1" ? { insideMaterial: material.textureId } : { outsideMaterial: material.textureId }; - const updatedWall = updateWall(wall.wallUuid, updated); - if (updatedWall && projectId) { + const updateWallToBackend = (updatedWall: Wall | undefined) => { + if (projectId && updatedWall) { if (!builderSocket?.connected) { // API - // upsertWallApi(projectId, selectedVersion?.versionId || '', updatedWall); + + upsertWallApi(projectId, selectedVersion?.versionId || "", updatedWall) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error updating wall: ${updatedWall.wallUuid}`); + return; + } + if (data.message === "Wall Updated Successfully") { + updateWallInScene(updatedWall, () => { + echo.log(`Updated wall: ${updatedWall.wallUuid}`); + }); + } else { + echo.error(`Error updating wall: ${updatedWall.wallUuid}`); + } + }) + .catch(() => { + echo.error(`Error updating wall: ${updatedWall.wallUuid}`); + }); } else { // SOCKET @@ -118,6 +79,32 @@ const SelectedWallProperties = () => { } }; + const handleHeightChange = (val: string) => { + setHeight(val); + const height = parseFloat(val); + if (!isNaN(height) && wall) { + const updatedWall = peekUpdateWall(wall.wallUuid, { wallHeight: height }); + updateWallToBackend(updatedWall); + } + }; + + const handleThicknessChange = (val: string) => { + setThickness(val); + const thickness = parseFloat(val); + if (!isNaN(thickness) && wall) { + const updatedWall = peekUpdateWall(wall.wallUuid, { wallThickness: thickness }); + updateWallToBackend(updatedWall); + } + }; + + const handleSelectMaterial = (material: { textureId: string; textureName: string }) => { + if (!wall) return; + + const updated = activeSide === "side1" ? { insideMaterial: material.textureId } : { outsideMaterial: material.textureId }; + const updatedWall = peekUpdateWall(wall.wallUuid, updated); + updateWallToBackend(updatedWall); + }; + if (!wall) return null; const selectedMaterials = { diff --git a/app/src/components/temporary/SelectFloorPlan.tsx b/app/src/components/temporary/SelectFloorPlan.tsx index 53b7eec..1a9b149 100644 --- a/app/src/components/temporary/SelectFloorPlan.tsx +++ b/app/src/components/temporary/SelectFloorPlan.tsx @@ -6,135 +6,127 @@ import { getWallPointsFromBlueprint } from "../../modules/builder/dfx/functions/ import { convertDXFToThree } from "../../modules/builder/dfx/functions/convertDxfToThree"; import { AIIcon } from "../icons/ExportCommonIcons"; import { useBuilderStore } from "../../store/builder/useBuilderStore"; -import { useSceneContext } from "../../modules/scene/sceneContext"; + type DXFData = any; const SelectFloorPlan: React.FC = () => { - // Access layout state and state setters - const { currentLayout, setLayout } = useLayoutStore(); - // Access DXF-related states and setters - const { setDfxUploaded, setDxfWallGenerate, setObjValue, objValue } = - useDfxUpload(); - const { activeLayer } = useActiveLayer(); - const { wallThickness, wallHeight, insideMaterial, outsideMaterial } = useBuilderStore(); - const { wallStore } = useSceneContext(); - const { addWall } = wallStore(); - // Local state to store the parsed DXF file - const [parsedFile, setParsedFile] = useState(undefined); - const { walls } = wallStore(); - // Flag to trigger generation after file upload - const [generate, setGenerate] = useState(false); + // Access layout state and state setters + const { currentLayout, setLayout } = useLayoutStore(); + // Access DXF-related states and setters + const { setDfxUploaded, setDxfWallGenerate, setObjValue, objValue } = useDfxUpload(); + const { activeLayer } = useActiveLayer(); + const { wallThickness, wallHeight, insideMaterial, outsideMaterial } = useBuilderStore(); + // Local state to store the parsed DXF file + const [parsedFile, setParsedFile] = useState(undefined); + // Flag to trigger generation after file upload + const [generate, setGenerate] = useState(false); - // Handles file upload and DXF parsing - const handleFileUpload = async ( - event: React.ChangeEvent - ) => { - setLayout(null); // Reset current layout - setParsedFile(undefined); // Clear any previously parsed file - const file = event.target.files?.[0]; - if (!file || !file.name.endsWith(".dxf")) { - alert("Please upload a valid .dxf file."); - return; - } + // Handles file upload and DXF parsing + const handleFileUpload = async (event: React.ChangeEvent) => { + setLayout(null); // Reset current layout + setParsedFile(undefined); // Clear any previously parsed file + const file = event.target.files?.[0]; + if (!file || !file.name.endsWith(".dxf")) { + alert("Please upload a valid .dxf file."); + return; + } - const reader = new FileReader(); - reader.onload = async (e) => { - const dxfContent = e.target?.result as string; + const reader = new FileReader(); + reader.onload = async (e) => { + const dxfContent = e.target?.result as string; - try { - const parser = new DxfParser(); - const parsedDatas = parser.parse(dxfContent) as DXFData; - const geometries = convertDXFToThree(parsedDatas); - setParsedFile(parsedDatas); - setObjValue({ x: 0, y: 0, z: 0 }); - setDfxUploaded(geometries); - } catch (error) { - console.error("Failed to import your .dxf file", error); - } finally { - // ✅ Reset input AFTER processing - event.target.value = ""; - } + try { + const parser = new DxfParser(); + const parsedDatas = parser.parse(dxfContent) as DXFData; + const geometries = convertDXFToThree(parsedDatas); + setParsedFile(parsedDatas); + setObjValue({ x: 0, y: 0, z: 0 }); + setDfxUploaded(geometries); + } catch (error) { + console.error("Failed to import your .dxf file", error); + } finally { + // ✅ Reset input AFTER processing + event.target.value = ""; + } + }; + + reader.readAsText(file); // Read the uploaded file as text }; - reader.readAsText(file); // Read the uploaded file as text - }; + // Trigger wall point generation when `generate` flag changes + useEffect(() => { + if (parsedFile !== undefined) { + getWallPointsFromBlueprint({ + parsedData: parsedFile, + setDxfWallGenerate, + objValue, + wallThickness, + wallHeight, + outsideMaterial, + insideMaterial, + activeLayer, + }); + } + }, [generate]); - // Trigger wall point generation when `generate` flag changes - useEffect(() => { - if (parsedFile !== undefined) { - getWallPointsFromBlueprint({ - parsedData: parsedFile, - setDxfWallGenerate, - objValue, - wallThickness, wallHeight, outsideMaterial, insideMaterial, activeLayer, addWall, walls - }); - } - }, [generate]); + return ( +
+ Upload Layouts +
+ - return ( -
- Upload Layouts -
- + - + {parsedFile && ( + + )} +
+ or +
+ - {parsedFile && ( - - )} -
- or -
- - - -
-
- ); + +
+
+ ); }; export default SelectFloorPlan; diff --git a/app/src/modules/builder/Decal/decalCreator/decalCreator.tsx b/app/src/modules/builder/Decal/decalCreator/decalCreator.tsx index 41c8d4d..1b1fba1 100644 --- a/app/src/modules/builder/Decal/decalCreator/decalCreator.tsx +++ b/app/src/modules/builder/Decal/decalCreator/decalCreator.tsx @@ -4,8 +4,9 @@ import { useThree } from "@react-three/fiber"; import { useParams } from "react-router-dom"; import { useSocketStore } from "../../../../store/socket/useSocketStore"; import { useBuilderStore } from "../../../../store/builder/useBuilderStore"; -import useModuleStore from "../../../../store/ui/useModuleStore"; import { useSceneContext } from "../../../scene/sceneContext"; +import useModuleStore from "../../../../store/ui/useModuleStore"; +import useWallResponseHandler from "../../../collaboration/responseHandler/useWallResponseHandler"; import { getUserData } from "../../../../functions/getUserData"; @@ -14,8 +15,9 @@ import { upsertFloorApi } from "../../../../services/factoryBuilder/floor/upsert function DecalCreator() { const { wallStore, floorStore, versionStore } = useSceneContext(); - const { addDecal: addDecalOnWall, getWallById } = wallStore(); + const { peekAddDecal: peekAddDecalOnWall, getWallById } = wallStore(); const { addDecal: addDecalOnFloor, getFloorById } = floorStore(); + const { updateWallInScene } = useWallResponseHandler(); const { droppedDecal, setDroppedDecal } = useBuilderStore(); const { activeModule } = useModuleStore(); const { userId, organization } = getUserData(); @@ -57,32 +59,44 @@ function DecalCreator() { decalScale: 0.5, }; - addDecalOnWall(wallIntersect.object.userData.wallUuid, decal); + const updatedWall = peekAddDecalOnWall(wallIntersect.object.userData.wallUuid, decal); + if (updatedWall) { + if (projectId) { + if (!builderSocket?.connected) { + // API - setTimeout(() => { - const updatedWall = getWallById(wallIntersect.object.userData.wallUuid); - if (updatedWall) { - if (projectId) { - if (!builderSocket?.connected) { - // API + upsertWallApi(projectId, selectedVersion?.versionId || "", updatedWall) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error adding decal`); + return; + } + if (data.message === "Wall Updated Successfully") { + updateWallInScene(updatedWall, () => { + echo.log(`Decal Added`); + }); + } else { + echo.error(`Error adding decal`); + } + }) + .catch(() => { + echo.error(`Error adding decal`); + }); + } else { + // SOCKET - upsertWallApi(projectId, selectedVersion?.versionId || "", updatedWall); - } else { - // SOCKET + const data = { + wallData: updatedWall, + projectId: projectId, + versionId: selectedVersion?.versionId || "", + userId: userId, + organization: organization, + }; - const data = { - wallData: updatedWall, - projectId: projectId, - versionId: selectedVersion?.versionId || "", - userId: userId, - organization: organization, - }; - - builderSocket.emit("v1:model-Wall:add", data); - } + builderSocket.emit("v1:model-Wall:add", data); } } - }, 0); + } } else if (floorIntersect) { const floor = getFloorById(floorIntersect.object.userData.floorUuid); if (!floor) return; diff --git a/app/src/modules/builder/Decal/eventHandler/useDecalEventHandlers.ts b/app/src/modules/builder/Decal/eventHandler/useDecalEventHandlers.ts index dd5e338..0af39a9 100644 --- a/app/src/modules/builder/Decal/eventHandler/useDecalEventHandlers.ts +++ b/app/src/modules/builder/Decal/eventHandler/useDecalEventHandlers.ts @@ -1,14 +1,15 @@ import * as THREE from "three"; +import { useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; import { CameraControls } from "@react-three/drei"; import { ThreeEvent, useFrame, useThree } from "@react-three/fiber"; -import { useEffect, useState } from "react"; import { useToggleView, useToolMode } from "../../../../store/builder/store"; import { useSocketStore } from "../../../../store/socket/useSocketStore"; import { useBuilderStore } from "../../../../store/builder/useBuilderStore"; -import useModuleStore from "../../../../store/ui/useModuleStore"; -import { getUserData } from "../../../../functions/getUserData"; -import { useParams } from "react-router-dom"; import { useSceneContext } from "../../../scene/sceneContext"; +import useModuleStore from "../../../../store/ui/useModuleStore"; +import useWallResponseHandler from "../../../collaboration/responseHandler/useWallResponseHandler"; +import { getUserData } from "../../../../functions/getUserData"; import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys"; import handleDecalPositionSnap from "../functions/handleDecalPositionSnap"; @@ -21,6 +22,7 @@ export function useDecalEventHandlers({ parent, decal, visible }: { parent: Wall const { removeDecal: removeDecalInWall, updateDecalPosition: updateDecalPositionInWall, getWallById, addDecal: addDecalToWall } = wallStore(); const { removeDecal: removeDecalInFloor, updateDecalPosition: updateDecalPositionInFloor, getFloorById, addDecal: addDecalToFloor } = floorStore(); const { setSelectedWall, setSelectedFloor, setSelectedDecal, setDeletableDecal, deletableDecal, selectedDecal, setDecalDragState, decalDragState } = useBuilderStore(); + const { updateWallInScene } = useWallResponseHandler(); const { toolMode } = useToolMode(); const { toggleView } = useToggleView(); const { activeModule } = useModuleStore(); @@ -142,7 +144,23 @@ export function useDecalEventHandlers({ parent, decal, visible }: { parent: Wall if (!builderSocket?.connected) { // API - upsertWallApi(projectId, selectedVersion?.versionId || "", updatedWall); + upsertWallApi(projectId, selectedVersion?.versionId || "", updatedWall) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error updating decal`); + return; + } + if (data.message === "Wall Updated Successfully") { + updateWallInScene(updatedWall, () => { + echo.log(`Decal Updated`); + }); + } else { + echo.error(`Error updating decal`); + } + }) + .catch(() => { + echo.error(`Error updating decal`); + }); } else { // SOCKET @@ -195,7 +213,23 @@ export function useDecalEventHandlers({ parent, decal, visible }: { parent: Wall if (!builderSocket?.connected) { // API - upsertWallApi(projectId, selectedVersion?.versionId || "", updatedWall); + upsertWallApi(projectId, selectedVersion?.versionId || "", updatedWall) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error removing decal`); + return; + } + if (data.message === "Wall Updated Successfully") { + updateWallInScene(updatedWall, () => { + echo.log(`Decal Removed`); + }); + } else { + echo.error(`Error removing decal`); + } + }) + .catch(() => { + echo.error(`Error removing decal`); + }); } else { // SOCKET diff --git a/app/src/modules/builder/asset/assetsGroup.tsx b/app/src/modules/builder/asset/assetsGroup.tsx index 2949d71..164eb9d 100644 --- a/app/src/modules/builder/asset/assetsGroup.tsx +++ b/app/src/modules/builder/asset/assetsGroup.tsx @@ -16,7 +16,7 @@ import { useLeftData, useTopData } from "../../../store/visualization/useZone3DW import { getUserData } from "../../../functions/getUserData"; import { useSceneContext } from "../../scene/sceneContext"; import { useBuilderStore } from "../../../store/builder/useBuilderStore"; -import useAssetResponseHandler from "./responseHandler/useAssetResponseHandler"; +import useAssetResponseHandler from "../../collaboration/responseHandler/useAssetResponseHandler"; const gltfLoaderWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js", import.meta.url)); diff --git a/app/src/modules/builder/asset/functions/addAssetModel.ts b/app/src/modules/builder/asset/functions/addAssetModel.ts index 9186f2d..e8fbe84 100644 --- a/app/src/modules/builder/asset/functions/addAssetModel.ts +++ b/app/src/modules/builder/asset/functions/addAssetModel.ts @@ -487,6 +487,8 @@ async function handleModelLoad( echo.log(`Added asset: ${model.modelName}`); }); + } else { + echo.error(`Error adding asset: ${data?.data?.modelName}`); } }) .catch(() => { @@ -591,6 +593,8 @@ async function handleModelLoad( echo.log(`Added asset: ${model.modelUuid}`); }); + } else { + echo.error(`Error adding asset: ${data?.data?.modelName}`); } }) .catch(() => { diff --git a/app/src/modules/builder/asset/models/model/eventHandlers/useModelEventHandlers.ts b/app/src/modules/builder/asset/models/model/eventHandlers/useModelEventHandlers.ts index 6331ac7..85a17b7 100644 --- a/app/src/modules/builder/asset/models/model/eventHandlers/useModelEventHandlers.ts +++ b/app/src/modules/builder/asset/models/model/eventHandlers/useModelEventHandlers.ts @@ -12,7 +12,7 @@ import { getUserData } from "../../../../../../functions/getUserData"; import { useLeftData, useTopData } from "../../../../../../store/visualization/useZone3DWidgetStore"; import { useSelectedAsset } from "../../../../../../store/simulation/useSimulationStore"; import { useBuilderStore } from "../../../../../../store/builder/useBuilderStore"; -import useAssetResponseHandler from "../../../responseHandler/useAssetResponseHandler"; +import useAssetResponseHandler from "../../../../../collaboration/responseHandler/useAssetResponseHandler"; import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi"; import { deleteFloorAssetApi } from "../../../../../../services/factoryBuilder/asset/floorAsset/deleteFloorAssetApi"; diff --git a/app/src/modules/builder/dfx/LoadBlueprint.tsx b/app/src/modules/builder/dfx/LoadBlueprint.tsx index aa76259..e0beb08 100644 --- a/app/src/modules/builder/dfx/LoadBlueprint.tsx +++ b/app/src/modules/builder/dfx/LoadBlueprint.tsx @@ -10,6 +10,7 @@ import { useSceneContext } from "../../scene/sceneContext"; import { upsertWallApi } from "../../../services/factoryBuilder/wall/upsertWallApi"; import { getUserData } from "../../../functions/getUserData"; +import useWallResponseHandler from "../../collaboration/responseHandler/useWallResponseHandler"; /** * DxfFile component handles the rendering and manipulation of DXf file data in a 3D scene. @@ -21,10 +22,9 @@ const DxfFile = () => { const { dfxuploaded, dfxWallGenerate, setObjValue, objValue, setDfxUploaded } = useDfxUpload(); const { toggleView } = useToggleView(); const { builderSocket } = useSocketStore(); - const { versionStore, wallStore } = useSceneContext(); + const { versionStore } = useSceneContext(); const { selectedVersion } = versionStore(); - const { addWall } = wallStore(); - const { walls } = wallStore(); + const { addWallToScene } = useWallResponseHandler(); const { projectId } = useParams(); const { userId, organization } = getUserData(); const { activeLayer } = useActiveLayer(); @@ -42,7 +42,23 @@ const DxfFile = () => { if (!builderSocket?.connected) { // API - upsertWallApi(projectId, selectedVersion?.versionId || "", wall); + upsertWallApi(projectId, selectedVersion?.versionId || "", wall) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error adding wall: ${wall.wallUuid}`); + return; + } + if (data.message === "Wall Created Successfully") { + addWallToScene(wall, () => { + echo.log(`Added wall: ${wall.wallUuid}`); + }); + } else { + echo.error(`Error adding wall: ${wall.wallUuid}`); + } + }) + .catch(() => { + echo.error(`Error adding wall: ${wall.wallUuid}`); + }); } else { // SOCKET @@ -53,7 +69,6 @@ const DxfFile = () => { userId: userId, organization: organization, }; - addWall(wall); builderSocket.emit("v1:model-Wall:add", data); } } @@ -85,8 +100,6 @@ const DxfFile = () => { outsideMaterial, insideMaterial, activeLayer, - addWall, - walls, }); }; useEffect(() => { diff --git a/app/src/modules/builder/dfx/functions/getWallPointsFromBlueprint.ts b/app/src/modules/builder/dfx/functions/getWallPointsFromBlueprint.ts index f655d35..55cf9a7 100644 --- a/app/src/modules/builder/dfx/functions/getWallPointsFromBlueprint.ts +++ b/app/src/modules/builder/dfx/functions/getWallPointsFromBlueprint.ts @@ -11,8 +11,6 @@ interface Props { outsideMaterial: string; insideMaterial: string; activeLayer: number; // Active layer for wall points - addWall: (wall: Wall) => void; // Function to add a wall to the scene - walls: Wall[]; // Array of walls to be processed } /** @@ -34,8 +32,6 @@ export function getWallPointsFromBlueprint({ outsideMaterial, insideMaterial, activeLayer, - addWall, - walls, }: Props) { // Early return if no data is provided if (!parsedData) return; diff --git a/app/src/modules/builder/line/eventHandler/useLineEventHandler.ts b/app/src/modules/builder/line/eventHandler/useLineEventHandler.ts index f38a16a..9728caa 100644 --- a/app/src/modules/builder/line/eventHandler/useLineEventHandler.ts +++ b/app/src/modules/builder/line/eventHandler/useLineEventHandler.ts @@ -1,15 +1,14 @@ import * as THREE from "three"; +import { useParams } from "react-router-dom"; import { ThreeEvent, useThree } from "@react-three/fiber"; import { useCallback, useEffect, useMemo, useState } from "react"; import { useToolMode } from "../../../../store/builder/store"; import { useSocketStore } from "../../../../store/socket/useSocketStore"; import { useBuilderStore } from "../../../../store/builder/useBuilderStore"; import { useSceneContext } from "../../../scene/sceneContext"; -import { useParams } from "react-router-dom"; -import { getUserData } from "../../../../functions/getUserData"; -import { handleCanvasCursors } from "../../../../utils/mouseUtils/handleCanvasCursors"; import { useSelectedPoints } from "../../../../store/simulation/useSimulationStore"; -import { calculateAssetTransformationOnWall } from "../../wallAsset/Instances/Instance/functions/calculateAssetTransformationOnWall"; +import useWallAssetResponseHandler from "../../../collaboration/responseHandler/useWallAssetResponseHandler"; +import useWallResponseHandler from "../../../collaboration/responseHandler/useWallResponseHandler"; import { upsertWallApi } from "../../../../services/factoryBuilder/wall/upsertWallApi"; import { deleteWallApi } from "../../../../services/factoryBuilder/wall/deleteWallApi"; @@ -20,6 +19,10 @@ import { upsertZoneApi } from "../../../../services/factoryBuilder/zone/upsertZo import { upsertWallAssetApi } from "../../../../services/factoryBuilder/asset/wallAsset/upsertWallAssetApi"; import { deleteWallAssetApi } from "../../../../services/factoryBuilder/asset/wallAsset/deleteWallAssetApi"; +import { handleCanvasCursors } from "../../../../utils/mouseUtils/handleCanvasCursors"; +import { getUserData } from "../../../../functions/getUserData"; +import { calculateAssetTransformationOnWall } from "../../wallAsset/Instances/Instance/functions/calculateAssetTransformationOnWall"; + interface LineProps { points: [Point, Point]; } @@ -33,10 +36,12 @@ export function useLineEventHandler({ points }: Readonly) { const { toolMode } = useToolMode(); const { wallStore, floorStore, zoneStore, undoRedo2DStore, wallAssetStore, versionStore } = useSceneContext(); const { push2D } = undoRedo2DStore(); - const { getWallAssetsByWall, updateWallAsset, removeWallAsset } = wallAssetStore(); - const { removeWallByPoints, setPosition: setWallPosition, getWallByPoints, getConnectedWallsByWallId } = wallStore(); + const { getWallAssetsByWall } = wallAssetStore(); + const { peekRemoveWallByPoints, setPosition: setWallPosition, getWallByPoints, getConnectedWallsByWallId } = wallStore(); const { removeFloorByPoints, setPosition: setFloorPosition, getFloorsByPointId, getFloorsByPoints } = floorStore(); const { removeZoneByPoints, setPosition: setZonePosition, getZonesByPointId, getZonesByPoints } = zoneStore(); + const { updateWallAssetInScene, removeWallAssetFromScene } = useWallAssetResponseHandler(); + const { updateWallInScene, removeWallFromScene } = useWallResponseHandler(); const { selectedVersion } = versionStore(); const { hoveredLine, setHoveredLine, hoveredPoint } = useBuilderStore(); const [dragOffset, setDragOffset] = useState(null); @@ -135,16 +140,33 @@ export function useLineEventHandler({ points }: Readonly) { assetsOnWall.forEach((asset) => { const { position, rotation } = calculateAssetTransformationOnWall(asset, initialWall, updatedWall); - const updatedWallAsset = updateWallAsset(asset.modelUuid, { + const updatedWallAsset: WallAsset = { + ...asset, position: [position[0], asset.position[1], position[2]], rotation: rotation, - }); + }; if (projectId && updatedWallAsset) { if (!builderSocket?.connected) { // API - upsertWallAssetApi(projectId, selectedVersion?.versionId || "", updatedWallAsset); + upsertWallAssetApi(projectId, selectedVersion?.versionId || "", updatedWallAsset) + .then((data) => { + if (!data.message) { + echo.error(`Error updating wallAsset ${updatedWallAsset.modelName} on the wall`); + return; + } + if (data.message === "WallAsset Updated Successfully" && data.data) { + updateWallAssetInScene(updatedWallAsset, () => { + echo.log(`Updated wallAsset: ${updatedWallAsset.modelUuid} on the wall`); + }); + } else { + echo.error(`Error updating wallAsset ${updatedWallAsset.modelName} on the wall`); + } + }) + .catch(() => { + echo.error(`Error updating wallAsset ${updatedWallAsset.modelName} on the wall`); + }); } else { // SOCKET @@ -165,7 +187,23 @@ export function useLineEventHandler({ points }: Readonly) { if (!builderSocket?.connected) { // API - upsertWallApi(projectId, selectedVersion?.versionId || "", updatedWall); + upsertWallApi(projectId, selectedVersion?.versionId || "", updatedWall) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error updating wall`); + return; + } + if (data.message === "Wall Updated Successfully") { + updateWallInScene(updatedWall, () => { + echo.log(`Updated wall: ${updatedWall.wallUuid}`); + }); + } else { + echo.error(`Error updating wall: ${updatedWall.wallUuid}`); + } + }) + .catch(() => { + echo.error(`Error updating wall: ${updatedWall.wallUuid}`); + }); } else { // SOCKET @@ -296,17 +334,32 @@ export function useLineEventHandler({ points }: Readonly) { const handleLineClick = useCallback(() => { if (toolMode === "2D-Delete") { if (points[0].pointType === "Wall" && points[1].pointType === "Wall") { - const removedWall = removeWallByPoints(points); + const removedWall = peekRemoveWallByPoints(points); if (removedWall && projectId) { const assetsOnWall = getWallAssetsByWall(removedWall.wallUuid); assetsOnWall.forEach((asset) => { if (projectId && asset) { - removeWallAsset(asset.modelUuid); if (!builderSocket?.connected) { // API - deleteWallAssetApi(projectId, selectedVersion?.versionId || "", asset.modelUuid, asset.wallUuid); + deleteWallAssetApi(projectId, selectedVersion?.versionId || "", asset.modelUuid, asset.wallUuid) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error removing wallAsset from wall`); + return; + } + if (data.message === "WallAsset Deleted Successfully") { + removeWallAssetFromScene(asset.modelUuid, () => { + echo.log(`Removed wallAsset: ${asset.modelName} along with wall`); + }); + } else { + echo.error(`Error removing wallAsset: ${asset.modelName} from wall`); + } + }) + .catch(() => { + echo.error(`Error removing wallAsset: ${asset.modelName}`); + }); } else { // SOCKET @@ -326,7 +379,23 @@ export function useLineEventHandler({ points }: Readonly) { if (!builderSocket?.connected) { // API - deleteWallApi(projectId, selectedVersion?.versionId || "", removedWall.wallUuid); + deleteWallApi(projectId, selectedVersion?.versionId || "", removedWall.wallUuid) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error removing wall`); + return; + } + if (data.message === "Wall Deleted Successfully") { + removeWallFromScene(removedWall.wallUuid, () => { + echo.log(`Removed wall: ${removedWall.wallUuid}`); + }); + } else { + echo.error(`Error removing wall: ${removedWall.wallUuid}`); + } + }) + .catch(() => { + echo.error(`Error removing wall: ${removedWall.wallUuid}`); + }); } else { // SOCKET diff --git a/app/src/modules/builder/point/eventHandler/usePointEventHandler.ts b/app/src/modules/builder/point/eventHandler/usePointEventHandler.ts index 50bf175..013621d 100644 --- a/app/src/modules/builder/point/eventHandler/usePointEventHandler.ts +++ b/app/src/modules/builder/point/eventHandler/usePointEventHandler.ts @@ -1,13 +1,15 @@ import * as THREE from "three"; +import { useParams } from "react-router-dom"; +import { ThreeEvent, useThree } from "@react-three/fiber"; import { useState, useEffect, useMemo, useCallback } from "react"; import { useToolMode } from "../../../../store/builder/store"; import { useSocketStore } from "../../../../store/socket/useSocketStore"; -import { ThreeEvent, useThree } from "@react-three/fiber"; import { useBuilderStore } from "../../../../store/builder/useBuilderStore"; +import { useSceneContext } from "../../../scene/sceneContext"; import { useSelectedPoints } from "../../../../store/simulation/useSimulationStore"; import { usePointSnapping } from "../helpers/usePointSnapping"; -import { useParams } from "react-router-dom"; -import { useSceneContext } from "../../../scene/sceneContext"; +import useWallAssetResponseHandler from "../../../collaboration/responseHandler/useWallAssetResponseHandler"; +import useWallResponseHandler from "../../../collaboration/responseHandler/useWallResponseHandler"; import { upsertAisleApi } from "../../../../services/factoryBuilder/aisle/upsertAisleApi"; import { deleteAisleApi } from "../../../../services/factoryBuilder/aisle/deleteAisleApi"; @@ -35,11 +37,13 @@ export function usePointEventHandler({ point }: { point: Point }) { const { toolMode } = useToolMode(); const { aisleStore, wallStore, floorStore, zoneStore, undoRedo2DStore, wallAssetStore, versionStore } = useSceneContext(); const { push2D } = undoRedo2DStore(); + const { getWallAssetsByWall } = wallAssetStore(); + const { updateWallAssetInScene, removeWallAssetFromScene } = useWallAssetResponseHandler(); + const { updateWallInScene, removeWallFromScene } = useWallResponseHandler(); const { setPosition: setAislePosition, removePoint: removeAislePoint, getAislesByPointId } = aisleStore(); const { setPosition: setWallPosition, removePoint: removeWallPoint, getWallsByPointId } = wallStore(); const { setPosition: setFloorPosition, removePoint: removeFloorPoint, getFloorsByPointId } = floorStore(); const { setPosition: setZonePosition, removePoint: removeZonePoint, getZonesByPointId } = zoneStore(); - const { getWallAssetsByWall, updateWallAsset, removeWallAsset } = wallAssetStore(); const { selectedVersion } = versionStore(); const { snapAislePoint, snapAisleAngle, snapWallPoint, snapWallAngle, snapFloorPoint, snapFloorAngle, snapZonePoint, snapZoneAngle } = usePointSnapping({ uuid: point.pointUuid, @@ -175,16 +179,33 @@ export function usePointEventHandler({ point }: { point: Point }) { assetsOnWall.forEach((asset) => { const { position, rotation } = calculateAssetTransformationOnWall(asset, initialWall, updatedWall); - const updatedWallAsset = updateWallAsset(asset.modelUuid, { + const updatedWallAsset: WallAsset = { + ...asset, position: [position[0], asset.position[1], position[2]], rotation: rotation, - }); + }; if (projectId && updatedWallAsset) { if (!builderSocket?.connected) { // API - upsertWallAssetApi(projectId, selectedVersion?.versionId || "", updatedWallAsset); + upsertWallAssetApi(projectId, selectedVersion?.versionId || "", updatedWallAsset) + .then((data) => { + if (!data.message) { + echo.error(`Error updating wallAsset ${updatedWallAsset.modelName} on the wall`); + return; + } + if (data.message === "WallAsset Updated Successfully" && data.data) { + updateWallAssetInScene(updatedWallAsset, () => { + echo.log(`Updated wallAsset: ${updatedWallAsset.modelUuid} on the wall`); + }); + } else { + echo.error(`Error updating wallAsset ${updatedWallAsset.modelName} on the wall`); + } + }) + .catch(() => { + echo.error(`Error updating wallAsset ${updatedWallAsset.modelName} on the wall`); + }); } else { // SOCKET @@ -205,7 +226,23 @@ export function usePointEventHandler({ point }: { point: Point }) { if (!builderSocket?.connected) { // API - upsertWallApi(projectId, selectedVersion?.versionId || "", updatedWall); + upsertWallApi(projectId, selectedVersion?.versionId || "", updatedWall) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error updating wall`); + return; + } + if (data.message === "Wall Updated Successfully") { + updateWallInScene(updatedWall, () => { + echo.log(`Updated wall: ${updatedWall.wallUuid}`); + }); + } else { + echo.error(`Error updating wall: ${updatedWall.wallUuid}`); + } + }) + .catch(() => { + echo.error(`Error updating wall: ${updatedWall.wallUuid}`); + }); } else { // SOCKET @@ -385,11 +422,26 @@ export function usePointEventHandler({ point }: { point: Point }) { assetsOnWall.forEach((asset) => { if (projectId && asset) { - removeWallAsset(asset.modelUuid); if (!builderSocket?.connected) { // API - deleteWallAssetApi(projectId, selectedVersion?.versionId || "", asset.modelUuid, asset.wallUuid); + deleteWallAssetApi(projectId, selectedVersion?.versionId || "", asset.modelUuid, asset.wallUuid) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error removing wallAsset from wall`); + return; + } + if (data.message === "WallAsset Deleted Successfully") { + removeWallAssetFromScene(asset.modelUuid, () => { + echo.log(`Removed wallAsset: ${asset.modelName} along with wall`); + }); + } else { + echo.error(`Error removing wallAsset: ${asset.modelName} from wall`); + } + }) + .catch(() => { + echo.error(`Error removing wallAsset: ${asset.modelName}`); + }); } else { // SOCKET @@ -411,7 +463,23 @@ export function usePointEventHandler({ point }: { point: Point }) { if (!builderSocket?.connected) { // API - deleteWallApi(projectId, selectedVersion?.versionId || "", wall.wallUuid); + deleteWallApi(projectId, selectedVersion?.versionId || "", wall.wallUuid) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error removing wall`); + return; + } + if (data.message === "Wall Deleted Successfully") { + removeWallFromScene(wall.wallUuid, () => { + echo.log(`Removed wall: ${wall.wallUuid}`); + }); + } else { + echo.error(`Error removing wall: ${wall.wallUuid}`); + } + }) + .catch(() => { + echo.error(`Error removing wall: ${wall.wallUuid}`); + }); } else { // SOCKET diff --git a/app/src/modules/builder/point/point.tsx b/app/src/modules/builder/point/point.tsx index 1070305..aebd678 100644 --- a/app/src/modules/builder/point/point.tsx +++ b/app/src/modules/builder/point/point.tsx @@ -60,7 +60,7 @@ function Point({ point }: { readonly point: Point }) { onPointerOut={handlePointerOut} userData={point} > - + { + if (projectId) { + if (!builderSocket?.connected) { + // API + + upsertWallApi(projectId, selectedVersion?.versionId || "", wall) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error adding or updating wall`); + return; + } + if (data.message === "Wall Created Successfully") { + addWallToScene(wall, () => { + echo.log(`Added wall: ${wall.wallUuid}`); + }); + } else if (data.message === "Wall Updated Successfully") { + updateWallInScene(wall, () => { + echo.log(`Updated wall: ${wall.wallUuid}`); + }); + } else { + removeWallFromScene(wall.wallUuid, () => { + echo.error(`Error adding or updating wall: ${wall.wallUuid}`); + }); + } + }) + .catch(() => { + echo.error(`Error adding or updating wall: ${wall.wallUuid}`); + }); + } else { + // SOCKET + + const data = { + wallData: wall, + projectId: projectId, + versionId: selectedVersion?.versionId || "", + userId: userId, + organization: organization, + }; + + builderSocket.emit("v1:model-Wall:add", data); + } + } + }; + + const removeWallFromBackend = (wallUuid: string) => { + if (projectId) { + if (!builderSocket?.connected) { + // API + + deleteWallApi(projectId, selectedVersion?.versionId || "", wallUuid) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error removing wall`); + return; + } + if (data.message === "Wall Deleted Successfully") { + removeWallFromScene(wallUuid, () => { + echo.log(`Removed wall: ${wallUuid}`); + }); + } else { + echo.error(`Error removing wall: ${wallUuid}`); + } + }) + .catch(() => { + echo.error(`Error removing wall: ${wallUuid}`); + }); + } else { + // SOCKET + + const data = { + wallUuid: wallUuid, + projectId: projectId, + versionId: selectedVersion?.versionId || "", + userId: userId, + organization: organization, + }; + + builderSocket.emit("v1:model-Wall:delete", data); + } + } + }; + const onMouseClick = () => { if (drag.current || !toggleView) return; @@ -90,27 +174,7 @@ function WallCreator() { const closestPoint = new THREE.Vector3().lerpVectors(point1Vec, point2Vec, t); - removeWall(wall.wallUuid); - - if (projectId) { - if (!builderSocket?.connected) { - // API - - deleteWallApi(projectId, selectedVersion?.versionId || "", wall.wallUuid); - } else { - // SOCKET - - const data = { - wallUuid: wall.wallUuid, - projectId: projectId, - versionId: selectedVersion?.versionId || "", - userId: userId, - organization: organization, - }; - - builderSocket.emit("v1:model-Wall:delete", data); - } - } + removeWallFromBackend(wall.wallUuid); const point1: Point = { pointUuid: wall.points[0].pointUuid, @@ -144,27 +208,7 @@ function WallCreator() { decals: [], }; - addWall(wall2); - - if (projectId) { - if (!builderSocket?.connected) { - // API - - upsertWallApi(projectId, selectedVersion?.versionId || "", wall2); - } else { - // SOCKET - - const data = { - wallData: wall2, - projectId: projectId, - versionId: selectedVersion?.versionId || "", - userId: userId, - organization: organization, - }; - - builderSocket.emit("v1:model-Wall:add", data); - } - } + addWallToBackend(wall2); const wall3: Wall = { wallUuid: THREE.MathUtils.generateUUID(), @@ -176,7 +220,7 @@ function WallCreator() { decals: [], }; - addWall(wall3); + addWallToBackend(wall3); push2D({ type: "Draw", @@ -207,26 +251,6 @@ function WallCreator() { ], }); - if (projectId) { - if (!builderSocket?.connected) { - // API - - upsertWallApi(projectId, selectedVersion?.versionId || "", wall3); - } else { - // SOCKET - - const data2 = { - wallData: wall3, - projectId: projectId, - versionId: selectedVersion?.versionId || "", - userId: userId, - organization: organization, - }; - - builderSocket.emit("v1:model-Wall:add", data2); - } - } - setTempPoints([newPoint]); setIsCreating(true); } else { @@ -240,27 +264,7 @@ function WallCreator() { decals: [], }; - addWall(wall1); - - if (projectId) { - if (!builderSocket?.connected) { - // API - - upsertWallApi(projectId, selectedVersion?.versionId || "", wall1); - } else { - // SOCKET - - const data = { - wallData: wall1, - projectId: projectId, - versionId: selectedVersion?.versionId || "", - userId: userId, - organization: organization, - }; - - builderSocket.emit("v1:model-Wall:add", data); - } - } + addWallToBackend(wall1); const wall2: Wall = { wallUuid: THREE.MathUtils.generateUUID(), @@ -272,27 +276,7 @@ function WallCreator() { decals: [], }; - addWall(wall2); - - if (projectId) { - if (!builderSocket?.connected) { - // API - - upsertWallApi(projectId, selectedVersion?.versionId || "", wall2); - } else { - // SOCKET - - const data1 = { - wallData: wall2, - projectId: projectId, - versionId: selectedVersion?.versionId || "", - userId: userId, - organization: organization, - }; - - builderSocket.emit("v1:model-Wall:add", data1); - } - } + addWallToBackend(wall2); const wall3: Wall = { wallUuid: THREE.MathUtils.generateUUID(), @@ -304,7 +288,7 @@ function WallCreator() { decals: [], }; - addWall(wall3); + addWallToBackend(wall3); push2D({ type: "Draw", @@ -340,26 +324,6 @@ function WallCreator() { ], }); - if (projectId) { - if (!builderSocket?.connected) { - // API - - upsertWallApi(projectId, selectedVersion?.versionId || "", wall3); - } else { - // SOCKET - - const data3 = { - wallData: wall3, - projectId: projectId, - versionId: selectedVersion?.versionId || "", - userId: userId, - organization: organization, - }; - - builderSocket.emit("v1:model-Wall:add", data3); - } - } - setTempPoints([newPoint]); } @@ -413,7 +377,7 @@ function WallCreator() { decals: [], }; - addWall(wall); + addWallToBackend(wall); push2D({ type: "Draw", @@ -429,26 +393,6 @@ function WallCreator() { ], }); - if (projectId) { - if (!builderSocket?.connected) { - // API - - upsertWallApi(projectId, selectedVersion?.versionId || "", wall); - } else { - // SOCKET - - const data = { - wallData: wall, - projectId: projectId, - versionId: selectedVersion?.versionId || "", - userId: userId, - organization: organization, - }; - - builderSocket.emit("v1:model-Wall:add", data); - } - } - setTempPoints([newPoint]); } }; @@ -501,7 +445,6 @@ function WallCreator() { builderSocket, tempPoints, isCreating, - addWall, getWallPointById, wallThickness, wallHeight, diff --git a/app/src/modules/builder/wallAsset/Instances/Instance/eventHandler/useWallAssetEventHandler.ts b/app/src/modules/builder/wallAsset/Instances/Instance/eventHandler/useWallAssetEventHandler.ts index 2247895..4583a2b 100644 --- a/app/src/modules/builder/wallAsset/Instances/Instance/eventHandler/useWallAssetEventHandler.ts +++ b/app/src/modules/builder/wallAsset/Instances/Instance/eventHandler/useWallAssetEventHandler.ts @@ -7,8 +7,11 @@ import { useActiveTool, useToggleView } from "../../../../../../store/builder/st import { useSocketStore } from "../../../../../../store/socket/useSocketStore"; import { useSceneContext } from "../../../../../scene/sceneContext"; import { useBuilderStore } from "../../../../../../store/builder/useBuilderStore"; -import { getUserData } from "../../../../../../functions/getUserData"; +import useWallAssetResponseHandler from "../../../../../collaboration/responseHandler/useWallAssetResponseHandler"; + import closestPointOnLineSegment from "../../../../line/helpers/getClosestPointOnLineSegment"; +import { getUserData } from "../../../../../../functions/getUserData"; + import { upsertWallAssetApi } from "../../../../../../services/factoryBuilder/asset/wallAsset/upsertWallAssetApi"; import { deleteWallAssetApi } from "../../../../../../services/factoryBuilder/asset/wallAsset/deleteWallAssetApi"; @@ -16,11 +19,12 @@ export function useWallAssetEventHandler({ wallAsset, groupRef, wall }: { wallAs const { builderSocket } = useSocketStore(); const { raycaster, pointer, camera, scene, controls, gl } = useThree(); const { wallAssetStore, versionStore } = useSceneContext(); - const { updateWallAsset, removeWallAsset, getWallAssetById } = wallAssetStore(); + const { updateWallAsset, getWallAssetById } = wallAssetStore(); const { toggleView } = useToggleView(); const { activeTool } = useActiveTool(); const { activeModule } = useModuleStore(); const { selectedWallAsset, setSelectedWallAsset, setDeletableWallAsset, deletableWallAsset } = useBuilderStore(); + const { updateWallAssetInScene, removeWallAssetFromScene } = useWallAssetResponseHandler(); const { selectedVersion } = versionStore(); const { userId, organization } = getUserData(); const { projectId } = useParams(); @@ -44,7 +48,23 @@ export function useWallAssetEventHandler({ wallAsset, groupRef, wall }: { wallAs if (!builderSocket?.connected) { // API - upsertWallAssetApi(projectId, selectedVersion?.versionId || "", updatedWallAsset); + upsertWallAssetApi(projectId, selectedVersion?.versionId || "", updatedWallAsset) + .then((data) => { + if (!data.message) { + echo.error(`Error updating wallAsset ${updatedWallAsset.modelName} on the wall`); + return; + } + if (data.message === "WallAsset Updated Successfully" && data.data) { + updateWallAssetInScene(updatedWallAsset, () => { + echo.log(`Updated wallAsset: ${updatedWallAsset.modelUuid} on the wall`); + }); + } else { + echo.error(`Error updating wallAsset ${updatedWallAsset.modelName} on the wall`); + } + }) + .catch(() => { + echo.error(`Error updating wallAsset ${updatedWallAsset.modelName} on the wall`); + }); } else { // SOCKET @@ -55,6 +75,7 @@ export function useWallAssetEventHandler({ wallAsset, groupRef, wall }: { wallAs userId: userId, organization: organization, }; + builderSocket.emit("v1:wall-asset:add", data); } } @@ -168,13 +189,27 @@ export function useWallAssetEventHandler({ wallAsset, groupRef, wall }: { wallAs } } else if (!toggleView && activeModule === "builder" && activeTool === "delete") { if (activeTool === "delete" && deletableWallAsset && deletableWallAsset.userData.modelUuid === wallAsset.modelUuid) { - const removedWallAsset = removeWallAsset(wallAsset.modelUuid); - - if (projectId && removedWallAsset) { + if (projectId) { if (!builderSocket?.connected) { // API - deleteWallAssetApi(projectId, selectedVersion?.versionId || "", removedWallAsset.modelUuid, removedWallAsset.wallUuid); + deleteWallAssetApi(projectId, selectedVersion?.versionId || "", wallAsset.modelUuid, wallAsset.wallUuid) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error removing wallAsset from wall`); + return; + } + if (data.message === "WallAsset Deleted Successfully") { + removeWallAssetFromScene(wallAsset.modelUuid, () => { + echo.log(`Removed wallAsset: ${wallAsset.modelName} along with wall`); + }); + } else { + echo.error(`Error removing wallAsset: ${wallAsset.modelName} from wall`); + } + }) + .catch(() => { + echo.error(`Error removing wallAsset: ${wallAsset.modelName}`); + }); } else { // SOCKET @@ -183,8 +218,8 @@ export function useWallAssetEventHandler({ wallAsset, groupRef, wall }: { wallAs versionId: selectedVersion?.versionId || "", userId: userId, organization: organization, - modelUuid: removedWallAsset.modelUuid, - wallUuid: removedWallAsset.wallUuid, + modelUuid: wallAsset.modelUuid, + wallUuid: wallAsset.wallUuid, }; builderSocket.emit("v1:wall-asset:delete", data); } diff --git a/app/src/modules/builder/wallAsset/wallAssetCreator.tsx b/app/src/modules/builder/wallAsset/wallAssetCreator.tsx index 24c32b5..50fb6f7 100644 --- a/app/src/modules/builder/wallAsset/wallAssetCreator.tsx +++ b/app/src/modules/builder/wallAsset/wallAssetCreator.tsx @@ -1,11 +1,12 @@ -import { useThree } from "@react-three/fiber"; import { useEffect } from "react"; -import useModuleStore from "../../../store/ui/useModuleStore"; +import { useParams } from "react-router-dom"; +import { MathUtils, Vector3 } from "three"; +import { useThree } from "@react-three/fiber"; +import { useSceneContext } from "../../scene/sceneContext"; import { useSocketStore } from "../../../store/socket/useSocketStore"; import { useSelectedItem, useToggleView } from "../../../store/builder/store"; -import { MathUtils, Vector3 } from "three"; -import { useSceneContext } from "../../scene/sceneContext"; -import { useParams } from "react-router-dom"; +import useModuleStore from "../../../store/ui/useModuleStore"; +import useWallAssetResponseHandler from "../../collaboration/responseHandler/useWallAssetResponseHandler"; import { getUserData } from "../../../functions/getUserData"; import closestPointOnLineSegment from "../line/helpers/getClosestPointOnLineSegment"; @@ -16,8 +17,8 @@ function WallAssetCreator() { const { pointer, camera, raycaster, scene, gl } = useThree(); const { toggleView } = useToggleView(); const { activeModule } = useModuleStore(); - const { wallAssetStore, versionStore } = useSceneContext(); - const { addWallAsset } = wallAssetStore(); + const { versionStore } = useSceneContext(); + const { addWallAssetToScene } = useWallAssetResponseHandler(); const { selectedItem, setSelectedItem } = useSelectedItem(); const { selectedVersion } = versionStore(); const { userId, organization } = getUserData(); @@ -59,12 +60,27 @@ function WallAssetCreator() { opacity: 1, }; - addWallAsset(newWallAsset); if (projectId) { if (!builderSocket?.connected) { // API - upsertWallAssetApi(projectId, selectedVersion?.versionId || "", newWallAsset); + upsertWallAssetApi(projectId, selectedVersion?.versionId || "", newWallAsset) + .then((data) => { + if (!data.message) { + echo.error(`Error adding wallAsset: ${newWallAsset.modelName}`); + return; + } + if (data.message === "WallAsset Created Successfully" && data.data) { + addWallAssetToScene(newWallAsset, () => { + echo.log(`Added wallAsset: ${newWallAsset.modelName}`); + }); + } else { + echo.error(`Error adding wallAsset: ${newWallAsset.modelName}`); + } + }) + .catch(() => { + echo.error(`Error adding wallAsset: ${newWallAsset.modelName}`); + }); } else { // SOCKET diff --git a/app/src/modules/collaboration/camera/collabUserIcon.tsx b/app/src/modules/collaboration/camera/collabUserIcon.tsx index d6f91ce..bfed4bf 100644 --- a/app/src/modules/collaboration/camera/collabUserIcon.tsx +++ b/app/src/modules/collaboration/camera/collabUserIcon.tsx @@ -1,7 +1,8 @@ import React from "react"; import CustomAvatar from "../users/Avatar"; import { useSelectedUserStore } from "../../../store/collaboration/useCollabStore"; -import { useCamMode } from "../../../store/builder/store"; +import { useCamMode, useToggleView } from "../../../store/builder/store"; +import useModuleStore from "../../../store/ui/useModuleStore"; interface CollabUserIconProps { userName: string; @@ -28,6 +29,8 @@ interface CollabUserIconProps { const CollabUserIcon: React.FC = ({ userImage, userName, id, color, position, rotation, target }) => { const { setSelectedUser } = useSelectedUserStore(); const { setCamMode } = useCamMode(); + const { activeModule } = useModuleStore(); + const { toggleView } = useToggleView(); return (
@@ -35,7 +38,7 @@ const CollabUserIcon: React.FC = ({ userImage, userName, id id="live-user-button" className="user-image-container" onClick={() => { - if (!position || !rotation || !target) return; + if (!position || !rotation || !target || toggleView || (activeModule !== "builder" && activeModule !== "simulation")) return; // Set the selected user in the store setSelectedUser({ id: id, diff --git a/app/src/modules/builder/asset/responseHandler/useAssetResponseHandler.ts b/app/src/modules/collaboration/responseHandler/useAssetResponseHandler.ts similarity index 87% rename from app/src/modules/builder/asset/responseHandler/useAssetResponseHandler.ts rename to app/src/modules/collaboration/responseHandler/useAssetResponseHandler.ts index 82eefa3..75b93e8 100644 --- a/app/src/modules/builder/asset/responseHandler/useAssetResponseHandler.ts +++ b/app/src/modules/collaboration/responseHandler/useAssetResponseHandler.ts @@ -1,5 +1,5 @@ import { useCallback } from "react"; -import { useSceneContext } from "../../../scene/sceneContext"; +import { useSceneContext } from "../../scene/sceneContext"; function useAssetResponseHandler() { const { assetStore } = useSceneContext(); @@ -24,13 +24,13 @@ function useAssetResponseHandler() { }, []); const duplicateAssetInScene = useCallback((modelUuid: string, callback?: () => void) => { - console.log("Duplicating asset with id:", modelUuid); + console.log("Duplicating asset: ", modelUuid); if (callback) callback(); }, []); const pasteAssetToScene = useCallback((asset: Asset, callback?: () => void) => { - console.log("Pasting asset:", asset); + console.log("Pasting asset: ", asset); if (callback) callback(); }, []); diff --git a/app/src/modules/collaboration/responseHandler/useWallAssetResponseHandler.ts b/app/src/modules/collaboration/responseHandler/useWallAssetResponseHandler.ts new file mode 100644 index 0000000..e555f55 --- /dev/null +++ b/app/src/modules/collaboration/responseHandler/useWallAssetResponseHandler.ts @@ -0,0 +1,47 @@ +import { useCallback } from "react"; +import { useSceneContext } from "../../scene/sceneContext"; + +function useWallAssetResponseHandler() { + const { wallAssetStore } = useSceneContext(); + const { addWallAsset, updateWallAsset, removeWallAsset } = wallAssetStore(); + + const addWallAssetToScene = useCallback((asset: WallAsset, callback?: () => void) => { + addWallAsset(asset); + + if (callback) callback(); + }, []); + + const updateWallAssetInScene = useCallback((asset: WallAsset, callback?: () => void) => { + updateWallAsset(asset.modelUuid, asset); + + if (callback) callback(); + }, []); + + const removeWallAssetFromScene = useCallback((modelUuid: string, callback?: () => void) => { + removeWallAsset(modelUuid); + + if (callback) callback(); + }, []); + + const duplicateWallAssetInScene = useCallback((modelUuid: string, callback?: () => void) => { + console.log("Duplicating wallAsset: ", modelUuid); + + if (callback) callback(); + }, []); + + const pasteAssetWallToScene = useCallback((asset: WallAsset, callback?: () => void) => { + console.log("Pasting wallAsset: ", asset); + + if (callback) callback(); + }, []); + + return { + addWallAssetToScene, + updateWallAssetInScene, + removeWallAssetFromScene, + duplicateWallAssetInScene, + pasteAssetWallToScene, + }; +} + +export default useWallAssetResponseHandler; diff --git a/app/src/modules/collaboration/responseHandler/useWallResponseHandler.ts b/app/src/modules/collaboration/responseHandler/useWallResponseHandler.ts new file mode 100644 index 0000000..52f3846 --- /dev/null +++ b/app/src/modules/collaboration/responseHandler/useWallResponseHandler.ts @@ -0,0 +1,47 @@ +import { useCallback } from "react"; +import { useSceneContext } from "../../scene/sceneContext"; + +function useWallResponseHandler() { + const { wallStore } = useSceneContext(); + const { addWall, updateWall, removeWall } = wallStore(); + + const addWallToScene = useCallback((wall: Wall, callback?: () => void) => { + addWall(wall); + + if (callback) callback(); + }, []); + + const updateWallInScene = useCallback((wall: Wall, callback?: () => void) => { + updateWall(wall.wallUuid, wall); + + if (callback) callback(); + }, []); + + const removeWallFromScene = useCallback((modelUuid: string, callback?: () => void) => { + removeWall(modelUuid); + + if (callback) callback(); + }, []); + + const duplicateWallInScene = useCallback((modelUuid: string, callback?: () => void) => { + console.log("Duplicating wall: ", modelUuid); + + if (callback) callback(); + }, []); + + const pasteAssetWallToScene = useCallback((wall: Wall, callback?: () => void) => { + console.log("Pasting wall: ", wall); + + if (callback) callback(); + }, []); + + return { + addWallToScene, + updateWallInScene, + removeWallFromScene, + duplicateWallInScene, + pasteAssetWallToScene, + }; +} + +export default useWallResponseHandler; diff --git a/app/src/modules/collaboration/socket/builderResponses.tsx b/app/src/modules/collaboration/socket/builderResponses.tsx index 1d406d0..78f0529 100644 --- a/app/src/modules/collaboration/socket/builderResponses.tsx +++ b/app/src/modules/collaboration/socket/builderResponses.tsx @@ -1,13 +1,17 @@ import { useEffect } from "react"; -import { useSocketStore } from "../../../store/socket/useSocketStore"; -import useAssetResponseHandler from "../../builder/asset/responseHandler/useAssetResponseHandler"; import { useSceneContext } from "../../scene/sceneContext"; +import { useSocketStore } from "../../../store/socket/useSocketStore"; +import useAssetResponseHandler from "../responseHandler/useAssetResponseHandler"; +import useWallAssetResponseHandler from "../responseHandler/useWallAssetResponseHandler"; +import useWallResponseHandler from "../responseHandler/useWallResponseHandler"; function BuilderResponses() { const { assetStore } = useSceneContext(); const { getAssetById } = assetStore(); const { builderSocket } = useSocketStore(); const { addAssetToScene, updateAssetInScene, removeAssetFromScene } = useAssetResponseHandler(); + const { addWallAssetToScene, updateWallAssetInScene, removeWallAssetFromScene } = useWallAssetResponseHandler(); + const { addWallToScene, updateWallInScene, removeWallFromScene } = useWallResponseHandler(); //#region Asset useEffect(() => { @@ -54,7 +58,7 @@ function BuilderResponses() { }); } else { removeAssetFromScene(data.data.modelUuid, () => { - echo.error(`Error adding asset: ${data?.data?.modelName}`); + echo.error(`Error adding or updating asset: ${data?.data?.modelName}`); }); } }); @@ -158,15 +162,62 @@ function BuilderResponses() { if (!builderSocket) return; builderSocket.on("v1:wall-asset:response:add", (data: any) => { - if (!data.message) return; + if (!data.message || !data.data) { + echo.error(`Error adding or updating wallAsset`); + return; + } if (data.message === "WallAsset Created Successfully") { + const model: WallAsset = { + modelName: data.data.modelName, + modelUuid: data.data.modelUuid, + wallUuid: data.data.wallUuid, + wallAssetType: data.data.wallAssetType, + assetId: data.data.assetId, + position: data.data.position, + rotation: data.data.rotation, + isLocked: data.data.isLocked, + isVisible: data.data.isVisible, + opacity: data.data.opacity, + }; + + addWallAssetToScene(model, () => { + echo.log(`Added wallAsset: ${model.modelName}`); + }); } else if (data.message === "WallAsset Updated Successfully") { + const model: WallAsset = { + modelName: data.data.modelName, + modelUuid: data.data.modelUuid, + wallUuid: data.data.wallUuid, + wallAssetType: data.data.wallAssetType, + assetId: data.data.assetId, + position: data.data.position, + rotation: data.data.rotation, + isLocked: data.data.isLocked, + isVisible: data.data.isVisible, + opacity: data.data.opacity, + }; + + updateWallAssetInScene(model, () => { + echo.log(`Updated wallAsset: ${model.modelName}`); + }); + } else { + removeWallAssetFromScene(data.data.modelUuid, () => { + echo.error(`Error adding or updating wallAsset: ${data?.data?.modelName}`); + }); } }); builderSocket.on("v1:wall-asset:response:delete", (data: any) => { - if (!data.message) return; - if (data.message === "WallAsset Created Successfully") { + if (!data.message || !data.data) { + echo.error(`Error removing wallAsset`); + return; + } + if (data.message === "WallAsset Deleted Successfully") { + removeWallAssetFromScene(data.data.modelUuid, () => { + echo.log(`Removed wallAsset: ${data.data.modelName}`); + }); + } else { + echo.error(`Error removing wallAsset: ${data?.data?.modelName}`); } }); @@ -184,15 +235,56 @@ function BuilderResponses() { if (!builderSocket) return; builderSocket.on("v1:model-Wall:response:add", (data: any) => { - if (!data.message) return; + if (!data.message || !data.data) { + echo.error(`Error adding or updating wall`); + return; + } if (data.message === "Wall Created Successfully") { + const wall: Wall = { + wallUuid: data.data.wallUuid, + points: data.data.points, + outsideMaterial: data.data.outsideMaterial, + insideMaterial: data.data.insideMaterial, + wallThickness: data.data.wallThickness, + wallHeight: data.data.wallHeight, + decals: data.data.decals, + }; + + addWallToScene(wall, () => { + echo.log(`Added wall: ${wall.wallUuid}`); + }); } else if (data.message === "Wall Updated Successfully") { + const wall: Wall = { + wallUuid: data.data.wallUuid, + points: data.data.points, + outsideMaterial: data.data.outsideMaterial, + insideMaterial: data.data.insideMaterial, + wallThickness: data.data.wallThickness, + wallHeight: data.data.wallHeight, + decals: data.data.decals, + }; + + updateWallInScene(wall, () => { + echo.log(`Updated wall: ${wall.wallUuid}`); + }); + } else { + removeWallFromScene(data.data.wallUuid, () => { + echo.error(`Error adding or updating wall: ${data?.data?.wallUuid}`); + }); } }); builderSocket.on("v1:model-Wall:response:delete", (data: any) => { - if (!data.message) return; + if (!data.message || !data.data) { + echo.error(`Error deleting wall`); + return; + } if (data.message === "Wall Deleted Successfully") { + removeWallFromScene(data.data.wallUuid, () => { + echo.log(`Removed wall: ${data.data.wallUuid}`); + }); + } else { + echo.error(`Error removing wall: ${data?.data?.wallUuid}`); } }); @@ -262,7 +354,6 @@ function BuilderResponses() { if (!builderSocket) return; builderSocket.on("v1:zone:response:updates", (data: any) => { - console.log("data: ", data); if (!data.message) return; if (data.message === "zone created successfully") { } else if (data.message === "zone updated") { @@ -270,7 +361,6 @@ function BuilderResponses() { }); builderSocket.on("v1:zone:response:delete", (data: any) => { - console.log("data: ", data); if (!data.message) return; if (data.message === "zone deleted created successfully") { } diff --git a/app/src/modules/scene/controls/selectionControls/selection2D/moveControls2D.tsx b/app/src/modules/scene/controls/selectionControls/selection2D/moveControls2D.tsx index c5f0156..28873b1 100644 --- a/app/src/modules/scene/controls/selectionControls/selection2D/moveControls2D.tsx +++ b/app/src/modules/scene/controls/selectionControls/selection2D/moveControls2D.tsx @@ -1,14 +1,16 @@ import * as THREE from "three"; +import { useParams } from "react-router-dom"; import { useCallback, useEffect, useMemo, useState } from "react"; import { useFrame, useThree } from "@react-three/fiber"; import { useToggleView, useToolMode } from "../../../../../store/builder/store"; import { useSocketStore } from "../../../../../store/socket/useSocketStore"; import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys"; -import { useParams } from "react-router-dom"; import { getUserData } from "../../../../../functions/getUserData"; import { useSceneContext } from "../../../sceneContext"; import { useSelectedPoints } from "../../../../../store/simulation/useSimulationStore"; import useModuleStore from "../../../../../store/ui/useModuleStore"; +import useWallAssetResponseHandler from "../../../../collaboration/responseHandler/useWallAssetResponseHandler"; +import useWallResponseHandler from "../../../../collaboration/responseHandler/useWallResponseHandler"; import { calculateAssetTransformationOnWall } from "../../../../builder/wallAsset/Instances/Instance/functions/calculateAssetTransformationOnWall"; import { upsertAisleApi } from "../../../../../services/factoryBuilder/aisle/upsertAisleApi"; @@ -29,7 +31,9 @@ function MoveControls2D({ movedObjects, setMovedObjects, pastedObjects, setPaste const { projectId } = useParams(); const { aisleStore, wallStore, floorStore, zoneStore, undoRedo2DStore, wallAssetStore, versionStore } = useSceneContext(); const { selectedVersion } = versionStore(); - const { getWallAssetsByWall, updateWallAsset } = wallAssetStore(); + const { getWallAssetsByWall } = wallAssetStore(); + const { updateWallAssetInScene } = useWallAssetResponseHandler(); + const { updateWallInScene } = useWallResponseHandler(); const { push2D } = undoRedo2DStore(); const { setPosition: setAislePosition, getAislesByPointId, getAisleById } = aisleStore(); const { setPosition: setWallPosition, getWallsByPointId, getWallById } = wallStore(); @@ -319,7 +323,23 @@ function MoveControls2D({ movedObjects, setMovedObjects, pastedObjects, setPaste if (!builderSocket?.connected) { // API - upsertWallApi(projectId, selectedVersion?.versionId || "", updatedWall); + upsertWallApi(projectId, selectedVersion?.versionId || "", updatedWall) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error updating wall`); + return; + } + if (data.message === "Wall Updated Successfully") { + updateWallInScene(updatedWall, () => { + echo.log(`Updated wall: ${updatedWall.wallUuid}`); + }); + } else { + echo.error(`Error updating wall: ${updatedWall.wallUuid}`); + } + }) + .catch(() => { + echo.error(`Error updating wall: ${updatedWall.wallUuid}`); + }); } else { // SOCKET @@ -442,15 +462,26 @@ function MoveControls2D({ movedObjects, setMovedObjects, pastedObjects, setPaste wallAssetUpdates.filter((wallAssets, index, self) => index === self.findIndex((w) => w.modelUuid === wallAssets.modelUuid)); wallAssetUpdates.forEach((updatedWallAsset) => { if (projectId && updatedWallAsset) { - updateWallAsset(updatedWallAsset.modelUuid, { - position: updatedWallAsset.position, - rotation: updatedWallAsset.rotation, - }); - if (!builderSocket?.connected) { // API - upsertWallAssetApi(projectId, selectedVersion?.versionId || "", updatedWallAsset); + upsertWallAssetApi(projectId, selectedVersion?.versionId || "", updatedWallAsset) + .then((data) => { + if (!data.message) { + echo.error(`Error updating wallAsset ${updatedWallAsset.modelName} on the wall`); + return; + } + if (data.message === "WallAsset Updated Successfully" && data.data) { + updateWallAssetInScene(updatedWallAsset, () => { + echo.log(`Updated wallAsset: ${updatedWallAsset.modelUuid}`); + }); + } else { + echo.error(`Error updating wallAsset ${updatedWallAsset.modelName} on the wall`); + } + }) + .catch(() => { + echo.error(`Error updating wallAsset ${updatedWallAsset.modelName} on the wall`); + }); } else { // SOCKET diff --git a/app/src/modules/scene/controls/selectionControls/selection2D/selectionControls2D.tsx b/app/src/modules/scene/controls/selectionControls/selection2D/selectionControls2D.tsx index 3daf5fe..f6848f1 100644 --- a/app/src/modules/scene/controls/selectionControls/selection2D/selectionControls2D.tsx +++ b/app/src/modules/scene/controls/selectionControls/selection2D/selectionControls2D.tsx @@ -12,6 +12,8 @@ import { useToggleView, useToolMode } from "../../../../../store/builder/store"; import { useSocketStore } from "../../../../../store/socket/useSocketStore"; import { useSelectedPoints } from "../../../../../store/simulation/useSimulationStore"; import { useBuilderStore } from "../../../../../store/builder/useBuilderStore"; +import useWallAssetResponseHandler from "../../../../collaboration/responseHandler/useWallAssetResponseHandler"; +import useWallResponseHandler from "../../../../collaboration/responseHandler/useWallResponseHandler"; import MoveControls2D from "./moveControls2D"; import { deleteAisleApi } from "../../../../../services/factoryBuilder/aisle/deleteAisleApi"; @@ -39,10 +41,12 @@ const SelectionControls2D: React.FC = () => { const { hoveredLine, hoveredPoint } = useBuilderStore(); const { aisleStore, wallStore, floorStore, zoneStore, undoRedo2DStore, wallAssetStore, versionStore } = useSceneContext(); const { selectedVersion } = versionStore(); - const { getWallAssetsByWall, removeWallAsset } = wallAssetStore(); + const { getWallAssetsByWall } = wallAssetStore(); + const { removeWallAssetFromScene } = useWallAssetResponseHandler(); + const { removeWallFromScene } = useWallResponseHandler(); const { push2D } = undoRedo2DStore(); const { removePoint: removeAislePoint } = aisleStore(); - const { removePoint: removeWallPoint } = wallStore(); + const { peekRemovePoint: peekRemoveWallPoint } = wallStore(); const { removePoint: removeFloorPoint, getFloorsByPointId, getFloorById } = floorStore(); const { removePoint: removeZonePoint, getZonesByPointId, getZoneById } = zoneStore(); @@ -271,19 +275,33 @@ const SelectionControls2D: React.FC = () => { } } if (point.pointType === "Wall") { - const removedWalls = removeWallPoint(point.pointUuid); + const removedWalls = peekRemoveWallPoint(point.pointUuid); if (removedWalls.length > 0) { removedWalls.forEach((wall) => { const assetsOnWall = getWallAssetsByWall(wall.wallUuid); assetsOnWall.forEach((asset) => { if (projectId && asset) { - removeWallAsset(asset.modelUuid); - if (!builderSocket?.connected) { // API - deleteWallAssetApi(projectId, selectedVersion?.versionId || "", asset.modelUuid, asset.wallUuid); + deleteWallAssetApi(projectId, selectedVersion?.versionId || "", asset.modelUuid, asset.wallUuid) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error removing wallAsset from wall`); + return; + } + if (data.message === "WallAsset Deleted Successfully") { + removeWallAssetFromScene(asset.modelUuid, () => { + echo.log(`Removed wallAsset: ${asset.modelName} along with wall`); + }); + } else { + echo.error(`Error removing wallAsset: ${asset.modelName} from wall`); + } + }) + .catch(() => { + echo.error(`Error removing wallAsset: ${asset.modelName}`); + }); } else { // SOCKET @@ -305,7 +323,23 @@ const SelectionControls2D: React.FC = () => { if (!builderSocket?.connected) { // API - deleteWallApi(projectId, selectedVersion?.versionId || "", wall.wallUuid); + deleteWallApi(projectId, selectedVersion?.versionId || "", wall.wallUuid) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error removing wall`); + return; + } + if (data.message === "Wall Deleted Successfully") { + removeWallFromScene(wall.wallUuid, () => { + echo.log(`Removed wall: ${wall.wallUuid}`); + }); + } else { + echo.error(`Error removing wall: ${wall.wallUuid}`); + } + }) + .catch(() => { + echo.error(`Error removing wall: ${wall.wallUuid}`); + }); } else { // SOCKET diff --git a/app/src/modules/scene/controls/selectionControls/selection3D/copyPasteControls3D.tsx b/app/src/modules/scene/controls/selectionControls/selection3D/copyPasteControls3D.tsx index 5e0c52e..79103ec 100644 --- a/app/src/modules/scene/controls/selectionControls/selection3D/copyPasteControls3D.tsx +++ b/app/src/modules/scene/controls/selectionControls/selection3D/copyPasteControls3D.tsx @@ -9,7 +9,7 @@ import { useSocketStore } from "../../../../../store/socket/useSocketStore"; import { useContextActionStore, useToggleView } from "../../../../../store/builder/store"; import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys"; import { getUserData } from "../../../../../functions/getUserData"; -import useAssetResponseHandler from "../../../../builder/asset/responseHandler/useAssetResponseHandler"; +import useAssetResponseHandler from "../../../../collaboration/responseHandler/useAssetResponseHandler"; import { setAssetsApi } from "../../../../../services/factoryBuilder/asset/floorAsset/setAssetsApi"; diff --git a/app/src/modules/scene/controls/selectionControls/selection3D/duplicationControls3D.tsx b/app/src/modules/scene/controls/selectionControls/selection3D/duplicationControls3D.tsx index 271566d..1c02e62 100644 --- a/app/src/modules/scene/controls/selectionControls/selection3D/duplicationControls3D.tsx +++ b/app/src/modules/scene/controls/selectionControls/selection3D/duplicationControls3D.tsx @@ -10,7 +10,7 @@ import { useContextActionStore, useToggleView } from "../../../../../store/build import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys"; import { getUserData } from "../../../../../functions/getUserData"; import { handleAssetPositionSnap } from "./functions/handleAssetPositionSnap"; -import useAssetResponseHandler from "../../../../builder/asset/responseHandler/useAssetResponseHandler"; +import useAssetResponseHandler from "../../../../collaboration/responseHandler/useAssetResponseHandler"; import { setAssetsApi } from "../../../../../services/factoryBuilder/asset/floorAsset/setAssetsApi"; diff --git a/app/src/modules/scene/controls/selectionControls/selection3D/moveControls3D.tsx b/app/src/modules/scene/controls/selectionControls/selection3D/moveControls3D.tsx index ced7fa9..779de9c 100644 --- a/app/src/modules/scene/controls/selectionControls/selection3D/moveControls3D.tsx +++ b/app/src/modules/scene/controls/selectionControls/selection3D/moveControls3D.tsx @@ -11,7 +11,7 @@ import { handleAssetPositionSnap } from "./functions/handleAssetPositionSnap"; import DistanceFindingControls from "./distanceFindingControls"; import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys"; import { getUserData } from "../../../../../functions/getUserData"; -import useAssetResponseHandler from "../../../../builder/asset/responseHandler/useAssetResponseHandler"; +import useAssetResponseHandler from "../../../../collaboration/responseHandler/useAssetResponseHandler"; import { upsertProductOrEventApi } from "../../../../../services/simulation/products/UpsertProductOrEventApi"; import { setAssetsApi } from "../../../../../services/factoryBuilder/asset/floorAsset/setAssetsApi"; diff --git a/app/src/modules/scene/controls/selectionControls/selection3D/rotateControls3D.tsx b/app/src/modules/scene/controls/selectionControls/selection3D/rotateControls3D.tsx index 87a524e..9be2e2c 100644 --- a/app/src/modules/scene/controls/selectionControls/selection3D/rotateControls3D.tsx +++ b/app/src/modules/scene/controls/selectionControls/selection3D/rotateControls3D.tsx @@ -11,7 +11,7 @@ import { useSceneContext } from "../../../sceneContext"; import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys"; import { handleAssetRotationSnap } from "./functions/handleAssetRotationSnap"; import useModuleStore from "../../../../../store/ui/useModuleStore"; -import useAssetResponseHandler from "../../../../builder/asset/responseHandler/useAssetResponseHandler"; +import useAssetResponseHandler from "../../../../collaboration/responseHandler/useAssetResponseHandler"; import { setAssetsApi } from "../../../../../services/factoryBuilder/asset/floorAsset/setAssetsApi"; diff --git a/app/src/modules/scene/controls/selectionControls/selection3D/selectionControls3D.tsx b/app/src/modules/scene/controls/selectionControls/selection3D/selectionControls3D.tsx index e7e5051..4c84035 100644 --- a/app/src/modules/scene/controls/selectionControls/selection3D/selectionControls3D.tsx +++ b/app/src/modules/scene/controls/selectionControls/selection3D/selectionControls3D.tsx @@ -19,7 +19,7 @@ import TransformControls3D from "./transformControls3D"; import { useBuilderStore } from "../../../../../store/builder/useBuilderStore"; import { deleteFloorAssetApi } from "../../../../../services/factoryBuilder/asset/floorAsset/deleteFloorAssetApi"; -import useAssetResponseHandler from "../../../../builder/asset/responseHandler/useAssetResponseHandler"; +import useAssetResponseHandler from "../../../../collaboration/responseHandler/useAssetResponseHandler"; const SelectionControls3D: React.FC = () => { const { camera, controls, gl, scene, raycaster, pointer } = useThree(); diff --git a/app/src/modules/scene/controls/selectionControls/selection3D/transformControls3D.tsx b/app/src/modules/scene/controls/selectionControls/selection3D/transformControls3D.tsx index 43e37ab..8c1d971 100644 --- a/app/src/modules/scene/controls/selectionControls/selection3D/transformControls3D.tsx +++ b/app/src/modules/scene/controls/selectionControls/selection3D/transformControls3D.tsx @@ -6,7 +6,7 @@ import { useRef, useEffect, useState, useCallback } from "react"; import { useToolMode } from "../../../../../store/builder/store"; import { useSocketStore } from "../../../../../store/socket/useSocketStore"; import { useSceneContext } from "../../../sceneContext"; -import useAssetResponseHandler from "../../../../builder/asset/responseHandler/useAssetResponseHandler"; +import useAssetResponseHandler from "../../../../collaboration/responseHandler/useAssetResponseHandler"; import { getUserData } from "../../../../../functions/getUserData"; import { upsertProductOrEventApi } from "../../../../../services/simulation/products/UpsertProductOrEventApi"; diff --git a/app/src/modules/scene/controls/transformControls/transformControls.tsx b/app/src/modules/scene/controls/transformControls/transformControls.tsx index d16b078..233fd5f 100644 --- a/app/src/modules/scene/controls/transformControls/transformControls.tsx +++ b/app/src/modules/scene/controls/transformControls/transformControls.tsx @@ -8,7 +8,7 @@ import { useSceneContext } from "../../sceneContext"; import { useObjectPosition, useObjectRotation, useActiveTool } from "../../../../store/builder/store"; import { useSocketStore } from "../../../../store/socket/useSocketStore"; import { useBuilderStore } from "../../../../store/builder/useBuilderStore"; -import useAssetResponseHandler from "../../../builder/asset/responseHandler/useAssetResponseHandler"; +import useAssetResponseHandler from "../../../collaboration/responseHandler/useAssetResponseHandler"; import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys"; import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi"; diff --git a/app/src/modules/scene/controls/undoRedoControls/handlers/use2DRedoHandler.ts b/app/src/modules/scene/controls/undoRedoControls/handlers/use2DRedoHandler.ts index 508414f..da7c569 100644 --- a/app/src/modules/scene/controls/undoRedoControls/handlers/use2DRedoHandler.ts +++ b/app/src/modules/scene/controls/undoRedoControls/handlers/use2DRedoHandler.ts @@ -2,6 +2,7 @@ import { useParams } from "react-router-dom"; import { getUserData } from "../../../../../functions/getUserData"; import { useSceneContext } from "../../../sceneContext"; import { useSocketStore } from "../../../../../store/socket/useSocketStore"; +import useWallResponseHandler from "../../../../collaboration/responseHandler/useWallResponseHandler"; import { upsertWallApi } from "../../../../../services/factoryBuilder/wall/upsertWallApi"; import { deleteWallApi } from "../../../../../services/factoryBuilder/wall/deleteWallApi"; @@ -16,9 +17,9 @@ import { upsertAisleApi } from "../../../../../services/factoryBuilder/aisle/ups import { deleteAisleApi } from "../../../../../services/factoryBuilder/aisle/deleteAisleApi"; function use2DRedoHandler() { - const { undoRedo2DStore, wallStore, floorStore, zoneStore, aisleStore, versionStore } = useSceneContext(); + const { undoRedo2DStore, floorStore, zoneStore, aisleStore, versionStore } = useSceneContext(); const { redo2D, peekRedo2D } = undoRedo2DStore(); - const { addWall, removeWall, updateWall } = wallStore(); + const { addWallToScene, removeWallFromScene, updateWallInScene } = useWallResponseHandler(); const { addFloor, removeFloor, updateFloor } = floorStore(); const { addZone, removeZone, updateZone } = zoneStore(); const { addAisle, removeAisle, updateAisle } = aisleStore(); @@ -119,12 +120,27 @@ function use2DRedoHandler() { }; const createWallFromBackend = (wallData: Wall) => { - addWall(wallData); if (projectId) { if (!builderSocket?.connected) { // API - upsertWallApi(projectId, selectedVersion?.versionId || "", wallData); + upsertWallApi(projectId, selectedVersion?.versionId || "", wallData) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error adding wall`); + return; + } + if (data.message === "Wall Created Successfully") { + addWallToScene(wallData, () => { + echo.log(`Added wall: ${wallData.wallUuid}`); + }); + } else { + echo.error(`Error adding wall: ${wallData.wallUuid}`); + } + }) + .catch(() => { + echo.error(`Error adding wall: ${wallData.wallUuid}`); + }); } else { // SOCKET @@ -142,12 +158,27 @@ function use2DRedoHandler() { }; const removeWallFromBackend = (wallUuid: string) => { - removeWall(wallUuid); if (projectId) { if (!builderSocket?.connected) { // API - deleteWallApi(projectId, selectedVersion?.versionId || "", wallUuid); + deleteWallApi(projectId, selectedVersion?.versionId || "", wallUuid) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error removing wall`); + return; + } + if (data.message === "Wall Deleted Successfully") { + removeWallFromScene(wallUuid, () => { + echo.log(`Removed wall: ${wallUuid}`); + }); + } else { + echo.error(`Error removing wall: ${wallUuid}`); + } + }) + .catch(() => { + echo.error(`Error removing wall: ${wallUuid}`); + }); } else { // SOCKET @@ -165,12 +196,25 @@ function use2DRedoHandler() { }; const updateWallFromBackend = (wallUuid: string, updatedData: Wall) => { - updateWall(wallUuid, updatedData); if (projectId) { if (!builderSocket?.connected) { // API - upsertWallApi(projectId, selectedVersion?.versionId || "", updatedData); + upsertWallApi(projectId, selectedVersion?.versionId || "", updatedData) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error updating wall`); + return; + } + if (data.message === "Wall Updated Successfully") { + updateWallInScene(updatedData, () => { + echo.log(`Updated wall: ${updatedData.wallUuid}`); + }); + } + }) + .catch(() => { + echo.error(`Error updating wall: ${updatedData.wallUuid}`); + }); } else { // SOCKET diff --git a/app/src/modules/scene/controls/undoRedoControls/handlers/use2DUndoHandler.ts b/app/src/modules/scene/controls/undoRedoControls/handlers/use2DUndoHandler.ts index d0e723a..2353e64 100644 --- a/app/src/modules/scene/controls/undoRedoControls/handlers/use2DUndoHandler.ts +++ b/app/src/modules/scene/controls/undoRedoControls/handlers/use2DUndoHandler.ts @@ -2,6 +2,7 @@ import { useParams } from "react-router-dom"; import { getUserData } from "../../../../../functions/getUserData"; import { useSceneContext } from "../../../sceneContext"; import { useSocketStore } from "../../../../../store/socket/useSocketStore"; +import useWallResponseHandler from "../../../../collaboration/responseHandler/useWallResponseHandler"; import { upsertWallApi } from "../../../../../services/factoryBuilder/wall/upsertWallApi"; import { deleteWallApi } from "../../../../../services/factoryBuilder/wall/deleteWallApi"; @@ -16,9 +17,9 @@ import { upsertAisleApi } from "../../../../../services/factoryBuilder/aisle/ups import { deleteAisleApi } from "../../../../../services/factoryBuilder/aisle/deleteAisleApi"; function use2DUndoHandler() { - const { undoRedo2DStore, wallStore, floorStore, zoneStore, aisleStore, versionStore } = useSceneContext(); + const { undoRedo2DStore, floorStore, zoneStore, aisleStore, versionStore } = useSceneContext(); const { undo2D, peekUndo2D } = undoRedo2DStore(); - const { addWall, removeWall, updateWall } = wallStore(); + const { addWallToScene, removeWallFromScene, updateWallInScene } = useWallResponseHandler(); const { addFloor, removeFloor, updateFloor } = floorStore(); const { addZone, removeZone, updateZone } = zoneStore(); const { addAisle, removeAisle, updateAisle } = aisleStore(); @@ -118,12 +119,27 @@ function use2DUndoHandler() { }; const createWallToBackend = (wallData: Wall) => { - addWall(wallData); if (projectId) { if (!builderSocket?.connected) { // API - upsertWallApi(projectId, selectedVersion?.versionId || "", wallData); + upsertWallApi(projectId, selectedVersion?.versionId || "", wallData) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error adding wall`); + return; + } + if (data.message === "Wall Created Successfully") { + addWallToScene(wallData, () => { + echo.log(`Added wall: ${wallData.wallUuid}`); + }); + } else { + echo.error(`Error adding wall: ${wallData.wallUuid}`); + } + }) + .catch(() => { + echo.error(`Error adding wall: ${wallData.wallUuid}`); + }); } else { // SOCKET @@ -136,17 +152,33 @@ function use2DUndoHandler() { }; builderSocket.emit("v1:model-Wall:add", data); + console.log('data: ', data); } } }; const removeWallToBackend = (wallUuid: string) => { - removeWall(wallUuid); if (projectId) { if (!builderSocket?.connected) { // API - deleteWallApi(projectId, selectedVersion?.versionId || "", wallUuid); + deleteWallApi(projectId, selectedVersion?.versionId || "", wallUuid) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error removing wall`); + return; + } + if (data.message === "Wall Deleted Successfully") { + removeWallFromScene(wallUuid, () => { + echo.log(`Removed wall: ${wallUuid}`); + }); + } else { + echo.error(`Error removing wall: ${wallUuid}`); + } + }) + .catch(() => { + echo.error(`Error removing wall: ${wallUuid}`); + }); } else { // SOCKET @@ -164,12 +196,25 @@ function use2DUndoHandler() { }; const updateWallToBackend = (wallUuid: string, updatedData: Wall) => { - updateWall(wallUuid, updatedData); if (projectId) { if (!builderSocket?.connected) { // API - upsertWallApi(projectId, selectedVersion?.versionId || "", updatedData); + upsertWallApi(projectId, selectedVersion?.versionId || "", updatedData) + .then((data) => { + if (!data.message || !data.data) { + echo.error(`Error updating wall`); + return; + } + if (data.message === "Wall Updated Successfully") { + updateWallInScene(updatedData, () => { + echo.log(`Updated wall: ${updatedData.wallUuid}`); + }); + } + }) + .catch(() => { + echo.error(`Error updating wall: ${updatedData.wallUuid}`); + }); } else { // SOCKET diff --git a/app/src/modules/scene/controls/undoRedoControls/handlers/use3DRedoHandler.ts b/app/src/modules/scene/controls/undoRedoControls/handlers/use3DRedoHandler.ts index 60b7eab..2d2c019 100644 --- a/app/src/modules/scene/controls/undoRedoControls/handlers/use3DRedoHandler.ts +++ b/app/src/modules/scene/controls/undoRedoControls/handlers/use3DRedoHandler.ts @@ -2,7 +2,7 @@ import { useParams } from "react-router-dom"; import { getUserData } from "../../../../../functions/getUserData"; import { useSceneContext } from "../../../sceneContext"; import { useSocketStore } from "../../../../../store/socket/useSocketStore"; -import useAssetResponseHandler from "../../../../builder/asset/responseHandler/useAssetResponseHandler"; +import useAssetResponseHandler from "../../../../collaboration/responseHandler/useAssetResponseHandler"; import { upsertProductOrEventApi } from "../../../../../services/simulation/products/UpsertProductOrEventApi"; @@ -13,7 +13,7 @@ function use3DRedoHandler() { const { undoRedo3DStore, productStore, eventStore, versionStore } = useSceneContext(); const { deleteEvent, selectedProduct } = productStore(); const { addEvent, removeEvent } = eventStore(); - const { addAssetToScene, removeAssetFromScene, updateAssetInScene } = useAssetResponseHandler(); + const { addAssetToScene, removeAssetFromScene } = useAssetResponseHandler(); const { redo3D, peekRedo3D } = undoRedo3DStore(); const { selectedVersion } = versionStore(); const { userId, organization } = getUserData(); diff --git a/app/src/modules/scene/controls/undoRedoControls/handlers/use3DUndoHandler.ts b/app/src/modules/scene/controls/undoRedoControls/handlers/use3DUndoHandler.ts index fa6b213..c6a304c 100644 --- a/app/src/modules/scene/controls/undoRedoControls/handlers/use3DUndoHandler.ts +++ b/app/src/modules/scene/controls/undoRedoControls/handlers/use3DUndoHandler.ts @@ -2,7 +2,7 @@ import { useParams } from "react-router-dom"; import { getUserData } from "../../../../../functions/getUserData"; import { useSceneContext } from "../../../sceneContext"; import { useSocketStore } from "../../../../../store/socket/useSocketStore"; -import useAssetResponseHandler from "../../../../builder/asset/responseHandler/useAssetResponseHandler"; +import useAssetResponseHandler from "../../../../collaboration/responseHandler/useAssetResponseHandler"; import { upsertProductOrEventApi } from "../../../../../services/simulation/products/UpsertProductOrEventApi"; diff --git a/app/src/services/simulation/comparison/validateSimulationDataApi.ts b/app/src/services/simulation/comparison/validateSimulationDataApi.ts index 4323e35..4dcfe38 100644 --- a/app/src/services/simulation/comparison/validateSimulationDataApi.ts +++ b/app/src/services/simulation/comparison/validateSimulationDataApi.ts @@ -1,4 +1,5 @@ let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + export const validateSimulationDataApi = async (data: any) => { try { const response = await fetch(`${url_Backend_dwinzo}/api/V1/ValidateSimulated`, { diff --git a/app/src/store/builder/useWallStore.ts b/app/src/store/builder/useWallStore.ts index 705e611..74afdbe 100644 --- a/app/src/store/builder/useWallStore.ts +++ b/app/src/store/builder/useWallStore.ts @@ -1,30 +1,36 @@ -import { create } from 'zustand'; -import { immer } from 'zustand/middleware/immer'; +import { create } from "zustand"; +import { immer } from "zustand/middleware/immer"; interface WallStore { walls: Wall[]; setWalls: (walls: Wall[]) => void; addWall: (wall: Wall) => void; - updateWall: (uuid: string, updated: Partial) => Wall | undefined; - removeWall: (uuid: string) => void; + updateWall: (wallUuid: string, updated: Partial) => Wall | undefined; + peekUpdateWall: (wallUuid: string, updated: Partial) => Wall | undefined; + removeWall: (wallUuid: string) => void; clearWalls: () => void; removeWallByPoints: (Points: [Point, Point]) => Wall | undefined; + peekRemoveWallByPoints: (points: [Point, Point]) => Wall | undefined; addDecal: (wallUuid: string, decal: Decal) => Decal | undefined; + peekAddDecal: (wallUuid: string, decal: Decal) => Wall | undefined; updateDecal: (decalUuid: string, decal: Partial) => Wall | undefined; + peekUpdateDecal: (decalUuid: string, decal: Partial) => Wall | undefined; removeDecal: (decalUuid: string) => Wall | undefined; updateDecalPosition: (decalUuid: string, position: [number, number, number]) => Wall | undefined; updateDecalRotation: (decalUuid: string, rotation: number) => void; updateDecalScale: (decalUuid: string, scale: number) => void; removePoint: (pointUuid: string) => Wall[]; + peekRemovePoint: (pointUuid: string) => Wall[]; + setPosition: (pointUuid: string, position: [number, number, number]) => Wall[] | []; setLayer: (pointUuid: string, layer: number) => void; - getWallById: (uuid: string) => Wall | undefined; - getWallsByPointId: (uuid: string) => Wall[] | []; + getWallById: (wallUuid: string) => Wall | undefined; + getWallsByPointId: (wallUuid: string) => Wall[] | []; getWallByPoints: (points: Point[]) => Wall | undefined; - getWallPointById: (uuid: string) => Point | undefined; - getConnectedPoints: (uuid: string) => Point[]; + getWallPointById: (wallUuid: string) => Point | undefined; + getConnectedPoints: (wallUuid: string) => Point[]; getConnectedWallsByWallId: (wallUuid: string, skipSelf: boolean) => Wall[]; } @@ -33,18 +39,20 @@ export const createWallStore = () => { immer((set, get) => ({ walls: [], - setWalls: (walls) => set((state) => { - state.walls = walls; - }), + setWalls: (walls) => + set((state) => { + state.walls = walls; + }), - addWall: (wall) => set((state) => { - state.walls.push(wall); - }), + addWall: (wall) => + set((state) => { + state.walls.push(wall); + }), - updateWall: (uuid, updated) => { + updateWall: (wallUuid, updated) => { let updatedWall: Wall | undefined; set((state) => { - const wall = state.walls.find(w => w.wallUuid === uuid); + const wall = state.walls.find((w) => w.wallUuid === wallUuid); if (wall) { Object.assign(wall, updated); updatedWall = JSON.parse(JSON.stringify(wall)); @@ -53,14 +61,25 @@ export const createWallStore = () => { return updatedWall; }, - removeWall: (uuid) => set((state) => { - state.walls = state.walls.filter(w => w.wallUuid !== uuid); - }), + peekUpdateWall: (wallUuid, updated) => { + const wall = get().walls.find((w) => w.wallUuid === wallUuid); + if (!wall) return undefined; + + const clonedWall: Wall = JSON.parse(JSON.stringify(wall)); + Object.assign(clonedWall, updated); + + return clonedWall; + }, + + removeWall: (wallUuid) => + set((state) => { + state.walls = state.walls.filter((w) => w.wallUuid !== wallUuid); + }), clearWalls: () => { set((state) => { state.walls = []; - }) + }); }, removeWallByPoints: (points) => { @@ -68,8 +87,8 @@ export const createWallStore = () => { const [pointA, pointB] = points; set((state) => { - state.walls = state.walls.filter(wall => { - const wallPoints = wall.points.map(p => p.pointUuid); + state.walls = state.walls.filter((wall) => { + const wallPoints = wall.points.map((p) => p.pointUuid); const hasBothPoints = wallPoints.includes(pointA.pointUuid) && wallPoints.includes(pointB.pointUuid); if (hasBothPoints) { @@ -83,23 +102,44 @@ export const createWallStore = () => { return removedWall; }, + peekRemoveWallByPoints: (points) => { + const [pointA, pointB] = points; + + const wall = get().walls.find((w) => { + const wallPoints = w.points.map((p) => p.pointUuid); + return wallPoints.includes(pointA.pointUuid) && wallPoints.includes(pointB.pointUuid); + }); + + return wall ? JSON.parse(JSON.stringify(wall)) : undefined; + }, + addDecal: (wallUuid, decal) => { let addedDecal: Decal | undefined; set((state) => { - const wallToUpdate = state.walls.find(w => w.wallUuid === wallUuid); + const wallToUpdate = state.walls.find((w) => w.wallUuid === wallUuid); if (wallToUpdate) { wallToUpdate.decals.push(decal); addedDecal = JSON.parse(JSON.stringify(decal)); } - }) + }); return addedDecal; }, + peekAddDecal: (wallUuid, decal) => { + const wall = get().walls.find((w) => w.wallUuid === wallUuid); + if (!wall) return undefined; + + const clonedWall: Wall = JSON.parse(JSON.stringify(wall)); + clonedWall.decals.push(JSON.parse(JSON.stringify(decal))); + + return clonedWall; + }, + updateDecal: (decalUuid, decal) => { let affectedWall: Wall | undefined; set((state) => { for (const wall of state.walls) { - const decalToUpdate = wall.decals.find(d => d.decalUuid === decalUuid); + const decalToUpdate = wall.decals.find((d) => d.decalUuid === decalUuid); if (decalToUpdate) { Object.assign(decalToUpdate, decal); affectedWall = JSON.parse(JSON.stringify(wall)); @@ -109,13 +149,27 @@ export const createWallStore = () => { return affectedWall; }, + peekUpdateDecal: (decalUuid, decal) => { + const wall = get().walls.find((w) => w.decals.some((d) => d.decalUuid === decalUuid)); + if (!wall) return undefined; + + const clonedWall: Wall = JSON.parse(JSON.stringify(wall)); + + const decalToUpdate = clonedWall.decals.find((d) => d.decalUuid === decalUuid); + if (decalToUpdate) { + Object.assign(decalToUpdate, decal); + } + + return clonedWall; + }, + removeDecal: (decalUuid) => { let affectedWall: Wall | undefined; set((state) => { for (const wall of state.walls) { - const hasDecal = wall.decals.some(d => d.decalUuid === decalUuid); + const hasDecal = wall.decals.some((d) => d.decalUuid === decalUuid); if (hasDecal) { - wall.decals = wall.decals.filter(d => d.decalUuid !== decalUuid); + wall.decals = wall.decals.filter((d) => d.decalUuid !== decalUuid); affectedWall = JSON.parse(JSON.stringify(wall)); } } @@ -127,42 +181,44 @@ export const createWallStore = () => { let affectedWall: Wall | undefined; set((state) => { for (const wall of state.walls) { - const decal = wall.decals.find(d => d.decalUuid === decalUuid); + const decal = wall.decals.find((d) => d.decalUuid === decalUuid); if (decal) { decal.decalPosition = position; affectedWall = JSON.parse(JSON.stringify(wall)); break; } } - }) + }); return affectedWall; }, - updateDecalRotation: (decalUuid, rotation) => set((state) => { - for (const wall of state.walls) { - const decal = wall.decals.find(d => d.decalUuid === decalUuid); - if (decal) { - decal.decalRotation = rotation; - break; + updateDecalRotation: (decalUuid, rotation) => + set((state) => { + for (const wall of state.walls) { + const decal = wall.decals.find((d) => d.decalUuid === decalUuid); + if (decal) { + decal.decalRotation = rotation; + break; + } } - } - }), + }), - updateDecalScale: (decalUuid, scale) => set((state) => { - for (const wall of state.walls) { - const decal = wall.decals.find(d => d.decalUuid === decalUuid); - if (decal) { - decal.decalScale = scale; - break; + updateDecalScale: (decalUuid, scale) => + set((state) => { + for (const wall of state.walls) { + const decal = wall.decals.find((d) => d.decalUuid === decalUuid); + if (decal) { + decal.decalScale = scale; + break; + } } - } - }), + }), removePoint: (pointUuid) => { const removedWalls: Wall[] = []; set((state) => { state.walls = state.walls.filter((wall) => { - const hasPoint = wall.points.some(p => p.pointUuid === pointUuid); + const hasPoint = wall.points.some((p) => p.pointUuid === pointUuid); if (hasPoint) { removedWalls.push(JSON.parse(JSON.stringify(wall))); return false; @@ -173,11 +229,17 @@ export const createWallStore = () => { return removedWalls; }, + peekRemovePoint: (pointUuid) => { + const wallsToRemove = get().walls.filter((wall) => wall.points.some((p) => p.pointUuid === pointUuid)); + + return wallsToRemove.map((w) => JSON.parse(JSON.stringify(w))); + }, + setPosition: (pointUuid, position) => { let updatedWalls: Wall[] = []; set((state) => { for (const wall of state.walls) { - const point = wall.points.find(p => p.pointUuid === pointUuid); + const point = wall.points.find((p) => p.pointUuid === pointUuid); if (point) { point.position = position; updatedWalls.push(wall); @@ -187,49 +249,52 @@ export const createWallStore = () => { return updatedWalls; }, - setLayer: (pointUuid, layer) => set((state) => { - for (const wall of state.walls) { - const point = wall.points.find(p => p.pointUuid === pointUuid); - if (point) { - point.layer = layer; + setLayer: (pointUuid, layer) => + set((state) => { + for (const wall of state.walls) { + const point = wall.points.find((p) => p.pointUuid === pointUuid); + if (point) { + point.layer = layer; + } } - } - }), + }), - getWallById: (uuid) => { - return get().walls.find(w => w.wallUuid === uuid); + getWallById: (wallUuid) => { + return get().walls.find((w) => w.wallUuid === wallUuid); }, - getWallsByPointId: (uuid) => { + getWallsByPointId: (wallUuid) => { return get().walls.filter((a) => { - return JSON.parse(JSON.stringify(a.points.some((p) => p.pointUuid === uuid))); - }) + return JSON.parse(JSON.stringify(a.points.some((p) => p.pointUuid === wallUuid))); + }); }, getWallByPoints: (point) => { for (const wall of get().walls) { - if (((wall.points[0].pointUuid === point[0].pointUuid) || (wall.points[1].pointUuid === point[0].pointUuid)) && - ((wall.points[0].pointUuid === point[1].pointUuid) || (wall.points[1].pointUuid === point[1].pointUuid))) { + if ( + (wall.points[0].pointUuid === point[0].pointUuid || wall.points[1].pointUuid === point[0].pointUuid) && + (wall.points[0].pointUuid === point[1].pointUuid || wall.points[1].pointUuid === point[1].pointUuid) + ) { return wall; } } return undefined; }, - getWallPointById: (uuid) => { + getWallPointById: (wallUuid) => { for (const wall of get().walls) { - const point = wall.points.find(p => p.pointUuid === uuid); + const point = wall.points.find((p) => p.pointUuid === wallUuid); if (point) return point; } return undefined; }, - getConnectedPoints: (uuid) => { + getConnectedPoints: (wallUuid) => { const connected: Point[] = []; for (const wall of get().walls) { for (const point of wall.points) { - if (point.pointUuid === uuid) { - connected.push(...wall.points.filter(p => p.pointUuid !== uuid)); + if (point.pointUuid === wallUuid) { + connected.push(...wall.points.filter((p) => p.pointUuid !== wallUuid)); } } } @@ -237,19 +302,18 @@ export const createWallStore = () => { }, getConnectedWallsByWallId: (wallUuid, skipSelf) => { - const wall = get().walls.find(w => w.wallUuid === wallUuid); + const wall = get().walls.find((w) => w.wallUuid === wallUuid); if (!wall) return []; - const pointUuids = wall.points.map(p => p.pointUuid); + const pointUuids = wall.points.map((p) => p.pointUuid); - return get().walls.filter(w => { + return get().walls.filter((w) => { if (skipSelf && w.wallUuid === wallUuid) return false; - return w.points.some(p => pointUuids.includes(p.pointUuid)); + return w.points.some((p) => pointUuids.includes(p.pointUuid)); }); }, - })) - ) -} + ); +}; -export type WallStoreType = ReturnType; \ No newline at end of file +export type WallStoreType = ReturnType;