Refactor: Update project handling and sharing functionalities; integrate shared projects retrieval; enhance user data structure and loading mechanisms; improve input handling in MultiEmailInvite component; adjust wall generation callbacks in DXF processing.

This commit is contained in:
2025-06-30 15:54:41 +05:30
parent 84101905ff
commit 898179c2c1
14 changed files with 337 additions and 186 deletions

View File

@@ -1,4 +1,4 @@
import React, { useState, useRef, useEffect } from "react";
import React, { useState, useRef, useEffect, act } from "react";
import img from "../../assets/image/image.png";
import { useNavigate } from "react-router-dom";
import { getUserData } from "../../functions/getUserData";
@@ -14,13 +14,15 @@ interface DashBoardCardProps {
projectId: string;
createdAt?: string;
isViewed?: string;
createdBy?: { _id: string, userName: string };
handleDeleteProject?: (projectId: string) => Promise<void>;
handleTrashDeleteProject?: (projectId: string) => Promise<void>;
handleRestoreProject?: (projectId: string) => Promise<void>;
handleDuplicateWorkspaceProject?: (
projectId: string,
projectName: string,
thumbnail: string
thumbnail: string,
userId?: string
) => Promise<void>;
handleDuplicateRecentProject?: (
projectId: string,
@@ -31,6 +33,7 @@ interface DashBoardCardProps {
setIsSearchActive?: React.Dispatch<React.SetStateAction<boolean>>;
setRecentDuplicateData?: React.Dispatch<React.SetStateAction<Object>>;
setProjectDuplicateData?: React.Dispatch<React.SetStateAction<Object>>;
setActiveFolder?: React.Dispatch<React.SetStateAction<string>>;
}
type RelativeTimeFormatUnit = any;
@@ -45,8 +48,10 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
handleDuplicateWorkspaceProject,
handleDuplicateRecentProject,
createdAt,
createdBy,
setRecentDuplicateData,
setProjectDuplicateData,
setActiveFolder
}) => {
const navigate = useNavigate();
const { setProjectName } = useProjectName();
@@ -59,10 +64,18 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
const kebabRef = useRef<HTMLDivElement>(null);
const navigateToProject = async (e: any) => {
console.log('active: ', active);
if (active && active == "trash") return;
setLoadingProgress(1)
setProjectName(projectName);
navigate(`/${projectId}`);
try {
const viewProjects = await viewProject(organization, projectId, userId)
console.log('viewProjects: ', viewProjects);
console.log('projectName: ', projectName);
setLoadingProgress(1)
setProjectName(projectName);
navigate(`/${projectId}`);
} catch {
}
};
const handleOptionClick = async (option: string) => {
@@ -81,11 +94,18 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
break;
case "open in new tab":
try {
await viewProject(organization, projectId, userId);
setProjectName(projectName);
setIsKebabOpen(false);
if (active === "shared" && createdBy) {
console.log("ihreq");
const newTab = await viewProject(organization, projectId, createdBy?._id);
console.log('newTab: ', newTab);
} else {
const newTab = await viewProject(organization, projectId, userId);
console.log('newTab: ', newTab);
setProjectName(projectName);
setIsKebabOpen(false);
}
} catch (error) {
console.error("Error opening project in new tab:", error);
}
window.open(`/${projectId}`, "_blank");
break;
@@ -100,13 +120,17 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
projectName,
thumbnail,
});
await handleDuplicateWorkspaceProject(projectId, projectName, thumbnail);
await handleDuplicateWorkspaceProject(projectId, projectName, thumbnail, userId);
if (active === "shared" && setActiveFolder) {
setActiveFolder("myProjects")
}
} else if (handleDuplicateRecentProject) {
setRecentDuplicateData &&
setRecentDuplicateData({
projectId,
projectName,
thumbnail,
userId
});
await handleDuplicateRecentProject(projectId, projectName, thumbnail);
}
@@ -128,7 +152,6 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
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
);
@@ -173,6 +196,19 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
return "just now";
}
const kebabOptionsMap: Record<string, string[]> = {
default: ["rename", "delete", "duplicate", "open in new tab"],
trash: ["restore", "delete"],
shared: ["duplicate", "open in new tab"],
};
const getOptions = () => {
if (active === "trash") return kebabOptionsMap.trash;
if (active === "shared") return kebabOptionsMap.shared;
if (createdBy && createdBy?._id !== userId) return kebabOptionsMap.shared;
return kebabOptionsMap.default;
};
return (
<button
className="dashboard-card-container"
@@ -212,13 +248,12 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
<div className="project-data">
{active && active == "trash" ? `Trashed by you` : `Edited `}{" "}
{getRelativeTime(createdAt)}
</div>
)}
</div>
<div className="users-list-container" ref={kebabRef}>
<div className="user-profile">
{userName ? userName.charAt(0).toUpperCase() : "A"}
{(!createdBy) ? userName ? userName?.charAt(0).toUpperCase() : "A" : createdBy?.userName?.charAt(0).toUpperCase()}
</div>
<button
className="kebab-wrapper"
@@ -232,29 +267,9 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
</div>
</div>
</div>
{isKebabOpen && active !== "trash" && (
{isKebabOpen && (
<div className="kebab-options-wrapper">
{["rename", "delete", "duplicate", "open in new tab"].map(
(option) => (
<button
key={option}
className="option"
title={""}
onClick={(e) => {
e.stopPropagation();
handleOptionClick(option);
}}
>
{option}
</button>
)
)}
</div>
)}
{isKebabOpen && active && active == "trash" && (
<div className="kebab-options-wrapper">
{["restore", "delete"].map((option) => (
{getOptions().map((option) => (
<button
key={option}
className="option"

View File

@@ -13,7 +13,7 @@ interface Project {
_id: string;
projectName: string;
thumbnail: string;
createdBy: string;
createdBy: { _id: string, userName: string };
projectUuid?: string;
createdAt: string;
isViewed?: string
@@ -34,7 +34,8 @@ const DashboardHome: React.FC = () => {
const fetchRecentProjects = async () => {
try {
const projects = await recentlyViewed(organization, userId);
console.log('projects: ', projects);
if (JSON.stringify(projects) !== JSON.stringify(recentProjects)) {
setRecentProjects(projects);
}
@@ -126,7 +127,8 @@ const DashboardHome: React.FC = () => {
projectName={project.projectName}
thumbnail={project.thumbnail}
projectId={project._id}
createdAt={project.isViewed}
createdBy={project.createdBy}
createdAt={project.createdAt}
handleDeleteProject={handleDeleteProject}
handleDuplicateRecentProject={handleDuplicateRecentProject}
setRecentDuplicateData={setRecentDuplicateData}

View File

@@ -7,6 +7,8 @@ import { getAllProjects } from "../../services/dashboard/getAllProjects";
import { searchProject } from "../../services/dashboard/searchProjects";
import { deleteProject } from "../../services/dashboard/deleteProject";
import ProjectSocketRes from "./socket/projectSocketRes.dev";
import { sharedWithMeProjects } from "../../services/dashboard/sharedWithMeProject";
import { duplicateProject } from "../../services/dashboard/duplicateProject";
interface Project {
_id: string;
@@ -25,12 +27,25 @@ const DashboardProjects: React.FC = () => {
const [workspaceProjects, setWorkspaceProjects] = useState<WorkspaceProjects>(
{}
);
const [sharedwithMeProject, setSharedWithMeProjects] = useState<any>([])
const [projectDuplicateData, setProjectDuplicateData] = useState<Object>({});
const [isSearchActive, setIsSearchActive] = useState<boolean>(false);
const [activeFolder, setActiveFolder] = useState<string>("myProjects");
const { projectSocket } = useSocketStore();
const { userId, organization } = getUserData();
const handleProjectsSearch = async (inputValue: string) => {
if (!inputValue.trim()) {
setIsSearchActive(false);
return;
}
if (!setWorkspaceProjects || !setIsSearchActive) return;
const searchedProject = await searchProject(organization, userId, inputValue);
setIsSearchActive(true);
setWorkspaceProjects(searchedProject.message ? {} : searchedProject);
};
const fetchAllProjects = async () => {
try {
const projects = await getAllProjects(userId, organization);
@@ -44,18 +59,6 @@ const DashboardProjects: React.FC = () => {
}
};
const handleProjectsSearch = async (inputValue: string) => {
if (!inputValue.trim()) {
setIsSearchActive(false);
return;
}
if (!setWorkspaceProjects || !setIsSearchActive) return;
const searchedProject = await searchProject(organization, userId, inputValue);
setIsSearchActive(true);
setWorkspaceProjects(searchedProject.message ? {} : searchedProject);
};
const handleDeleteProject = async (projectId: any) => {
try {
// const deletedProject = await deleteProject(
@@ -97,18 +100,9 @@ const DashboardProjects: React.FC = () => {
const handleDuplicateWorkspaceProject = async (
projectId: string,
projectName: string,
thumbnail: string
thumbnail: string,
) => {
// await handleDuplicateProjects({
// userId,
// organization,
// projectId,
// projectName,
// projectSocket,
// thumbnail,
// setWorkspaceProjects,
// setIsSearchActive
// });
const duplicateProjectData = {
userId,
thumbnail,
@@ -121,9 +115,7 @@ const DashboardProjects: React.FC = () => {
const renderProjects = () => {
if (activeFolder !== "myProjects") return null;
const projectList = workspaceProjects[Object.keys(workspaceProjects)[0]];
if (!projectList?.length) {
return <div className="empty-state">No projects found</div>;
}
@@ -143,12 +135,49 @@ const DashboardProjects: React.FC = () => {
));
};
const renderSharedProjects = () => {
return sharedwithMeProject?.map((project: any) => (
<DashboardCard
key={project._id}
projectName={project.projectName}
thumbnail={project.thumbnail}
projectId={project._id}
createdAt={project.createdAt}
setIsSearchActive={setIsSearchActive}
active="shared"
createdBy={project.createdBy}
setProjectDuplicateData={setProjectDuplicateData}
handleDuplicateWorkspaceProject={handleDuplicateWorkspaceProject}
setActiveFolder={setActiveFolder}
/>
));
};
const sharedProject = async () => {
try {
const sharedWithMe = await sharedWithMeProjects();
console.log('sharedWithMe: ', sharedWithMe);
setSharedWithMeProjects(sharedWithMe)
} catch {
}
}
useEffect(() => {
if (!isSearchActive) {
fetchAllProjects();
}
}, [isSearchActive]);
useEffect(() => {
if (activeFolder === "shared") {
sharedProject()
}
}, [activeFolder])
return (
<div className="dashboard-home-container">
<DashboardNavBar
@@ -171,7 +200,8 @@ const DashboardProjects: React.FC = () => {
Shared with me
</button>
</div>
<div className="cards-container">{renderProjects()}</div>
<div className="cards-container">{activeFolder == "myProjects" ? renderProjects() : renderSharedProjects()}</div>
{projectDuplicateData && Object.keys(projectDuplicateData).length > 0 && (
<ProjectSocketRes
setIsSearchActive={setIsSearchActive}
@@ -183,4 +213,6 @@ const DashboardProjects: React.FC = () => {
);
};
export default DashboardProjects;
export default DashboardProjects;

View File

@@ -14,12 +14,24 @@ interface Project {
createdAt: string;
isViewed?: string
}
interface RecentProject {
_id: string;
projectName: string;
thumbnail: string;
createdBy: { _id: string, userName: string };
projectUuid?: string;
createdAt: string;
isViewed?: string
}
interface RecentProjectData {
[key: string]: RecentProject[];
}
interface ProjectsData {
[key: string]: Project[];
}
interface ProjectSocketResProps {
setRecentProjects?: React.Dispatch<React.SetStateAction<ProjectsData>>;
setRecentProjects?: React.Dispatch<React.SetStateAction<RecentProjectData>>;
setWorkspaceProjects?: React.Dispatch<React.SetStateAction<ProjectsData>>;
setIsSearchActive?: React.Dispatch<React.SetStateAction<boolean>>;
}
@@ -52,7 +64,7 @@ const ProjectSocketRes = ({
};
const handleDuplicate = async (data: any) => {
// console.log("Project duplicate response:", data);
console.log("Project duplicate response:", data);
if (data?.message === "Project Duplicated successfully") {
if (setWorkspaceProjects) {
const allProjects = await getAllProjects(userId, organization);

View File

@@ -6,6 +6,7 @@ import { useProjectName } from "../../store/builder/store";
import { getAllProjects } from "../../services/dashboard/getAllProjects";
import { useComparisonProduct } from "../../store/simulation/useSimulationStore";
import { getUserData } from "../../functions/getUserData";
import { sharedWithMeProjects } from "../../services/dashboard/sharedWithMeProject";
interface LoadingPageProps {
progress: number; // Expect progress as a percentage (0-100)
@@ -18,19 +19,35 @@ const LoadingPage: React.FC<LoadingPageProps> = ({ progress }) => {
const { userId, organization } = getUserData();
const validatedProgress = Math.min(100, Math.max(0, progress));
useEffect(() => {
if (!userId) return;
if (!userId) {
console.error("User data not found in localStorage");
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);
const fetchProjects = async () => {
try {
const projects = await getAllProjects(userId, organization);
const shared = await sharedWithMeProjects();
const allProjects = [...(projects?.Projects || []), ...(shared || [])];
const matchedProject = allProjects.find(
(val: any) => val.projectUuid === projectId || val._id === projectId
);
if (matchedProject) {
setProjectName(matchedProject.projectName);
} else {
console.warn("Project not found with given ID:", projectId);
}
} catch (error) {
console.error("Error fetching projects:", error);
}
}).catch((error) => {
console.log(error);
})
};
fetchProjects();
}, []);
return (

View File

@@ -12,7 +12,7 @@ const SelectFloorPlan: React.FC = () => {
// Access layout state and state setters
const { currentLayout, setLayout } = useLayoutStore();
// Access DXF-related states and setters
const { setDfxUploaded, setDfxGenerate, setObjValue, objValue } =
const { setDfxUploaded, setDxfWallGenerate, setObjValue, objValue } =
useDfxUpload();
const { activeLayer } = useActiveLayer();
const { wallThickness, wallHeight, insideMaterial, outsideMaterial } = useBuilderStore();
@@ -63,7 +63,7 @@ const SelectFloorPlan: React.FC = () => {
if (parsedFile !== undefined) {
getWallPointsFromBlueprint({
parsedData: parsedFile,
setDfxGenerate,
setDxfWallGenerate,
objValue,
wallThickness, wallHeight, outsideMaterial, insideMaterial, activeLayer, addWall, walls
});

View File

@@ -1,6 +1,7 @@
import React, { useState } from "react";
import { getSearchUsers } from "../../../services/factoryBuilder/collab/getSearchUsers";
import { useParams } from "react-router-dom";
import { getSearchUsers } from "../../../services/factoryBuilder/collab/getSearchUsers";
import { shareProject } from "../../../services/factoryBuilder/collab/shareProject";
import { getUserData } from "../../../functions/getUserData";
@@ -11,121 +12,120 @@ interface UserData {
}
interface MultiEmailProps {
users: any,
getData: any,
users: Array<any>;
getData: () => void;
}
const MultiEmailInvite: React.FC<MultiEmailProps> = ({ users, getData }) => {
const [emails, setEmails] = useState<any>([]);
const [searchedEmail, setSearchedEmail] = useState<UserData[]>([]);
const [inputFocus, setInputFocus] = useState(false);
const [selectedUsers, setSelectedUsers] = useState<UserData[]>([]);
const [searchResults, setSearchResults] = useState<UserData[]>([]);
const [inputValue, setInputValue] = useState("");
const [isFocused, setIsFocused] = useState(false);
const { projectId } = useParams();
const { userId } = getUserData();
const handleAddEmail = async (selectedUser: UserData) => {
if (!projectId || !selectedUser) return
const trimmedEmail = inputValue.trim();
setEmails((prev: any[]) => {
if (!selectedUser) return prev;
const isNotCurrentUser = selectedUser._id !== userId;
const alreadyExistsInEmails = prev.some(email => email._id === selectedUser._id);
const alreadyExistsInUsers = users.some((val: any) => val.userId === selectedUser._id);
if (isNotCurrentUser && !alreadyExistsInEmails && !alreadyExistsInUsers) {
return [...prev, selectedUser];
}
return prev;
});
setInputValue(""); // Clear the input field after adding
};
const handleSearchMail = async (e: any) => {
setInputValue(e.target.value);
const trimmedEmail = e.target.value.trim();
const handleSearchInput = async (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value.trim();
setInputValue(value);
if (value.length < 3) return;
if (trimmedEmail.length < 3) return;
try {
const searchedMail = await getSearchUsers(trimmedEmail);
const filteredEmail = searchedMail.sharchMail?.filtered;
if (filteredEmail) {
setSearchedEmail(filteredEmail)
}
} catch (error) {
console.error("Failed to search mail:", error);
const result = await getSearchUsers(value);
const filtered = result?.sharchMail?.filtered || [];
setSearchResults(filtered);
} catch (err) {
console.error("Search failed:", err);
}
};
const handleAddUser = (user: UserData) => {
if (!user || user._id === userId) return;
const handleKeyDown = async (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter" || e.key === "," && searchedEmail.length > 0) {
const isAlreadySelected = selectedUsers.some(u => u._id === user._id);
const isAlreadyShared = users.some(u => u.userId === user._id);
if (!isAlreadySelected && !isAlreadyShared) {
setSelectedUsers(prev => [...prev, user]);
}
setInputValue("");
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if ((e.key === "Enter" || e.key === ",") && searchResults.length > 0) {
e.preventDefault();
handleAddEmail(searchedEmail[0]);
handleAddUser(searchResults[0]);
}
};
const handleRemoveEmail = (idToRemove: string) => {
setEmails((prev: any) => prev.filter((email: any) => email._id !== idToRemove));
const handleRemoveUser = (userIdToRemove: string) => {
setSelectedUsers(prev => prev.filter(user => user._id !== userIdToRemove));
};
const validateEmail = (email: string) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
};
const handleInvite = () => {
const handleAddEmail = async () => {
if (!projectId) return;
try {
emails.forEach((user: any) => {
shareProject(user._id, projectId)
.then((res) => {
console.log("sharedProject:", res);
})
.catch((err) => {
console.error("Error sharing project:", err);
});
setEmails([])
setInputValue("")
});
setTimeout(() => {
getData()
}, 1000);
try {
await Promise.all(
selectedUsers.map(user =>
shareProject(user._id, projectId)
.then(res => console.log("Shared:", res))
.catch(err => console.error("Share error:", err))
)
);
setSelectedUsers([]);
setInputValue("");
setTimeout(getData, 1000);
} catch (error) {
console.error("General error:", error);
console.error("Invite error:", error);
}
};
return (
<div className="multi-email-invite-input-container">
<div className={`multi-email-invite-input${inputFocus ? " active" : ""}`}>
{emails.map((email: any, index: number) => (
<div key={index} className="entered-emails">
{email.Email}
<span onClick={() => handleRemoveEmail(email._id)}>&times;</span>
<div className={`multi-email-invite-input${isFocused ? " active" : ""}`}>
{selectedUsers.map(user => (
<div key={user._id} className="entered-emails">
{user.Email}
<span onClick={() => handleRemoveUser(user._id)}>&times;</span>
</div>
))}
<input
type="text"
value={inputValue}
onChange={(e) => handleSearchMail(e)}
onFocus={() => setInputFocus(true)}
// onBlur={() => setInputFocus(false)}
onChange={handleSearchInput}
onFocus={() => setIsFocused(true)}
onKeyDown={handleKeyDown}
placeholder="Enter email and press Enter or comma to seperate"
placeholder="Enter email and press Enter or comma"
/>
</div>
<div onClick={handleInvite} className="invite-button">
<div onClick={handleAddEmail} className="invite-button">
Add
</div>
{inputFocus && inputValue.length > 2 && searchedEmail && searchedEmail.length > 0 && (
{isFocused && inputValue.length > 2 && searchResults.length > 0 && (
<div className="users-list-container">
{/* list available users here */}
{searchedEmail.map((val: any, i: any) => (
<div onClick={(e) => {
handleAddEmail(val)
setInputFocus(false)
}} key={i} >
{val?.Email}
{searchResults.map(user => (
<div
key={user._id}
onClick={() => {
handleAddUser(user);
setIsFocused(false);
}}
>
{user.Email}
</div>
))}
</div>

View File

@@ -76,7 +76,7 @@ const DxfFile = () => {
// Recalculate wall points based on new position
getWallPointsFromBlueprint({
objValue: { x: position.x, y: position.y, z: position.z },
setDfxGenerate: () => { },
setDxfWallGenerate: () => { },
wallThickness, wallHeight, outsideMaterial, insideMaterial, activeLayer, addWall, walls
});
};

View File

@@ -7,7 +7,7 @@ type DXFEntity = any; // Replace with actual DXF entity type
type WallLineVertex = [Vector3, string, number, string]; // Represents a wall segment with start point, ID, weight, and type
interface Props {
parsedData?: DXFData; // Parsed DXF file data
setDfxGenerate?: any; // Callback to set generated walls
setDxfWallGenerate?: any; // Callback to set generated walls
objValue: any; // Object position values for offset calculation
wallThickness: number;
wallHeight: number;
@@ -25,12 +25,12 @@ interface Props {
*
* @param {Props} params - Configuration parameters
* @param {DXFData} params.parsedData - Parsed DXF file data
* @param {Function} params.setDfxGenerate - Callback to store generated walls
* @param {Function} params.setDxfWallGenerate - Callback to store generated walls
* @param {Object} params.objValue - Contains x,y,z offsets for position adjustment
*/
export function getWallPointsFromBlueprint({
parsedData,
setDfxGenerate,
setDxfWallGenerate,
objValue,
wallThickness,
wallHeight,
@@ -46,6 +46,16 @@ export function getWallPointsFromBlueprint({
const unit = 1000; // Conversion factor from millimeters to meters
const wallVertex: any[] = []; // Array to store wall vertices
const findExistingPoint = (vec: Vector3): Point | undefined => {
for (const wall of wallVertex) {
for (const pt of wall.points) {
const pos = new Vector3(...pt.position);
if (pos.equals(vec)) return pt;
}
}
return undefined;
};
// Process each entity in the DXF file
parsedData.entities.forEach((entity: DXFEntity) => {
// Handle LINE entities
@@ -64,17 +74,19 @@ export function getWallPointsFromBlueprint({
).add(new Vector3(objValue.x, 0, objValue.z));
// Create start and end points
const startPoint: Point = {
pointUuid: MathUtils.generateUUID(), // Generate unique ID for new points
pointType: "Wall", // Type identifier
position: [startVec.x, startVec.y, startVec.z], // Position in 3D space
layer: activeLayer, // Default weight
const existingStart = findExistingPoint(startVec);
const startPoint: Point = existingStart || {
pointUuid: MathUtils.generateUUID(),
pointType: "Wall",
position: [startVec.x, startVec.y, startVec.z],
layer: activeLayer,
};
const endPoint: Point = {
pointUuid: MathUtils.generateUUID(), // Generate unique ID for new points
pointType: "Wall", // Type identifier
position: [endVec.x, endVec.y, endVec.z], // Position in 3D space
const existingEnd = findExistingPoint(endVec);
const endPoint: Point = existingEnd || {
pointUuid: MathUtils.generateUUID(),
pointType: "Wall",
position: [endVec.x, endVec.y, endVec.z],
layer: activeLayer,
};
@@ -113,14 +125,16 @@ export function getWallPointsFromBlueprint({
).add(new Vector3(objValue.x, 0, objValue.z));
// Create start and end points
const startPoint: Point = {
const existingStart = findExistingPoint(startVec);
const startPoint: Point = existingStart || {
pointUuid: MathUtils.generateUUID(), // Generate unique ID for new points
pointType: "Wall", // Type identifier
position: [startVec.x, startVec.y, startVec.z], // Position in 3D space
layer: activeLayer,
};
const endPoint: Point = {
const existingEnd = findExistingPoint(endVec);
const endPoint: Point = existingEnd || {
pointUuid: MathUtils.generateUUID(), // Generate unique ID for new points
pointType: "Wall", // Type identifier
position: [endVec.x, endVec.y, endVec.z], // Position in 3D space
@@ -200,14 +214,16 @@ export function getWallPointsFromBlueprint({
const endVec = arcPoints[i + 1];
// Create start and end points
const startPoint: Point = {
const existingStart = findExistingPoint(startVec);
const startPoint: Point = existingStart || {
pointUuid: MathUtils.generateUUID(),
pointType: "Wall",
position: [startVec.x, startVec.y, startVec.z],
layer: activeLayer,
};
const endPoint: Point = {
const existingEnd = findExistingPoint(endVec);
const endPoint: Point = existingEnd || {
pointUuid: MathUtils.generateUUID(),
pointType: "Wall",
position: [endVec.x, endVec.y, endVec.z],
@@ -236,7 +252,7 @@ export function getWallPointsFromBlueprint({
console.error("Unsupported entity type:", entity.type);
}
});
console.log("wallVertex: ", wallVertex);
// Return the generated walls through callback if provided
setDfxGenerate && setDfxGenerate(wallVertex);
}
setDxfWallGenerate && setDxfWallGenerate(wallVertex);
}

View File

@@ -29,6 +29,7 @@ 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 { sharedWithMeProjects } from "../services/dashboard/sharedWithMeProject";
const Project: React.FC = () => {
let navigate = useNavigate();
@@ -54,16 +55,29 @@ const Project: React.FC = () => {
return;
}
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")
})
const fetchProjects = async () => {
try {
const projects = await getAllProjects(userId, organization);
const shared = await sharedWithMeProjects();
const allProjects = [...(projects?.Projects || []), ...(shared || [])];
const matchedProject = allProjects.find(
(val: any) => val.projectUuid === projectId || val._id === projectId
);
if (matchedProject) {
setProjectName(matchedProject.projectName);
await viewProject(organization, matchedProject._id, userId);
} else {
console.warn("Project not found with given ID:", projectId);
}
} catch (error) {
console.error("Error fetching projects:", error);
}
};
fetchProjects();
}, []);
useEffect(() => {

View File

@@ -0,0 +1,30 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const sharedWithMeProjects = async (
) => {
try {
const response = await fetch(`${url_Backend_dwinzo}/api/V1/sharedWithMe`, {
method: "GET",
headers: {
Authorization: "Bearer <access_token>",
"Content-Type": "application/json",
token: localStorage.getItem("token") || "",
refresh_token: localStorage.getItem("refreshToken") || "",
},
});
const newAccessToken = response.headers.get("x-access-token");
if (newAccessToken) {
//console.log("New token received:", newAccessToken);
localStorage.setItem("token", newAccessToken);
}
if (!response.ok) {
throw new Error("Failed to fetch assets");
}
return await response.json();
} catch (error: any) {
echo.error("Failed to get asset image");
console.log(error.message);
}
};

View File

@@ -586,7 +586,7 @@ export const useDfxUpload = create<any>((set: any) => ({
dfxWallGenerate: [],
objValue: { x: 0, y: 0, z: 0 },
setDfxUploaded: (x: any) => set({ dfxuploaded: x }),
setDfxGenerate: (x: any) => set({ dfxWallGenerate: x }),
setDxfWallGenerate: (x: any) => set({ dfxWallGenerate: x }),
setObjValue: (x: any) => set({ objValue: x }),
}));

View File

@@ -46,7 +46,6 @@ textarea {
}
input[type="number"] {
// Chrome, Safari, Edge, Opera
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
@@ -487,7 +486,6 @@ input[type="number"] {
position: relative;
cursor: pointer;
.check-box-style {
position: absolute;
height: 20px;
@@ -665,6 +663,21 @@ input[type="number"] {
.multi-email-invite-input-container {
@include flex-space-between;
gap: 20px;
position: relative;
.users-list-container {
position: absolute;
top: calc(100% + 8px);
background: var(--background-color);
backdrop-filter: blur(18px);
padding: 12px;
width: 100%;
height: auto;
max-height: 200px;
border-radius: 8px;
z-index: 100;
outline: 1px solid var(--border-color);
}
.multi-email-invite-input {
width: 100%;
@@ -764,4 +777,4 @@ input[type="number"] {
background: var(--background-color-gray);
}
}
}
}

View File

@@ -53,7 +53,7 @@ const KeyPressListener: React.FC = () => {
const { setCreateNewVersion } = useVersionHistoryStore();
const { setVersionHistoryVisible } = useVersionHistoryVisibleStore();
const { setSelectedComment } = useSelectedComment();
const { setDfxUploaded, setDfxGenerate } = useDfxUpload();
const { setDfxUploaded, setDxfWallGenerate } = useDfxUpload();
const isTextInput = (element: Element | null): boolean =>
element instanceof HTMLInputElement ||
element instanceof HTMLTextAreaElement ||