Merge branch 'main-dev' into dev-refactor
This commit is contained in:
@@ -127,6 +127,7 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
|
||||
if (!projectId) return;
|
||||
try {
|
||||
const projects = await getAllProjects(userId, organization);
|
||||
if (!projects || !projects.Projects) return;
|
||||
// console.log("projects: ", projects);
|
||||
let projectUuid = projects.Projects.find(
|
||||
(val: any) => val.projectUuid === projectId || val._id === projectId
|
||||
|
||||
@@ -34,6 +34,7 @@ const DashboardProjects: React.FC = () => {
|
||||
const fetchAllProjects = async () => {
|
||||
try {
|
||||
const projects = await getAllProjects(userId, organization);
|
||||
if (!projects || !projects.Projects) return;
|
||||
|
||||
if (JSON.stringify(projects) !== JSON.stringify(workspaceProjects)) {
|
||||
setWorkspaceProjects(projects);
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
useLoadingProgress,
|
||||
useRenameModeStore,
|
||||
useSaveVersion,
|
||||
useSelectedComment,
|
||||
useSelectedFloorItem,
|
||||
useSocketStore,
|
||||
useWidgetSubOption,
|
||||
@@ -39,6 +40,7 @@ import { useVersionHistoryStore } from "../../../store/builder/useVersionHistory
|
||||
import { useVersionContext } from "../../../modules/builder/version/versionContext";
|
||||
import VersionSaved from "../sidebarRight/versionHisory/VersionSaved";
|
||||
import Footer from "../../footer/Footer";
|
||||
import ThreadChat from "../../ui/collaboration/ThreadChat";
|
||||
|
||||
function MainScene() {
|
||||
const { setMainProduct } = useMainProduct();
|
||||
@@ -64,6 +66,7 @@ function MainScene() {
|
||||
const { versionHistory } = useVersionHistoryStore();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion, setSelectedVersion } = selectedVersionStore();
|
||||
const { selectedComment, commentPositionState } = useSelectedComment();
|
||||
|
||||
useEffect(() => {
|
||||
if (activeModule !== 'simulation') {
|
||||
@@ -185,6 +188,7 @@ function MainScene() {
|
||||
{activeModule !== "market" && !selectedUser && <Footer />}
|
||||
|
||||
<VersionSaved />
|
||||
{(commentPositionState !== null || selectedComment !== null) && <ThreadChat/>}
|
||||
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -5,16 +5,25 @@ import FileMenu from "../../ui/FileMenu";
|
||||
import { useToggleStore } from "../../../store/useUIToggleStore";
|
||||
import useModuleStore from "../../../store/useModuleStore";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import useRestStates from "../../../hooks/useResetStates";
|
||||
|
||||
const Header: React.FC = () => {
|
||||
const { toggleUILeft, toggleUIRight, setToggleUI } = useToggleStore();
|
||||
const { activeModule } = useModuleStore();
|
||||
const navigate = useNavigate();
|
||||
const { resetStates } = useRestStates();
|
||||
|
||||
return (
|
||||
<div className="header-container">
|
||||
<div className="header-content">
|
||||
<button className="logo-container" onClick={() => navigate("/Dashboard")} title="Back to Dashboard">
|
||||
<button
|
||||
className="logo-container"
|
||||
onClick={() => {
|
||||
resetStates();
|
||||
navigate("/Dashboard")
|
||||
}}
|
||||
title="Back to Dashboard"
|
||||
>
|
||||
<LogoIcon />
|
||||
</button>
|
||||
<div className="header-title">
|
||||
|
||||
@@ -23,6 +23,7 @@ const LoadingPage: React.FC<LoadingPageProps> = ({ progress }) => {
|
||||
if (!userId) return;
|
||||
|
||||
getAllProjects(userId, organization).then((projects) => {
|
||||
if (!projects || !projects.Projects) return;
|
||||
const filterProject = projects?.Projects.find((val: any) => val.projectUuid === projectId || val._id === projectId);
|
||||
if (filterProject) {
|
||||
setProjectName(filterProject.projectName);
|
||||
|
||||
@@ -51,6 +51,7 @@ const FileMenu: React.FC = () => {
|
||||
if (!email || !userId) return;
|
||||
|
||||
const projects = await getAllProjects(userId, organization);
|
||||
if (!projects || !projects.Projects) return;
|
||||
// console.log('projects: ', projects);
|
||||
let projectUuid = projects.Projects.find((val: any) => val.projectUuid === projectId || val._id === projectId)
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useCommentStore } from "../../../store/collaboration/useCommentStore";
|
||||
import { useSelectedComment, useSocketStore } from "../../../store/builder/store";
|
||||
import { getRelativeTime } from "./function/getRelativeTime";
|
||||
import { editThreadTitleApi } from "../../../services/factoryBuilder/comments/editThreadTitleApi";
|
||||
import { useVersionContext } from "../../../modules/builder/version/versionContext";
|
||||
|
||||
|
||||
interface MessageProps {
|
||||
@@ -34,8 +35,9 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
|
||||
const { threadSocket } = useSocketStore();
|
||||
const { userName, userId, organization } = getUserData();
|
||||
const [isEditComment, setIsEditComment] = useState(false)
|
||||
|
||||
const { selectedComment, setCommentPositionState } = useSelectedComment();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
|
||||
// input
|
||||
const [value, setValue] = useState<string>(
|
||||
@@ -59,11 +61,11 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
|
||||
|
||||
const handleSaveAction = async () => {
|
||||
|
||||
if (!projectId) return
|
||||
if (!projectId || !selectedVersion) return
|
||||
|
||||
if (isEditableThread && editedThread) {
|
||||
try {
|
||||
// const editThreadTitle = await editThreadTitleApi(projectId, (val as CommentSchema).threadId, value)
|
||||
// const editThreadTitle = await editThreadTitleApi(projectId, (val as CommentSchema).threadId, value, selectedVersion?.versionId || "")
|
||||
// if (editThreadTitle.message == "ThreadTitle updated Successfully") {
|
||||
// const editedThread: CommentSchema = {
|
||||
// state: 'active',
|
||||
@@ -74,7 +76,7 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
|
||||
// lastUpdatedAt: new Date().toISOString(),
|
||||
// position: editThreadTitle.data.position,
|
||||
// rotation: [0, 0, 0],
|
||||
// comments: []
|
||||
// comments: [],
|
||||
// }
|
||||
// updateComment((val as CommentSchema).threadId, editedThread)
|
||||
// }
|
||||
@@ -84,17 +86,17 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
|
||||
userId,
|
||||
threadTitle: value,
|
||||
organization,
|
||||
threadId: (val as CommentSchema).threadId
|
||||
threadId: (val as CommentSchema).threadId || selectedComment.threadId,
|
||||
versionId: selectedVersion?.versionId || ""
|
||||
}
|
||||
|
||||
threadSocket.emit('v1:thread:updateTitle', threadEdit)
|
||||
} catch {
|
||||
}
|
||||
} else {
|
||||
|
||||
if (mode === "edit") {
|
||||
try {
|
||||
// const editComments = await addCommentsApi(projectId, value, selectedComment?.threadId, (val as Reply).replyId)
|
||||
// const editComments = await addCommentsApi(projectId, value, selectedComment?.threadId, (val as Reply).replyId, selectedVersion?.versionId || "")
|
||||
//
|
||||
// const commentData = {
|
||||
// replyId: `${editComments.data?.replyId}`,
|
||||
@@ -114,7 +116,8 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
|
||||
comment: value,
|
||||
organization,
|
||||
threadId: selectedComment?.threadId,
|
||||
commentId: (val as Reply).replyId ?? ""
|
||||
commentId: (val as Reply).replyId ?? "",
|
||||
versionId: selectedVersion?.versionId || ""
|
||||
}
|
||||
|
||||
|
||||
@@ -133,10 +136,10 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
|
||||
}
|
||||
|
||||
const handleDeleteAction = async (replyID: any) => {
|
||||
if (!projectId) return
|
||||
if (!projectId || !selectedVersion) return
|
||||
setOpenOptions(false);
|
||||
try {
|
||||
// const deletedComment = await deleteCommentApi(projectId, selectedComment?.threadId, (val as Reply).replyId)
|
||||
// const deletedComment = await deleteCommentApi(projectId, selectedComment?.threadId, (val as Reply).replyId , selectedVersion?.versionId || "")
|
||||
//
|
||||
// if (deletedComment === "'Thread comment deleted Successfully'") {
|
||||
// setMessages && setMessages(prev => prev.filter(message => message.replyId !== replyID));
|
||||
@@ -151,13 +154,16 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
|
||||
userId,
|
||||
commentId: (val as Reply).replyId,
|
||||
organization,
|
||||
threadId: selectedComment?.threadId
|
||||
threadId: selectedComment?.threadId,
|
||||
versionId: selectedVersion?.versionId || ""
|
||||
}
|
||||
|
||||
|
||||
setMessages(prev => prev.filter(message => message.replyId !== (val as Reply).replyId))
|
||||
|
||||
setMessages(prev => {
|
||||
// 👈 logs the current state
|
||||
return prev.filter(message => message.replyId !== (val as Reply).replyId);
|
||||
});
|
||||
removeReply(selectedComment?.threadId, (val as Reply).replyId); // Remove listener after response
|
||||
|
||||
|
||||
threadSocket.emit("v1-Comment:delete", deleteComment);
|
||||
}
|
||||
} catch {
|
||||
@@ -173,7 +179,7 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{isEditComment ? (
|
||||
|
||||
@@ -12,7 +12,7 @@ import { addCommentsApi } from "../../../services/factoryBuilder/comments/addCom
|
||||
import { deleteThreadApi } from "../../../services/factoryBuilder/comments/deleteThreadApi";
|
||||
import { createThreadApi } from "../../../services/factoryBuilder/comments/createThreadApi";
|
||||
import { getRelativeTime } from "./function/getRelativeTime";
|
||||
|
||||
import { useVersionContext } from "../../../modules/builder/version/versionContext";
|
||||
|
||||
const ThreadChat: React.FC = () => {
|
||||
const { userId, organization } = getUserData();
|
||||
@@ -35,6 +35,8 @@ const ThreadChat: React.FC = () => {
|
||||
const { threadSocket } = useSocketStore();
|
||||
const modeRef = useRef<'create' | 'edit' | null>(null);
|
||||
const messagesRef = useRef<HTMLDivElement>(null);
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
|
||||
useEffect(() => {
|
||||
modeRef.current = mode;
|
||||
@@ -42,7 +44,6 @@ const ThreadChat: React.FC = () => {
|
||||
|
||||
useEffect(() => {
|
||||
if (comments.length > 0 && selectedComment) {
|
||||
|
||||
|
||||
const allMessages = comments
|
||||
.flatMap((val: any) =>
|
||||
@@ -50,20 +51,20 @@ const ThreadChat: React.FC = () => {
|
||||
)
|
||||
.map((c) => {
|
||||
return {
|
||||
replyId: c._id ?? "",
|
||||
replyId: c._id ?? c.replyId,
|
||||
creatorId: c.creatorId || c.userId,
|
||||
createdAt: c.createdAt,
|
||||
lastUpdatedAt: "1 hr ago",
|
||||
comment: c.comment,
|
||||
_id: c._id ?? "",
|
||||
_id: c._id ?? c.replyId,
|
||||
};
|
||||
});
|
||||
|
||||
setMessages(allMessages);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}, [selectedComment])
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (textareaRef.current) adjustHeight(textareaRef.current);
|
||||
@@ -145,7 +146,7 @@ const ThreadChat: React.FC = () => {
|
||||
const handleCreateComments = async (e: any) => {
|
||||
e.preventDefault();
|
||||
try {
|
||||
// const createComments = await addCommentsApi(projectId, value, selectedComment?.threadId)/
|
||||
// const createComments = await addCommentsApi(projectId, value, selectedComment?.threadId, selectedVersion?.versionId || "")/
|
||||
// if (createComments.message === 'Thread comments add Successfully' && createComments.data) {
|
||||
// const commentData = {
|
||||
// replyId: `${createComments.data?._id}`,
|
||||
@@ -164,11 +165,13 @@ const ThreadChat: React.FC = () => {
|
||||
|
||||
if (threadSocket && mode === "create") {
|
||||
const addComment = {
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
projectId,
|
||||
userId,
|
||||
comment: value,
|
||||
organization,
|
||||
threadId: selectedComment?.threadId
|
||||
threadId: selectedComment?.threadId,
|
||||
|
||||
}
|
||||
|
||||
threadSocket.emit("v1-Comment:add", addComment);
|
||||
@@ -181,21 +184,22 @@ const ThreadChat: React.FC = () => {
|
||||
const handleDeleteThread = async () => {
|
||||
if (!projectId) return;
|
||||
try {
|
||||
// const deleteThread = await deleteThreadApi(projectId, selectedComment?.threadId)
|
||||
// const deleteThread = await deleteThreadApi(projectId, selectedComment?.threadId, selectedVersion?.versionId || "")
|
||||
//
|
||||
// if (deleteThread.message === "Thread deleted Successfully") {
|
||||
// removeComment(selectedComment?.threadId)
|
||||
// setSelectedComment([])
|
||||
// }
|
||||
console.log('threadSocket:threadChat ', threadSocket);
|
||||
if (threadSocket) {
|
||||
// projectId, userId, organization, threadId
|
||||
const deleteThread = {
|
||||
projectId,
|
||||
userId,
|
||||
organization,
|
||||
threadId: selectedComment?.threadId
|
||||
threadId: selectedComment?.threadId,
|
||||
versionId: selectedVersion?.versionId || ""
|
||||
}
|
||||
|
||||
setSelectedComment(null)
|
||||
removeComment(selectedComment?.threadId)
|
||||
threadSocket.emit("v1:thread:delete", deleteThread);
|
||||
@@ -213,11 +217,12 @@ const ThreadChat: React.FC = () => {
|
||||
try {
|
||||
// try {
|
||||
// const thread = await createThreadApi(
|
||||
// projectId,
|
||||
// "active",
|
||||
// commentPositionState[0].position,
|
||||
// [0, 0, 0],
|
||||
// value
|
||||
// projectId,
|
||||
// "active",
|
||||
// commentPositionState[0].position,
|
||||
// [0, 0, 0],
|
||||
// value,
|
||||
// selectedVersion?.versionId || ""
|
||||
// );
|
||||
//
|
||||
//
|
||||
@@ -243,18 +248,17 @@ const ThreadChat: React.FC = () => {
|
||||
|
||||
const createThread = {
|
||||
projectId,
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
userId,
|
||||
organization,
|
||||
state: "active",
|
||||
position: commentPositionState.position,
|
||||
rotation: [0, 0, 0],
|
||||
threadTitle: value
|
||||
threadTitle: value,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
if (threadSocket) {
|
||||
console.log('createThread: ', createThread);
|
||||
|
||||
setInputActive(false);
|
||||
threadSocket.emit("v1:thread:create", createThread);
|
||||
|
||||
@@ -22,7 +22,7 @@ export const getUserData = (): UserData => {
|
||||
const [_, emailDomain] = email.split("@");
|
||||
|
||||
if (!emailDomain) {
|
||||
throw new Error("Invalid email format");
|
||||
console.error("Invalid email format");
|
||||
}
|
||||
|
||||
const [organization] = emailDomain.split(".");
|
||||
|
||||
26
app/src/hooks/useResetStates.ts
Normal file
26
app/src/hooks/useResetStates.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { useVersionContext } from "../modules/builder/version/versionContext";
|
||||
import { useSceneContext } from "../modules/scene/sceneContext";
|
||||
import { useProductContext } from "../modules/simulation/products/productContext";
|
||||
import { useVersionHistoryStore } from "../store/builder/useVersionHistoryStore";
|
||||
|
||||
const useRestStates = () => {
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { clearSelectedVersion } = selectedVersionStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { clearSelectedProduct } = selectedProductStore();
|
||||
const { clearVersions } = useVersionHistoryStore();
|
||||
const { clearStores } = useSceneContext();
|
||||
|
||||
const resetStates = () => {
|
||||
clearSelectedVersion();
|
||||
clearSelectedProduct();
|
||||
clearVersions();
|
||||
clearStores();
|
||||
};
|
||||
|
||||
return {
|
||||
resetStates,
|
||||
};
|
||||
};
|
||||
|
||||
export default useRestStates;
|
||||
@@ -16,7 +16,7 @@ async function loadInitialWallItems(
|
||||
const { organization, email } = getUserData();
|
||||
|
||||
if (!email) {
|
||||
throw new Error("No email found in localStorage");
|
||||
console.error("No email found in localStorage");
|
||||
}
|
||||
|
||||
const items = await getWallItems(organization, projectId, versionId);
|
||||
|
||||
@@ -48,14 +48,11 @@ function AisleInstances() {
|
||||
|
||||
{toggleView &&
|
||||
<Html
|
||||
// data
|
||||
key={`${aisle.points[0].pointUuid}_${aisle.points[1].pointUuid}`}
|
||||
userData={aisle}
|
||||
position={[textPosition.x, 1, textPosition.z]}
|
||||
// class
|
||||
wrapperClass="distance-text-wrapper"
|
||||
className="distance-text"
|
||||
// other
|
||||
zIndexRange={[1, 0]}
|
||||
prepend
|
||||
sprite
|
||||
@@ -68,7 +65,6 @@ function AisleInstances() {
|
||||
</div>
|
||||
</Html>
|
||||
}
|
||||
|
||||
</React.Fragment>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -104,7 +104,7 @@ export default function Builder() {
|
||||
const { setWalls } = useWalls();
|
||||
const { refTextupdate, setRefTextUpdate } = useRefTextUpdate();
|
||||
const { projectId } = useParams();
|
||||
const { setHoveredPoint } = useBuilderStore();
|
||||
const { setHoveredPoint, setHoveredLine } = useBuilderStore();
|
||||
const { userId, organization } = getUserData();
|
||||
|
||||
// const loader = new GLTFLoader();
|
||||
@@ -127,7 +127,9 @@ export default function Builder() {
|
||||
dragPointControls
|
||||
);
|
||||
} else {
|
||||
setHoveredLine(null);
|
||||
setHoveredPoint(null);
|
||||
state.gl.domElement.style.cursor = 'default';
|
||||
setToolMode('cursor');
|
||||
loadWalls(lines, setWalls);
|
||||
setUpdateScene(true);
|
||||
|
||||
@@ -123,7 +123,7 @@ function loadOnlyFloors(
|
||||
const originalPoint = originalLines.flat().find(([point]) => point.x === x && point.z === z);
|
||||
|
||||
if (!originalPoint) {
|
||||
throw new Error(`Original point for coordinate [${x}, ${z}] not found.`);
|
||||
console.error(`Original point for coordinate [${x}, ${z}] not found.`);
|
||||
}
|
||||
|
||||
return originalPoint;
|
||||
|
||||
@@ -39,7 +39,7 @@ const ZoneGroup: React.FC = () => {
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { projectId } = useParams();
|
||||
const { userId, organization, email } = getUserData();
|
||||
const { userId, organization } = getUserData();
|
||||
|
||||
const groupsRef = useRef<any>();
|
||||
|
||||
@@ -384,13 +384,7 @@ const ZoneGroup: React.FC = () => {
|
||||
drag = true;
|
||||
}
|
||||
raycaster.setFromCamera(pointer, camera);
|
||||
const intersects = raycaster.intersectObjects(groupsRef.current.children, true);
|
||||
|
||||
if (intersects.length > 0 && intersects[0].object.name.includes("point")) {
|
||||
gl.domElement.style.cursor = toolMode === "move" ? "pointer" : "default";
|
||||
} else {
|
||||
gl.domElement.style.cursor = "default";
|
||||
}
|
||||
if (isDragging && draggedSphere) {
|
||||
raycaster.setFromCamera(pointer, camera);
|
||||
const intersectionPoint = new THREE.Vector3();
|
||||
|
||||
@@ -1,13 +1,26 @@
|
||||
import * as THREE from 'three';
|
||||
import { useMemo } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import * as Constants from '../../../types/world/worldConstants';
|
||||
import { Tube } from '@react-three/drei';
|
||||
import { DragControls, Tube } from '@react-three/drei';
|
||||
import { useToolMode } from '../../../store/builder/store';
|
||||
import { useBuilderStore } from '../../../store/builder/useBuilderStore';
|
||||
import { useWallStore } from '../../../store/builder/useWallStore';
|
||||
import { useThree } from '@react-three/fiber';
|
||||
|
||||
interface LineProps {
|
||||
points: [Point, Point];
|
||||
}
|
||||
|
||||
function Line({ points }: Readonly<LineProps>) {
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const { raycaster, camera, pointer, gl } = useThree();
|
||||
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
|
||||
const [isDeletable, setIsDeletable] = useState(false);
|
||||
const { toolMode } = useToolMode();
|
||||
const { removeWallByPoints, setPosition } = useWallStore();
|
||||
const [dragOffset, setDragOffset] = useState<THREE.Vector3 | null>(null);
|
||||
const { hoveredLine, setHoveredLine, hoveredPoint } = useBuilderStore();
|
||||
|
||||
const path = useMemo(() => {
|
||||
const [start, end] = points.map(p => new THREE.Vector3(...p.position));
|
||||
return new THREE.LineCurve3(start, end);
|
||||
@@ -44,16 +57,119 @@ function Line({ points }: Readonly<LineProps>) {
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (toolMode === '2D-Delete') {
|
||||
if (isHovered && !hoveredPoint) {
|
||||
setIsDeletable(true);
|
||||
} else {
|
||||
setIsDeletable(false);
|
||||
}
|
||||
} else {
|
||||
setIsDeletable(false);
|
||||
}
|
||||
}, [isHovered, colors.defaultLineColor, colors.defaultDeleteColor, toolMode, hoveredPoint]);
|
||||
|
||||
useEffect(() => {
|
||||
if (hoveredLine && (hoveredLine[0].pointUuid !== points[0].pointUuid || hoveredLine[1].pointUuid !== points[1].pointUuid)) {
|
||||
setIsHovered(false);
|
||||
}
|
||||
}, [hoveredLine])
|
||||
|
||||
const handlePointClick = (points: [Point, Point]) => {
|
||||
if (toolMode === '2D-Delete') {
|
||||
if (points[0].pointType === 'Wall' && points[1].pointType === 'Wall') {
|
||||
removeWallByPoints(points);
|
||||
}
|
||||
gl.domElement.style.cursor = 'default';
|
||||
}
|
||||
}
|
||||
|
||||
const handleDrag = (points: [Point, Point]) => {
|
||||
if (toolMode === 'move' && isHovered && dragOffset) {
|
||||
raycaster.setFromCamera(pointer, camera);
|
||||
const intersectionPoint = new THREE.Vector3();
|
||||
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||
|
||||
if (hit) {
|
||||
gl.domElement.style.cursor = 'move';
|
||||
const positionWithOffset = new THREE.Vector3().addVectors(hit, dragOffset);
|
||||
|
||||
const start = new THREE.Vector3(...points[0].position);
|
||||
const end = new THREE.Vector3(...points[1].position);
|
||||
const midPoint = new THREE.Vector3().addVectors(start, end).multiplyScalar(0.5);
|
||||
|
||||
const delta = new THREE.Vector3().subVectors(positionWithOffset, midPoint);
|
||||
|
||||
const newStart = new THREE.Vector3().addVectors(start, delta);
|
||||
const newEnd = new THREE.Vector3().addVectors(end, delta);
|
||||
|
||||
setPosition(points[0].pointUuid, [newStart.x, newStart.y, newStart.z]);
|
||||
setPosition(points[1].pointUuid, [newEnd.x, newEnd.y, newEnd.z]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleDragStart = (points: [Point, Point]) => {
|
||||
raycaster.setFromCamera(pointer, camera);
|
||||
const intersectionPoint = new THREE.Vector3();
|
||||
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||
|
||||
if (hit && !hoveredPoint) {
|
||||
const start = new THREE.Vector3(...points[0].position);
|
||||
const end = new THREE.Vector3(...points[1].position);
|
||||
const midPoint = new THREE.Vector3().addVectors(start, end).multiplyScalar(0.5);
|
||||
|
||||
const offset = new THREE.Vector3().subVectors(midPoint, hit);
|
||||
setDragOffset(offset);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDragEnd = (points: [Point, Point]) => {
|
||||
gl.domElement.style.cursor = 'default';
|
||||
setDragOffset(null);
|
||||
if (toolMode !== 'move') return;
|
||||
if (points[0].pointType === 'Wall' && points[1].pointType === 'Wall') {
|
||||
// console.log('Wall after drag: ', points);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Tube
|
||||
name={`${points[0].pointType}-Line`}
|
||||
key={`${points[0].pointUuid}-${points[1].pointUuid}`}
|
||||
uuid={`${points[0].pointUuid}-${points[1].pointUuid}`}
|
||||
userData={{ points, path }}
|
||||
args={[path, Constants.lineConfig.tubularSegments, Constants.lineConfig.radius, Constants.lineConfig.radialSegments, false]}
|
||||
<DragControls
|
||||
axisLock="y"
|
||||
autoTransform={false}
|
||||
onDragStart={() => handleDragStart(points)}
|
||||
onDrag={() => handleDrag(points)}
|
||||
onDragEnd={() => handleDragEnd(points)}
|
||||
>
|
||||
<meshStandardMaterial color={colors.defaultLineColor} />
|
||||
</Tube>
|
||||
<Tube
|
||||
name={`${points[0].pointType}-Line`}
|
||||
key={`${points[0].pointUuid}-${points[1].pointUuid}`}
|
||||
uuid={`${points[0].pointUuid}-${points[1].pointUuid}`}
|
||||
userData={{ points, path }}
|
||||
args={[path, Constants.lineConfig.tubularSegments, Constants.lineConfig.radius, Constants.lineConfig.radialSegments, false]}
|
||||
onClick={() => {
|
||||
handlePointClick(points);
|
||||
}}
|
||||
onPointerOver={() => {
|
||||
if (!hoveredLine) {
|
||||
setHoveredLine(points);
|
||||
setIsHovered(true)
|
||||
if (toolMode === 'move' && !hoveredPoint) {
|
||||
gl.domElement.style.cursor = 'pointer';
|
||||
}
|
||||
}
|
||||
}}
|
||||
onPointerOut={() => {
|
||||
if (hoveredLine) {
|
||||
setHoveredLine(null);
|
||||
gl.domElement.style.cursor = 'default';
|
||||
}
|
||||
setIsHovered(false)
|
||||
}}
|
||||
>
|
||||
<meshStandardMaterial color={isDeletable ? colors.defaultDeleteColor : colors.defaultLineColor} />
|
||||
</Tube>
|
||||
</DragControls >
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,10 @@ import { useSceneContext } from '../../scene/sceneContext';
|
||||
|
||||
function Point({ point }: { readonly point: Point }) {
|
||||
const materialRef = useRef<THREE.ShaderMaterial>(null);
|
||||
const { raycaster, camera, pointer } = useThree();
|
||||
const { raycaster, camera, pointer, gl } = useThree();
|
||||
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const [dragOffset, setDragOffset] = useState<THREE.Vector3 | null>(null);
|
||||
const { toolMode } = useToolMode();
|
||||
const { aisleStore } = useSceneContext();
|
||||
const { setPosition: setAislePosition, removePoint: removeAislePoint, getAislesByPointId } = aisleStore();
|
||||
@@ -91,33 +92,45 @@ function Point({ point }: { readonly point: Point }) {
|
||||
}), [colors.defaultInnerColor, colors.defaultOuterColor]);
|
||||
|
||||
const handleDrag = (point: Point) => {
|
||||
if (toolMode === 'move' && isHovered) {
|
||||
if (toolMode === 'move' && isHovered && dragOffset) {
|
||||
raycaster.setFromCamera(pointer, camera);
|
||||
const intersectionPoint = new THREE.Vector3();
|
||||
const position = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||
if (point.pointType === 'Aisle') {
|
||||
if (position) {
|
||||
const newPosition: [number, number, number] = [position.x, position.y, position.z];
|
||||
const aisleSnappedPosition = snapAisleAngle(newPosition);
|
||||
const finalSnappedPosition = snapAislePoint(aisleSnappedPosition.position);
|
||||
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||
|
||||
setAislePosition(point.pointUuid, finalSnappedPosition.position);
|
||||
if (hit) {
|
||||
gl.domElement.style.cursor = 'move';
|
||||
const positionWithOffset = new THREE.Vector3().addVectors(hit, dragOffset);
|
||||
const newPosition: [number, number, number] = [positionWithOffset.x, positionWithOffset.y, positionWithOffset.z];
|
||||
|
||||
}
|
||||
} else if (point.pointType === 'Wall') {
|
||||
if (position) {
|
||||
const newPosition: [number, number, number] = [position.x, position.y, position.z];
|
||||
const wallSnappedPosition = snapWallAngle(newPosition);
|
||||
const finalSnappedPosition = snapWallPoint(wallSnappedPosition.position);
|
||||
|
||||
setWallPosition(point.pointUuid, finalSnappedPosition.position);
|
||||
if (point.pointType === 'Aisle') {
|
||||
const aisleSnapped = snapAisleAngle(newPosition);
|
||||
const finalSnapped = snapAislePoint(aisleSnapped.position);
|
||||
setAislePosition(point.pointUuid, finalSnapped.position);
|
||||
} else if (point.pointType === 'Wall') {
|
||||
const wallSnapped = snapWallAngle(newPosition);
|
||||
const finalSnapped = snapWallPoint(wallSnapped.position);
|
||||
setWallPosition(point.pointUuid, finalSnapped.position);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleDragStart = (point: Point) => {
|
||||
raycaster.setFromCamera(pointer, camera);
|
||||
const intersectionPoint = new THREE.Vector3();
|
||||
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||
|
||||
if (hit) {
|
||||
const currentPosition = new THREE.Vector3(...point.position);
|
||||
const offset = new THREE.Vector3().subVectors(currentPosition, hit);
|
||||
setDragOffset(offset);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDragEnd = (point: Point) => {
|
||||
if (toolMode === '2D-Delete') return;
|
||||
gl.domElement.style.cursor = 'default';
|
||||
setDragOffset(null);
|
||||
if (toolMode !== 'move') return;
|
||||
if (point.pointType === 'Aisle') {
|
||||
const updatedAisles = getAislesByPointId(point.pointUuid);
|
||||
if (updatedAisles.length > 0 && projectId) {
|
||||
@@ -148,6 +161,7 @@ function Point({ point }: { readonly point: Point }) {
|
||||
setHoveredPoint(null);
|
||||
}
|
||||
}
|
||||
gl.domElement.style.cursor = 'default';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,8 +179,9 @@ function Point({ point }: { readonly point: Point }) {
|
||||
<DragControls
|
||||
axisLock='y'
|
||||
autoTransform={false}
|
||||
onDrag={() => { handleDrag(point) }}
|
||||
onDragEnd={() => { handleDragEnd(point) }}
|
||||
onDragStart={() => handleDragStart(point)}
|
||||
onDrag={() => handleDrag(point)}
|
||||
onDragEnd={() => handleDragEnd(point)}
|
||||
>
|
||||
<mesh
|
||||
key={point.pointUuid}
|
||||
@@ -179,12 +194,16 @@ function Point({ point }: { readonly point: Point }) {
|
||||
onPointerOver={() => {
|
||||
if (!hoveredPoint) {
|
||||
setHoveredPoint(point);
|
||||
setIsHovered(true)
|
||||
setIsHovered(true);
|
||||
if (toolMode === 'move') {
|
||||
gl.domElement.style.cursor = 'pointer';
|
||||
}
|
||||
}
|
||||
}}
|
||||
onPointerOut={() => {
|
||||
if (hoveredPoint) {
|
||||
setHoveredPoint(null);
|
||||
gl.domElement.style.cursor = 'default';
|
||||
}
|
||||
setIsHovered(false)
|
||||
}}
|
||||
|
||||
@@ -120,7 +120,6 @@ export function useWallClassification(walls: Walls) {
|
||||
}
|
||||
});
|
||||
|
||||
console.log('rooms: ', rooms);
|
||||
return rooms;
|
||||
};
|
||||
|
||||
|
||||
@@ -8,17 +8,17 @@ import { useWallStore } from '../../../../../store/builder/useWallStore';
|
||||
import { useWallClassification } from './helpers/useWallClassification';
|
||||
import { useFrame, useThree } from '@react-three/fiber';
|
||||
import { useWallVisibility } from '../../../../../store/builder/store';
|
||||
import { Decal, PivotControls } from '@react-three/drei';
|
||||
import { Base, Geometry, Subtraction } from '@react-three/csg';
|
||||
import { Decal } from '@react-three/drei';
|
||||
import { Base } from '@react-three/csg';
|
||||
|
||||
function Wall({ wall }: { readonly wall: Wall }) {
|
||||
const { walls } = useWallStore();
|
||||
const { getWallType, isWallFlipped } = useWallClassification(walls);
|
||||
const wallType = getWallType(wall);
|
||||
const [visible, setVisible] = useState(true);
|
||||
const { wallVisibility } = useWallVisibility();
|
||||
const meshRef = useRef<any>();
|
||||
const { camera } = useThree();
|
||||
const { wallVisibility } = useWallVisibility();
|
||||
const { getWallType, isWallFlipped } = useWallClassification(walls);
|
||||
const [visible, setVisible] = useState(true);
|
||||
const meshRef = useRef<any>();
|
||||
const wallType = getWallType(wall);
|
||||
|
||||
const wallFlipped = isWallFlipped(wall);
|
||||
|
||||
@@ -84,7 +84,6 @@ function Wall({ wall }: { readonly wall: Wall }) {
|
||||
camera.getWorldDirection(u);
|
||||
if (!u || !v) return;
|
||||
setVisible((2 * v.dot(u)) <= 0.1);
|
||||
|
||||
} else {
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
import React, { useEffect, useMemo, useRef } from 'react';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { DoubleSide, RepeatWrapping, Shape, SRGBColorSpace, TextureLoader, Vector2, Vector3 } from 'three';
|
||||
import { Geometry } from '@react-three/csg';
|
||||
import { Html, Extrude } from '@react-three/drei';
|
||||
import { useWallStore } from '../../../../store/builder/useWallStore'
|
||||
import WallInstance from './instance/wallInstance';
|
||||
import { useWallClassification } from './instance/helpers/useWallClassification';
|
||||
import { useToggleView } from '../../../../store/builder/store';
|
||||
import Line from '../../line/line';
|
||||
import Point from '../../point/point';
|
||||
import { useToggleView } from '../../../../store/builder/store';
|
||||
import { Geometry } from '@react-three/csg';
|
||||
import WallInstance from './instance/wallInstance';
|
||||
import * as Constants from '../../../../types/world/worldConstants';
|
||||
|
||||
import texturePath from "../../../../assets/textures/floor/white.png";
|
||||
import texturePathDark from "../../../../assets/textures/floor/black.png";
|
||||
import { useLoader } from '@react-three/fiber';
|
||||
|
||||
function WallInstances() {
|
||||
const { walls } = useWallStore();
|
||||
const { rooms } = useWallClassification(walls)
|
||||
const { toggleView } = useToggleView();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -32,24 +41,22 @@ function WallInstances() {
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
{!toggleView && (
|
||||
|
||||
<mesh name='Walls-Group'>
|
||||
{/* <Base name="base" geometry={box} scale={[3, 3, 3]} /> */}
|
||||
|
||||
<Geometry useGroups>
|
||||
{walls.map((wall) => (
|
||||
<WallInstance key={wall.wallUuid} wall={wall} />
|
||||
))}
|
||||
</Geometry>
|
||||
|
||||
{/* <Subtraction rotation={[0, Math.PI / 2, 0]} position={[-1.425, -0.45, 0]} scale={[1, 3, 1]}>
|
||||
<Geometry>
|
||||
<Base geometry={box} />
|
||||
<>
|
||||
<mesh name='Walls-Group'>
|
||||
<Geometry useGroups>
|
||||
{walls.map((wall) => (
|
||||
<WallInstance key={wall.wallUuid} wall={wall} />
|
||||
))}
|
||||
</Geometry>
|
||||
</Subtraction> */}
|
||||
</mesh>
|
||||
</mesh>
|
||||
|
||||
<group name='Wall-Floors-Group'>
|
||||
{rooms.map((room, index) => (
|
||||
<Floor key={index} room={room} />
|
||||
))}
|
||||
</group>
|
||||
</>
|
||||
)}
|
||||
|
||||
{toggleView && (
|
||||
@@ -61,11 +68,42 @@ function WallInstances() {
|
||||
</group>
|
||||
|
||||
<group name='Wall-Lines-Group'>
|
||||
|
||||
{walls.map((wall) => (
|
||||
<React.Fragment key={wall.wallUuid}>
|
||||
<Line points={wall.points} />
|
||||
</React.Fragment>
|
||||
))}
|
||||
|
||||
{walls.map((wall) => {
|
||||
const textPosition = new Vector3().addVectors(new Vector3(...wall.points[0].position), new Vector3(...wall.points[1].position)).divideScalar(2);
|
||||
const distance = new Vector3(...wall.points[0].position).distanceTo(new Vector3(...wall.points[1].position));
|
||||
|
||||
return (
|
||||
< React.Fragment key={wall.wallUuid}>
|
||||
{toggleView &&
|
||||
<Html
|
||||
key={`${wall.points[0].pointUuid}_${wall.points[1].pointUuid}`}
|
||||
userData={wall}
|
||||
position={[textPosition.x, 1, textPosition.z]}
|
||||
wrapperClass="distance-text-wrapper"
|
||||
className="distance-text"
|
||||
zIndexRange={[1, 0]}
|
||||
prepend
|
||||
sprite
|
||||
>
|
||||
<div
|
||||
key={wall.wallUuid}
|
||||
className={`distance ${wall.wallUuid}`}
|
||||
>
|
||||
{distance.toFixed(2)} m
|
||||
</div>
|
||||
</Html>
|
||||
}
|
||||
</React.Fragment>
|
||||
)
|
||||
})}
|
||||
|
||||
</group>
|
||||
</>
|
||||
)}
|
||||
@@ -73,4 +111,36 @@ function WallInstances() {
|
||||
)
|
||||
}
|
||||
|
||||
export default WallInstances
|
||||
export default WallInstances;
|
||||
|
||||
function Floor({ room }: { room: Point[] }) {
|
||||
const savedTheme: string | null = localStorage.getItem('theme');
|
||||
const textureScale = Constants.floorConfig.textureScale;
|
||||
const floorTexture = useLoader(TextureLoader, savedTheme === "dark" ? texturePathDark : texturePath);
|
||||
floorTexture.wrapS = floorTexture.wrapT = RepeatWrapping;
|
||||
floorTexture.repeat.set(textureScale, textureScale);
|
||||
floorTexture.colorSpace = SRGBColorSpace;
|
||||
|
||||
const shape = useMemo(() => {
|
||||
const shape = new Shape();
|
||||
const points = room.map(p => new Vector2(p.position[0], p.position[2]));
|
||||
if (points.length < 3) return null;
|
||||
shape.moveTo(points[0].x, points[0].y);
|
||||
points.forEach((pt) => { shape.lineTo(pt.x, pt.y); });
|
||||
return shape;
|
||||
}, [room]);
|
||||
|
||||
if (!shape) return null;
|
||||
|
||||
return (
|
||||
<group name="Wall-Floor" rotation={[Math.PI / 2, 0, 0]}>
|
||||
<Extrude
|
||||
args={[shape, { depth: Constants.floorConfig.height, bevelEnabled: false }]}
|
||||
position={[0, 0, 0]}
|
||||
receiveShadow
|
||||
>
|
||||
<meshStandardMaterial color={Constants.floorConfig.defaultColor} map={floorTexture} side={DoubleSide} />
|
||||
</Extrude>
|
||||
</group>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ function WallCreator() {
|
||||
canvasElement.removeEventListener("click", onMouseClick);
|
||||
canvasElement.removeEventListener("contextmenu", onContext);
|
||||
};
|
||||
}, [gl, camera, scene, raycaster, pointer, plane, toggleView, toolMode, activeLayer, socket, tempPoints, isCreating, addWall, getWallPointById, snappedPosition, snappedPoint]);
|
||||
}, [gl, camera, scene, raycaster, pointer, plane, toggleView, toolMode, activeLayer, socket, tempPoints, isCreating, addWall, getWallPointById, wallThickness, wallHeight, insideMaterial, outsideMaterial, snappedPosition, snappedPoint]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { MathUtils, Vector3 } from "three";
|
||||
import { Vector3 } from "three";
|
||||
import CommentInstances from "./instances/commentInstances";
|
||||
import { Sphere } from "@react-three/drei";
|
||||
import { useActiveTool, useSelectedComment } from "../../../store/builder/store";
|
||||
|
||||
|
||||
function CommentsGroup() {
|
||||
const { gl, raycaster, camera, scene, pointer, size } = useThree();
|
||||
const { activeTool } = useActiveTool();
|
||||
const [hoverPos, setHoverPos] = useState<Vector3 | null>(null);
|
||||
const { setSelectedComment, setCommentPositionState, setPosition2Dstate } = useSelectedComment();
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const canvasElement = gl.domElement;
|
||||
|
||||
|
||||
@@ -5,17 +5,19 @@ import { getAllThreads } from '../../../../services/factoryBuilder/comments/getA
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { getUserData } from '../../../../functions/getUserData';
|
||||
import { getRelativeTime } from '../../../../components/ui/collaboration/function/getRelativeTime';
|
||||
|
||||
import { useVersionContext } from '../../../builder/version/versionContext';
|
||||
|
||||
function CommentInstances() {
|
||||
const { comments, setComments } = useCommentStore();
|
||||
const { projectId } = useParams();
|
||||
const { userId } = getUserData()
|
||||
const getThreads = async () => {
|
||||
if (!projectId) return;
|
||||
try {
|
||||
const getComments = await getAllThreads(projectId);
|
||||
const { userId } = getUserData();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
|
||||
const getThreads = async () => {
|
||||
if (!projectId || !selectedVersion) return;
|
||||
try {
|
||||
const getComments = await getAllThreads(projectId, selectedVersion?.versionId);
|
||||
|
||||
const formattedThreads = Array.isArray(getComments.data)
|
||||
? getComments.data.map((thread: any) => ({
|
||||
@@ -32,14 +34,12 @@ function CommentInstances() {
|
||||
: [],
|
||||
}))
|
||||
: [];
|
||||
// console.log('formattedThreads: ', formattedThreads);
|
||||
setComments(formattedThreads);
|
||||
} catch (err) {
|
||||
// console.error("Failed to fetch threads:", err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
getThreads();
|
||||
}, []);
|
||||
|
||||
@@ -14,12 +14,13 @@ interface ThreadSocketProps {
|
||||
const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSocketProps) => {
|
||||
const { threadSocket } = useSocketStore();
|
||||
const { selectedComment, setSelectedComment, setCommentPositionState, commentPositionState } = useSelectedComment();
|
||||
const { comments, addComment, addReply, updateComment, updateReply } = useCommentStore();
|
||||
const { comments, removeReply, addComment, addReply, updateComment, updateReply } = useCommentStore();
|
||||
const { userId } = getUserData();
|
||||
|
||||
useEffect(() => {
|
||||
if (!threadSocket) return;
|
||||
|
||||
|
||||
// --- Add Comment Handler ---
|
||||
// const handleAddComment = (data: any) => {
|
||||
//
|
||||
@@ -55,23 +56,21 @@ const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSock
|
||||
// };
|
||||
// threadSocket.on('v1-Comment:response:add', handleAddComment);
|
||||
const handleAddComment = (data: any) => {
|
||||
// console.log('Add: ', data);
|
||||
|
||||
|
||||
|
||||
const commentData = {
|
||||
replyId: data.data?._id,
|
||||
creatorId: data.data?.userId,
|
||||
createdAt: getRelativeTime(data.data?.createdAt),
|
||||
lastUpdatedAt: "2 hrs ago",
|
||||
comment: data.data.comment,
|
||||
comment: data.data?.comment,
|
||||
};
|
||||
|
||||
if (modeRef.current === "create") {
|
||||
|
||||
|
||||
addReply(selectedComment?.threadId, commentData);
|
||||
setMessages((prevMessages) => [...prevMessages, commentData]);
|
||||
} else if (modeRef.current === "edit") {
|
||||
|
||||
updateReply(selectedComment?.threadId, data.data?._id, commentData);
|
||||
setMessages((prev) =>
|
||||
prev.map((message) => {
|
||||
@@ -81,26 +80,22 @@ const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSock
|
||||
: message;
|
||||
})
|
||||
);
|
||||
// console.log('data.data?.comment: ', data.data?.comment);
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
threadSocket.off("v1-Comment:response:add", handleAddComment);
|
||||
};
|
||||
threadSocket.on('v1-Comment:response:add', handleAddComment);
|
||||
// --- Delete Comment Handler ---
|
||||
|
||||
const handleDeleteComment = (data: any) => {
|
||||
// console.log('delete: ', data);
|
||||
|
||||
threadSocket.off('v1-Comment:response:delete', handleDeleteComment);
|
||||
};
|
||||
threadSocket.on('v1-Comment:response:delete', handleDeleteComment);
|
||||
|
||||
// --- Create Thread Handler ---
|
||||
const handleCreateThread = (data: any) => {
|
||||
// console.log('createThread: ', data);
|
||||
|
||||
|
||||
const comment: CommentSchema = {
|
||||
state: 'active',
|
||||
@@ -117,20 +112,26 @@ const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSock
|
||||
addComment(comment);
|
||||
setCommentPositionState(null);
|
||||
// setSelectedComment(null);
|
||||
threadSocket.off('v1-thread:response:create', handleCreateThread);
|
||||
};
|
||||
threadSocket.on('v1-thread:response:create', handleCreateThread);
|
||||
|
||||
// --- Delete Thread Handler ---
|
||||
// const handleDeleteThread = (data: any) => {
|
||||
//
|
||||
|
||||
// };
|
||||
// threadSocket.on("v1-thread:response:delete", handleDeleteThread);
|
||||
|
||||
const handleDeleteThread = (data: any) => {
|
||||
|
||||
threadSocket.off('v1-thread:response:delete', handleDeleteThread);
|
||||
};
|
||||
threadSocket.on('v1-thread:response:delete', handleDeleteThread);
|
||||
threadSocket.on("v1-thread:response:delete", handleDeleteThread);
|
||||
|
||||
|
||||
|
||||
const handleEditThread = (data: any) => {
|
||||
|
||||
|
||||
const editedThread: CommentSchema = {
|
||||
state: 'active',
|
||||
threadId: data.data?._id,
|
||||
@@ -138,17 +139,16 @@ const ThreadSocketResponsesDev = ({ setMessages, modeRef, messages }: ThreadSock
|
||||
createdAt: data.data?.createdAt,
|
||||
threadTitle: data.data?.threadTitle,
|
||||
lastUpdatedAt: new Date().toISOString(),
|
||||
position: data.data.position,
|
||||
position: data.data?.position,
|
||||
rotation: [0, 0, 0],
|
||||
comments: data.data.comments,
|
||||
comments: data.data?.comments,
|
||||
};
|
||||
|
||||
// console.log('data.data?._id: ', data.data?._id);
|
||||
//
|
||||
updateComment(data.data?._id, editedThread);
|
||||
setSelectedComment(editedThread)
|
||||
|
||||
// setSelectedComment(null);
|
||||
|
||||
};
|
||||
threadSocket.on('v1-thread:response:updateTitle', handleEditThread);
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ export default function Scene({ layout }: { readonly layout: 'Main Layout' | 'Co
|
||||
if (!projectId && loadingProgress > 1) return;
|
||||
getAllProjects(userId, organization)
|
||||
.then((projects) => {
|
||||
if (!projects || !projects.Projects) return;
|
||||
let project = projects.Projects.find((val: any) => val.projectUuid === projectId || val._id === projectId);
|
||||
const canvas = document.getElementById("sceneCanvas")?.getElementsByTagName('canvas')[0];
|
||||
if (!canvas) return;
|
||||
|
||||
@@ -28,6 +28,8 @@ type SceneContextValue = {
|
||||
vehicleStore: VehicleStoreType;
|
||||
storageUnitStore: StorageUnitStoreType;
|
||||
|
||||
clearStores: () => void;
|
||||
|
||||
layout: 'Main Layout' | 'Comparison Layout';
|
||||
};
|
||||
|
||||
@@ -55,8 +57,17 @@ export function SceneProvider({
|
||||
const storageUnitStore = useMemo(() => createStorageUnitStore(), []);
|
||||
|
||||
const clearStores = useMemo(() => () => {
|
||||
assetStore().clearAssets();
|
||||
}, [assetStore]);
|
||||
assetStore.getState().clearAssets();
|
||||
aisleStore.getState().clearAisles();
|
||||
eventStore.getState().clearEvents();
|
||||
productStore.getState().clearProducts();
|
||||
materialStore.getState().clearMaterials();
|
||||
armBotStore.getState().clearArmBots();
|
||||
machineStore.getState().clearMachines();
|
||||
conveyorStore.getState().clearConveyors();
|
||||
vehicleStore.getState().clearVehicles();
|
||||
storageUnitStore.getState().clearStorageUnits();
|
||||
}, [assetStore, aisleStore, eventStore, productStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore]);
|
||||
|
||||
const contextValue = useMemo(() => (
|
||||
{
|
||||
|
||||
@@ -33,7 +33,7 @@ export const createHandleDrop = ({
|
||||
|
||||
const droppedData = JSON.parse(data);
|
||||
const canvasElement = document.getElementById("work-space-three-d-canvas");
|
||||
if (!canvasElement) throw new Error("Canvas element not found");
|
||||
if (!canvasElement) return;
|
||||
|
||||
const rect = canvasElement.getBoundingClientRect();
|
||||
const relativeX = event.clientX - rect.left;
|
||||
|
||||
@@ -683,7 +683,7 @@ export default function Dropped3dWidgets() {
|
||||
event.preventDefault();
|
||||
|
||||
const canvasElement = document.getElementById("work-space-three-d-canvas");
|
||||
if (!canvasElement) throw new Error("Canvas element not found");
|
||||
if (!canvasElement) return;
|
||||
|
||||
const canvasRect = canvasElement.getBoundingClientRect();
|
||||
const relativeX = event.clientX - canvasRect.left;
|
||||
@@ -747,7 +747,7 @@ export default function Dropped3dWidgets() {
|
||||
const canvasElement = document.getElementById(
|
||||
"work-space-three-d-canvas"
|
||||
);
|
||||
if (!canvasElement) throw new Error("Canvas element not found");
|
||||
if (!canvasElement) return;
|
||||
const canvasRect = canvasElement.getBoundingClientRect();
|
||||
const relativeX = event.clientX - canvasRect.left;
|
||||
const relativeY = event.clientY - canvasRect.top;
|
||||
|
||||
@@ -29,7 +29,6 @@ import { SceneProvider } from "../modules/scene/sceneContext";
|
||||
import { getVersionHistoryApi } from "../services/factoryBuilder/versionControl/getVersionHistoryApi";
|
||||
import { useVersionHistoryStore } from "../store/builder/useVersionHistoryStore";
|
||||
import { VersionProvider } from "../modules/builder/version/versionContext";
|
||||
import ThreadChat from "../components/ui/collaboration/ThreadChat";
|
||||
|
||||
const Project: React.FC = () => {
|
||||
let navigate = useNavigate();
|
||||
@@ -47,7 +46,7 @@ const Project: React.FC = () => {
|
||||
const { selectedUser } = useSelectedUserStore();
|
||||
const { isLogListVisible } = useLogger();
|
||||
const { setVersions } = useVersionHistoryStore();
|
||||
const { selectedComment, commentPositionState } = useSelectedComment();
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (!email || !userId) {
|
||||
@@ -56,11 +55,14 @@ const Project: React.FC = () => {
|
||||
}
|
||||
|
||||
getAllProjects(userId, organization).then((projects) => {
|
||||
if (!projects || !projects.Projects) return;
|
||||
const filterProject = projects?.Projects.find((val: any) => val.projectUuid === projectId || val._id === projectId)
|
||||
setProjectName(filterProject.projectName)
|
||||
viewProject(organization, filterProject._id, userId).then((viewedProject) => {
|
||||
});
|
||||
});
|
||||
}).catch(() => {
|
||||
console.error("Error fetching projects")
|
||||
})
|
||||
|
||||
}, []);
|
||||
|
||||
@@ -79,6 +81,8 @@ const Project: React.FC = () => {
|
||||
})
|
||||
})
|
||||
setVersions(versions);
|
||||
}).catch(() => {
|
||||
console.error("Error fetching version history")
|
||||
})
|
||||
}, [projectId])
|
||||
|
||||
@@ -127,8 +131,6 @@ const Project: React.FC = () => {
|
||||
<LogList />
|
||||
</RenderOverlay>
|
||||
)}
|
||||
{(commentPositionState !== null || selectedComment !== null) && <ThreadChat />}
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -43,7 +43,6 @@ const UserAuth: React.FC = () => {
|
||||
const organization = email.split("@")[1].split(".")[0];
|
||||
try {
|
||||
const res = await signInApi(email, password, organization, fingerprint);
|
||||
console.log('res: ', res);
|
||||
if (res.message.message === "login successfull") {
|
||||
setError("");
|
||||
setOrganization(organization);
|
||||
@@ -57,6 +56,7 @@ const UserAuth: React.FC = () => {
|
||||
|
||||
try {
|
||||
const projects = await recentlyViewed(organization, res.message.userId);
|
||||
console.log('projects: ', projects);
|
||||
if (res.message.isShare) {
|
||||
if (Object.values(projects.RecentlyViewed).length > 0) {
|
||||
const firstId = (Object.values(projects?.RecentlyViewed || {})[0] as any)?._id;
|
||||
@@ -72,7 +72,6 @@ const UserAuth: React.FC = () => {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error fetching recent projects:", error);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export const createProject = async (projectUuid: string, userId: string, thumbna
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to add project");
|
||||
console.error("Failed to add project");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -28,7 +28,7 @@ export const deleteProject = async (
|
||||
}
|
||||
console.log("response: ", response);
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to clearPanel in the zone");
|
||||
console.error("Failed to clearPanel in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -23,13 +23,13 @@ export const deleteTrash = async (organization: string, projectId: string) => {
|
||||
console.log("restore: ", response);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch trash data");
|
||||
console.error("Failed to fetch trash data");
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data;
|
||||
} catch (error: any) {
|
||||
console.error("Failed to fetch trash data:", error);
|
||||
throw new Error(error.message || "Unknown error");
|
||||
console.error(error.message || "Unknown error");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@ export const duplicateProject = async (
|
||||
}
|
||||
// console.log("response: ", response);
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to add project");
|
||||
console.error("Failed to add project");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -22,13 +22,13 @@ export const getTrash = async (organization: string) => {
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch trash data");
|
||||
console.error("Failed to fetch trash data");
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data;
|
||||
} catch (error: any) {
|
||||
console.error("Failed to fetch trash data:", error);
|
||||
throw new Error(error.message || "Unknown error");
|
||||
console.error(error.message || "Unknown error");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ export const projectTutorial = async () => {
|
||||
// console.log("response: ", response);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to add project");
|
||||
console.error("Failed to add project");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -20,7 +20,7 @@ export const recentlyViewed = async (organization: string, userId: string) => {
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch project");
|
||||
console.error("Failed to fetch project");
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
|
||||
@@ -22,7 +22,7 @@ export const restoreTrash = async (organization: string, projectId: string) => {
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch trash data");
|
||||
console.error("Failed to fetch trash data");
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
@@ -30,6 +30,6 @@ export const restoreTrash = async (organization: string, projectId: string) => {
|
||||
return data;
|
||||
} catch (error: any) {
|
||||
console.error("Failed to fetch trash data:", error);
|
||||
throw new Error(error.message || "Unknown error");
|
||||
console.error(error.message || "Unknown error");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@ export const searchProject = async (
|
||||
|
||||
console.log("response: ", response);
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to Search project");
|
||||
console.error("Failed to Search project");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -24,7 +24,7 @@ export const trashSearchProject = async (
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to add project");
|
||||
console.error("Failed to add project");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -37,7 +37,7 @@ export const updateProject = async (
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to clearPanel in the zone");
|
||||
console.error("Failed to clearPanel in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -25,7 +25,7 @@ export const viewProject = async (
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch");
|
||||
console.error("Failed to fetch");
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
|
||||
@@ -25,7 +25,7 @@ export const createAisleApi = async (
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to add project");
|
||||
console.error("Failed to add project");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -18,7 +18,7 @@ export const deleteAisleApi = async (aisleUuid: string, projectId: string, versi
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to clearPanel in the zone");
|
||||
console.error("Failed to clearPanel in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -22,7 +22,7 @@ export const getAisleApi = async (projectId: string, versionId: string) => {
|
||||
|
||||
// console.log("response: ", response);
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch");
|
||||
console.error("Failed to fetch");
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
|
||||
@@ -13,7 +13,7 @@ export const getAssetImages = async (cursor?: string) => {
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch assets");
|
||||
console.error("Failed to fetch assets");
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
|
||||
@@ -13,7 +13,7 @@ export const getAssetModel = async (modelId: string) => {
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch model");
|
||||
console.error("Failed to fetch model");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -26,7 +26,7 @@ export const deleteFloorItem = async (
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete Floor Item");
|
||||
console.error("Failed to delete Floor Item");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -22,7 +22,7 @@ export const getFloorAssets = async (organization: string, projectId?: string, v
|
||||
|
||||
// console.log('response: ', response);
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to get assets");
|
||||
console.error("Failed to get assets");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -18,7 +18,7 @@ export const setAssetsApi = async (data: any) => {
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to set or update Floor Item");
|
||||
console.error("Failed to set or update Floor Item");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -26,7 +26,7 @@ export const deleteWallItem = async (
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete Wall Item");
|
||||
console.error("Failed to delete Wall Item");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -21,7 +21,7 @@ export const getWallItems = async (organization: string, projectId?: string, ver
|
||||
}
|
||||
// console.log('response: ', response);
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to get Wall Items");
|
||||
console.error("Failed to get Wall Items");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -39,7 +39,7 @@ export const setWallItem = async (
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to set or update Wall Item");
|
||||
console.error("Failed to set or update Wall Item");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -21,7 +21,7 @@ export const getCamera = async (organization: string, userId: string, projectId?
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to get Camera position and target");
|
||||
console.error("Failed to get Camera position and target");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -31,7 +31,7 @@ export const setCamera = async (
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to set Camera Position and Target");
|
||||
console.error("Failed to set Camera Position and Target");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -21,11 +21,11 @@ export default async function getActiveUsersData(organization: string) {
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error: ${response.status} - ${response.statusText}`);
|
||||
console.error(`Error: ${response.status} - ${response.statusText}`);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to get active cameras ");
|
||||
console.error("Failed to get active cameras ");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -20,11 +20,11 @@ export default async function fetchShareUsers(organization: string) {
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error: ${response.status} - ${response.statusText}`);
|
||||
console.error(`Error: ${response.status} - ${response.statusText}`);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to get users ");
|
||||
console.error("Failed to get users ");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -23,7 +23,7 @@ export default async function giveCollabAccess(
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to set Camera Position and Target");
|
||||
console.error("Failed to set Camera Position and Target");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -4,18 +4,20 @@ export const addCommentsApi = async (
|
||||
projectId: any,
|
||||
comment: string,
|
||||
threadId?: string,
|
||||
commentId?: string
|
||||
commentId?: string,
|
||||
versionId?: string
|
||||
) => {
|
||||
console.log(
|
||||
" projectId, comments, threadId: ",
|
||||
projectId,
|
||||
comment,
|
||||
threadId,
|
||||
commentId
|
||||
commentId,
|
||||
versionId
|
||||
);
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${url_Backend_dwinzo}/api/v1/Thread/addComment`,
|
||||
`${url_Backend_dwinzo}/api/V1/Thread/addComment`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
@@ -33,9 +35,9 @@ export const addCommentsApi = async (
|
||||
//console.log("New token received:", newAccessToken);
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
console.log('response: ', response);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to add project");
|
||||
console.error("Failed to add project");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
@@ -44,9 +46,9 @@ export const addCommentsApi = async (
|
||||
return result;
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
throw new Error(error.message);
|
||||
console.error(error.message);
|
||||
} else {
|
||||
throw new Error("An unknown error occurred");
|
||||
console.error("An unknown error occurred");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5,10 +5,11 @@ export const createThreadApi = async (
|
||||
state: string,
|
||||
position: any,
|
||||
rotation: any,
|
||||
threadTitle: any
|
||||
threadTitle: any,
|
||||
versionId?: string
|
||||
) => {
|
||||
try {
|
||||
const response = await fetch(`${url_Backend_dwinzo}/api/v1/upsetThread`, {
|
||||
const response = await fetch(`${url_Backend_dwinzo}/api/V1/upsetThread`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: "Bearer <access_token>",
|
||||
@@ -16,7 +17,14 @@ export const createThreadApi = async (
|
||||
token: localStorage.getItem("token") || "",
|
||||
refresh_token: localStorage.getItem("refreshToken") || "",
|
||||
},
|
||||
body: JSON.stringify({ projectId, state, position, rotation, threadTitle }),
|
||||
body: JSON.stringify({
|
||||
projectId,
|
||||
state,
|
||||
position,
|
||||
rotation,
|
||||
threadTitle,
|
||||
versionId,
|
||||
}),
|
||||
});
|
||||
const newAccessToken = response.headers.get("x-access-token");
|
||||
if (newAccessToken) {
|
||||
@@ -24,16 +32,16 @@ export const createThreadApi = async (
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to add project");
|
||||
console.error("Failed to add project");
|
||||
}
|
||||
const result = await response.json();
|
||||
console.log('result: ', result);
|
||||
console.log("result: ", result);
|
||||
return result;
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
throw new Error(error.message);
|
||||
console.error(error.message);
|
||||
} else {
|
||||
throw new Error("An unknown error occurred");
|
||||
console.error("An unknown error occurred");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,17 +4,19 @@ let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_UR
|
||||
export const deleteCommentApi = async (
|
||||
projectId: string,
|
||||
threadId: string,
|
||||
commentId: string
|
||||
commentId: string,
|
||||
versionId?: string
|
||||
) => {
|
||||
const body: any = {
|
||||
projectId,
|
||||
threadId,
|
||||
commentId,
|
||||
versionId,
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${url_Backend_dwinzo}/api/v1/Thread/deleteComment`,
|
||||
`${url_Backend_dwinzo}/api/V1/Thread/deleteComment`,
|
||||
{
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
@@ -32,16 +34,16 @@ export const deleteCommentApi = async (
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to clearPanel in the zone");
|
||||
console.error("Failed to clearPanel in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
return result;
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
throw new Error(error.message);
|
||||
console.error(error.message);
|
||||
} else {
|
||||
throw new Error("An unknown error occurred");
|
||||
console.error("An unknown error occurred");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
|
||||
|
||||
export const deleteThreadApi = async (projectId: string, threadId: string) => {
|
||||
export const deleteThreadApi = async (
|
||||
projectId: string,
|
||||
threadId: string,
|
||||
versionId: string
|
||||
) => {
|
||||
const body: any = {
|
||||
projectId,
|
||||
threadId,
|
||||
versionId,
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch(`${url_Backend_dwinzo}/api/v1/Thread/delete`, {
|
||||
const response = await fetch(`${url_Backend_dwinzo}/api/V1/Thread/delete`, {
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
Authorization: "Bearer <access_token>",
|
||||
@@ -24,16 +29,16 @@ export const deleteThreadApi = async (projectId: string, threadId: string) => {
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to clearPanel in the zone");
|
||||
console.error("Failed to clearPanel in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
return result;
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
throw new Error(error.message);
|
||||
console.error(error.message);
|
||||
} else {
|
||||
throw new Error("An unknown error occurred");
|
||||
console.error("An unknown error occurred");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,17 +4,19 @@ let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_UR
|
||||
export const editThreadTitleApi = async (
|
||||
projectId: string,
|
||||
threadId: string,
|
||||
threadTitle: string
|
||||
threadTitle: string,
|
||||
versionId?: string
|
||||
) => {
|
||||
const body: any = {
|
||||
projectId,
|
||||
threadId,
|
||||
threadTitle,
|
||||
versionId,
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${url_Backend_dwinzo}/api/v1/Thread/updateTitle`,
|
||||
`${url_Backend_dwinzo}/api/V1/Thread/updateTitle`,
|
||||
{
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
@@ -32,16 +34,16 @@ export const editThreadTitleApi = async (
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to clearPanel in the zone");
|
||||
console.error("Failed to clearPanel in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
return result;
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
throw new Error(error.message);
|
||||
console.error(error.message);
|
||||
} else {
|
||||
throw new Error("An unknown error occurred");
|
||||
console.error("An unknown error occurred");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||
|
||||
export const getAllThreads = async (projectId: string) => {
|
||||
export const getAllThreads = async (projectId: string, versionId: string) => {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${url_Backend_dwinzo}/api/v1/Threads/${projectId}`,
|
||||
`${url_Backend_dwinzo}/api/V1/Threads/${projectId}/${versionId}`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
@@ -21,19 +21,19 @@ export const getAllThreads = async (projectId: string) => {
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to get assets");
|
||||
console.error("Failed to get assets");
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
// console.log('result: ', result);
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
echo.error("Failed to get floor asset");
|
||||
if (error instanceof Error) {
|
||||
throw new Error(error.message);
|
||||
console.error(error.message);
|
||||
} else {
|
||||
throw new Error("An unknown error occurred");
|
||||
console.error("An unknown error occurred");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -22,7 +22,7 @@ export const findEnvironment = async (organization: string, userId: string, proj
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to get wall and roof visibility");
|
||||
console.error("Failed to get wall and roof visibility");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -41,7 +41,7 @@ export const setEnvironment = async (
|
||||
}
|
||||
// console.log('responseenv: ', response);
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to set wall and roof visibility");
|
||||
console.error("Failed to set wall and roof visibility");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -18,7 +18,7 @@ export const deleteLayer = async (organization: string, layer: number) => {
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete line");
|
||||
console.error("Failed to delete line");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -18,7 +18,7 @@ export const deleteLineApi = async (organization: string, line: Object) => {
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete line");
|
||||
console.error("Failed to delete line");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -19,7 +19,7 @@ export const deletePointApi = async (organization: string, uuid: string) => {
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete point");
|
||||
console.error("Failed to delete point");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -21,7 +21,7 @@ export const getLines = async (organization: string, projectId?: string, version
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to get Lines");
|
||||
console.error("Failed to get Lines");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -25,7 +25,7 @@ export const setLine = async (
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to set line");
|
||||
console.error("Failed to set line");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -22,7 +22,7 @@ export const updatePoint = async (
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to update point");
|
||||
console.error("Failed to update point");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -14,7 +14,7 @@ export const signUpApi = async (
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to signUpApi");
|
||||
console.error("Failed to signUpApi");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -28,7 +28,7 @@ export const createVersionApi = async (projectId: string, createdBy: string, hie
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to create Version History");
|
||||
console.error("Failed to create Version History");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -21,7 +21,7 @@ export const getVersionDataApi = async (projectId: string, versionId: string) =>
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to get Version Data");
|
||||
console.error("Failed to get Version Data");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -21,7 +21,7 @@ export const getVersionHistoryApi = async (projectId: string, page?: number, lim
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to get Version History");
|
||||
console.error("Failed to get Version History");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -22,7 +22,7 @@ export const deleteZonesApi = async (
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete zone");
|
||||
console.error("Failed to delete zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -22,7 +22,7 @@ export const getZonesApi = async (organization: string, projectId?: string, vers
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to get Zones");
|
||||
console.error("Failed to get Zones");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -22,7 +22,7 @@ export const setZonesApi = async (
|
||||
localStorage.setItem("token", newAccessToken);
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to set zone");
|
||||
console.error("Failed to set zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -11,7 +11,7 @@ export const getAssetDetails = async (filename: string) => {
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch asset details");
|
||||
console.error("Failed to fetch asset details");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -3,7 +3,7 @@ export const fetchAssets = async () => {
|
||||
try {
|
||||
const response = await fetch(`${BackEnd_url}/api/v1/getAllAssets`);
|
||||
if (!response.ok) {
|
||||
throw new Error("Network response was not ok");
|
||||
console.error("Network response was not ok");
|
||||
}
|
||||
const result = await response.json();
|
||||
// const last10Assets = result.slice(-10);
|
||||
|
||||
@@ -13,7 +13,7 @@ export const fetchGltfUrl = async (filename: string, AssetID: string) => {
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch asset details");
|
||||
console.error("Failed to fetch asset details");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -12,7 +12,7 @@ export const getSortedAssets = async (category: any, orders: any) => {
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error: ${response.statusText}`);
|
||||
console.error(`Error: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -22,7 +22,7 @@ export const upsertProductOrEventApi = async (body: any) => {
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to add product or event");
|
||||
console.error("Failed to add product or event");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -24,7 +24,7 @@ export const deleteEventDataApi = async (body: any) => {
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete event data");
|
||||
console.error("Failed to delete event data");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -22,7 +22,7 @@ export const deleteProductApi = async (body: any) => {
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete product data");
|
||||
console.error("Failed to delete product data");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -24,7 +24,7 @@ export const getProductApi = async (
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch product data");
|
||||
console.error("Failed to fetch product data");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -21,7 +21,7 @@ export const getAllProductsApi = async (projectId: string, versionId: string) =>
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch all products data");
|
||||
console.error("Failed to fetch all products data");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -24,7 +24,7 @@ export const renameProductApi = async (body: {
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to rename product");
|
||||
console.error("Failed to rename product");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -28,7 +28,7 @@ export const adding3dWidgets = async (
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to add 3dwidget in the zone");
|
||||
console.error("Failed to add 3dwidget in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -22,7 +22,7 @@ export const addingFloatingWidgets = async (zoneUuid: string,organization: strin
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to add Floatingwidget in the zone");
|
||||
console.error("Failed to add Floatingwidget in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -27,7 +27,7 @@ export const addingWidgets = async (
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to add widget in the zone");
|
||||
console.error("Failed to add widget in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -25,7 +25,7 @@ export const clearPanel = async (
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to clearPanel in the zone");
|
||||
console.error("Failed to clearPanel in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -29,7 +29,7 @@ export const delete3dWidgetApi = async (
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete floating widget in the zone");
|
||||
console.error("Failed to delete floating widget in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -27,7 +27,7 @@ export const deleteFloatingWidgetApi = async (
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete floating widget in the zone");
|
||||
console.error("Failed to delete floating widget in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -26,7 +26,7 @@ export const deletePanelApi = async (
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete widget in the zone");
|
||||
console.error("Failed to delete widget in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -25,7 +25,7 @@ export const deleteTemplateApi = async (
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete template ");
|
||||
console.error("Failed to delete template ");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
@@ -25,7 +25,7 @@ export const deleteWidgetApi = async (
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete widget in the zone");
|
||||
console.error("Failed to delete widget in the zone");
|
||||
}
|
||||
const result = await response.json();
|
||||
return result;
|
||||
|
||||
@@ -23,7 +23,7 @@ export const duplicateWidgetApi = async (
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to duplicate widget in the zone");
|
||||
console.error("Failed to duplicate widget in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user