This commit is contained in:
2025-06-23 09:37:53 +05:30
parent 2fbdf8ab61
commit 54b02541c1
278 changed files with 10134 additions and 7904 deletions

View File

@@ -1,7 +1,7 @@
import React, { useState, useRef, useEffect } from "react";
import img from "../../assets/image/image.png";
import { useNavigate } from "react-router-dom";
import { getUserData } from "./functions/getUserData";
import { getUserData } from "../../functions/getUserData";
import { useLoadingProgress, useProjectName, useSocketStore } from "../../store/builder/store";
import { viewProject } from "../../services/dashboard/viewProject";
import OuterClick from "../../utils/outerClick";
@@ -60,12 +60,6 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
const navigateToProject = async (e: any) => {
if (active && active == "trash") return;
try {
const viewedProject = await viewProject(organization, projectId, userId);
console.log("Viewed project:", viewedProject);
} catch (error) {
console.error("Error opening project:", error);
}
setLoadingProgress(1)
setProjectName(projectName);
navigate(`/${projectId}`);
@@ -75,9 +69,9 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
switch (option) {
case "delete":
if (handleDeleteProject) {
await handleDeleteProject(projectId);
handleDeleteProject(projectId);
} else if (handleTrashDeleteProject) {
await handleTrashDeleteProject(projectId);
handleTrashDeleteProject(projectId);
}
break;
case "restore":
@@ -133,7 +127,7 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
if (!projectId) return;
try {
const projects = await getAllProjects(userId, organization);
console.log("projects: ", projects);
// console.log("projects: ", projects);
let projectUuid = projects.Projects.find(
(val: any) => val.projectUuid === projectId || val._id === projectId
);
@@ -264,7 +258,6 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
key={option}
className="option"
onClick={(e) => {
console.log("option", option);
e.stopPropagation();
handleOptionClick(option);
}}

View File

@@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
import DashboardCard from "./DashboardCard";
import DashboardNavBar from "./DashboardNavBar";
import MarketPlaceBanner from "./MarketPlaceBanner";
import { getUserData } from "./functions/getUserData";
import { getUserData } from "../../functions/getUserData";
import { useSocketStore } from "../../store/builder/store";
import { recentlyViewed } from "../../services/dashboard/recentlyViewed";
import { searchProject } from "../../services/dashboard/searchProjects";
@@ -34,8 +34,7 @@ const DashboardHome: React.FC = () => {
const fetchRecentProjects = async () => {
try {
const projects = await recentlyViewed(organization, userId);
console.log("RecentlyViewed: ", projects);
if (JSON.stringify(projects) !== JSON.stringify(recentProjects)) {
setRecentProjects(projects);
}
@@ -59,7 +58,6 @@ const DashboardHome: React.FC = () => {
};
const handleDeleteProject = async (projectId: any) => {
console.log("projectId:delete ", projectId);
try {
//API for delete project
// const deletedProject = await deleteProject(
@@ -115,6 +113,7 @@ const DashboardHome: React.FC = () => {
const renderProjects = () => {
const projectList = recentProjects[Object.keys(recentProjects)[0]];
console.log('projectList: ', projectList);
if (!projectList?.length) {
return <div className="empty-state">No recent projects found</div>;
@@ -150,7 +149,7 @@ const DashboardHome: React.FC = () => {
handleRecentProjectSearch={handleRecentProjectSearch}
/>
<MarketPlaceBanner />
<div className="container">
<div className="dashboard-container">
<h2 className="section-header">Recents</h2>
<div className="cards-container">{renderProjects()}</div>
</div>

View File

@@ -1,7 +1,7 @@
import React, { useEffect, useState } from "react";
import DashboardNavBar from "./DashboardNavBar";
import DashboardCard from "./DashboardCard";
import { getUserData } from "./functions/getUserData";
import { getUserData } from "../../functions/getUserData";
import { useSocketStore } from "../../store/builder/store";
import { getAllProjects } from "../../services/dashboard/getAllProjects";
import { searchProject } from "../../services/dashboard/searchProjects";
@@ -65,7 +65,7 @@ const DashboardProjects: React.FC = () => {
// console.log('deletedProject: ', deletedProject);
const deleteProjects = {
projectId,
organization: organization,
organization,
userId,
};

View File

@@ -1,7 +1,7 @@
import React, { useEffect, useState } from "react";
import DashboardCard from "./DashboardCard";
import DashboardNavBar from "./DashboardNavBar";
import { getUserData } from "./functions/getUserData";
import { getUserData } from "../../functions/getUserData";
import { trashSearchProject } from "../../services/dashboard/trashSearchProject";
import { restoreTrash } from "../../services/dashboard/restoreTrash";
import { getTrash } from "../../services/dashboard/getTrash";
@@ -22,9 +22,7 @@ interface DiscardedProjects {
}
const DashboardTrash: React.FC = () => {
const [discardedProjects, setDiscardedProjects] = useState<DiscardedProjects>(
{}
);
const [discardedProjects, setDiscardedProjects] = useState<DiscardedProjects>({});
const [isSearchActive, setIsSearchActive] = useState(false);
const { userId, organization } = getUserData();
const { projectSocket } = useSocketStore();
@@ -60,7 +58,6 @@ const DashboardTrash: React.FC = () => {
};
const handleRestoreProject = async (projectId: any) => {
console.log("projectId: ", projectId);
try {
const restoreProject = await restoreTrash(organization, projectId);
// console.log('restoreProject: ', restoreProject);
@@ -86,6 +83,7 @@ const DashboardTrash: React.FC = () => {
};
const handleTrashDeleteProject = async (projectId: any) => {
console.log('projectId: ', projectId);
try {
// const deletedProject = await deleteTrash(
// organization, projectId

View File

@@ -12,7 +12,7 @@ import { useNavigate } from "react-router-dom";
import darkThemeImage from "../../assets/image/darkThemeProject.png";
import lightThemeImage from "../../assets/image/lightThemeProject.png";
import { SettingsIcon, TrashIcon } from "../icons/ExportCommonIcons";
import { getUserData } from "./functions/getUserData";
import { getUserData } from "../../functions/getUserData";
import { useLoadingProgress, useSocketStore } from "../../store/builder/store";
import { createProject } from "../../services/dashboard/createProject";
@@ -42,7 +42,7 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
const projectId = generateProjectId();
useSocketStore.getState().initializeSocket(email, organization, token);
//API for creating new Project
// const project = await createProject(
// projectId,
@@ -57,11 +57,11 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
organization: organization,
projectUuid: projectId,
};
console.log("projectSocket: ", projectSocket);
// console.log("projectSocket: ", projectSocket);
if (projectSocket) {
// console.log('addProject: ', addProject);
const handleResponse = (data: any) => {
console.log('Project add response:', data);
// console.log('Project add response:', data);
if (data.message === "Project created successfully") {
setLoadingProgress(1)
navigate(`/${data.data.projectId}`);
@@ -70,7 +70,7 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
};
projectSocket.on("v1-project:response:add", handleResponse);
console.log('addProject: ', addProject);
// console.log('addProject: ', addProject);
projectSocket.emit("v1:project:add", addProject);
} else {
console.error("Socket is not connected.");
@@ -163,7 +163,10 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
<SettingsIcon />
Settings
</div>
<div className="option-list" style={{ cursor: "pointer" }}>
<div className="option-list" style={{ cursor: "pointer" }} onClick={() => {
localStorage.clear();
navigate("/");
}}>
<LogoutIcon />
Log out
</div>

View File

@@ -1,36 +0,0 @@
interface UserData {
email: string;
userId: string;
userName?: string; // Optional
organization: string;
}
export const getUserData = (): UserData => {
const email = localStorage.getItem("email");
const userId = localStorage.getItem("userId");
const userName = localStorage.getItem("userName");
if (!email || !userId) {
return {
email: '',
userId: '',
userName: '',
organization: '',
};
}
const [_, emailDomain] = email.split("@");
if (!emailDomain) {
throw new Error("Invalid email format");
}
const [organization] = emailDomain.split(".");
return {
email: email,
userId: userId,
userName: userName ?? undefined,
organization,
};
};

View File

@@ -1,7 +1,7 @@
import React, { useEffect } from 'react';
import { useSocketStore } from '../../../store/builder/store';
import { getUserData } from '../functions/getUserData';
import { getUserData } from '../../../functions/getUserData';
import { getAllProjects } from '../../../services/dashboard/getAllProjects';
import { recentlyViewed } from '../../../services/dashboard/recentlyViewed';
@@ -56,7 +56,7 @@ const ProjectSocketRes = ({
if (data?.message === "Project Duplicated successfully") {
if (setWorkspaceProjects) {
const allProjects = await getAllProjects(userId, organization);
console.log('allProjects: ', allProjects);
// console.log('allProjects: ', allProjects);
setWorkspaceProjects(allProjects);
} else if (setRecentProjects) {
const recentProjects = await recentlyViewed(organization, userId);

View File

@@ -8,15 +8,22 @@ import {
CurserRightIcon,
} from "../icons/LogIcons";
import ShortcutHelper from "./shortcutHelper";
import { useShortcutStore } from "../../store/builder/store";
import useVersionHistoryVisibleStore, { useShortcutStore } from "../../store/builder/store";
import { usePlayButtonStore } from "../../store/usePlayButtonStore";
import useModuleStore, { useSubModuleStore } from "../../store/useModuleStore";
import { useVersionContext } from "../../modules/builder/version/versionContext";
const Footer: React.FC = () => {
const { logs, setIsLogListVisible } = useLogger();
const lastLog = logs.length > 0 ? logs[logs.length - 1] : null;
const { setActiveModule } = useModuleStore();
const { setSubModule } = useSubModuleStore();
const { setVersionHistoryVisible } = useVersionHistoryVisibleStore();
const { isPlaying } = usePlayButtonStore();
const { showShortcuts, setShowShortcuts } = useShortcutStore();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
return (
<div className="footer-container">
@@ -61,8 +68,12 @@ const Footer: React.FC = () => {
)}
</button>
</div>
<div className="version">
V 0.01
<div className="version" onClick={() => {
setVersionHistoryVisible(true);
setSubModule("properties");
setActiveModule('builder');
}}>
{(selectedVersion?.version) ?? 'v 0.0.0'}
<div className="icon">
<HelpIcon />
</div>
@@ -72,11 +83,10 @@ const Footer: React.FC = () => {
{!isPlaying && (
<div
className={`shortcut-helper-overlay ${
showShortcuts ? "visible" : ""
}`}
className={`shortcut-helper-overlay ${showShortcuts ? "visible" : ""
}`}
>
<ShortcutHelper setShowShortcuts={setShowShortcuts}/>
<ShortcutHelper setShowShortcuts={setShowShortcuts} />
</div>
)}
</div>

View File

@@ -1,6 +1,5 @@
import { useProductContext } from '../../../modules/simulation/products/productContext'
import RegularDropDown from '../../ui/inputs/RegularDropDown';
import { useProductStore } from '../../../store/simulation/useProductStore';
import { useCompareProductDataStore, useLoadingProgress, useSaveVersion } from '../../../store/builder/store';
import useModuleStore from '../../../store/useModuleStore';
import CompareLayOut from '../../ui/compareVersion/CompareLayOut';
@@ -8,10 +7,14 @@ import ComparisonResult from '../../ui/compareVersion/ComparisonResult';
import { useComparisonProduct, useMainProduct } from '../../../store/simulation/useSimulationStore';
import { usePlayButtonStore } from '../../../store/usePlayButtonStore';
import { useEffect, useState } from 'react';
import { useVersionHistoryStore } from '../../../store/builder/useVersionHistoryStore';
import { useVersionContext } from '../../../modules/builder/version/versionContext';
import { useSceneContext } from '../../../modules/scene/sceneContext';
function ComparisonScene() {
const { isPlaying, setIsPlaying } = usePlayButtonStore();
const { products } = useProductStore();
const { isPlaying } = usePlayButtonStore();
const { productStore } = useSceneContext();
const { products } = productStore();
const { isVersionSaved } = useSaveVersion();
const { activeModule } = useModuleStore();
const { selectedProductStore } = useProductContext();
@@ -21,13 +24,30 @@ function ComparisonScene() {
const { loadingProgress } = useLoadingProgress();
const { compareProductsData, setCompareProductsData } = useCompareProductDataStore();
const [shouldShowComparisonResult, setShouldShowComparisonResult] = useState(false);
const { versionHistory } = useVersionHistoryStore();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion, setSelectedVersion } = selectedVersionStore();
const handleSelectLayout = (option: string) => {
const handleSelectVersion = (option: string) => {
const version = versionHistory.find((version) => version.versionName === option);
if (version) {
setSelectedVersion(version);
}
};
const handleSelectProduct = (option: string) => {
const product = products.find((product) => product.productName === option);
if (product) {
setComparisonProduct(product.productUuid, product.productName);
}
};
// useEffect(() => {
// if (versionHistory.length > 0) {
// setSelectedVersion(versionHistory[0])
// }
// }, [versionHistory])
// useEffect(() => {
// setCompareProductsData([
// {
@@ -57,7 +77,7 @@ function ComparisonScene() {
// }
// }
// ])
// }, []); // ✅ Runs only once on mount
// }, []);
useEffect(() => {
@@ -79,12 +99,19 @@ function ComparisonScene() {
<>
{isVersionSaved && activeModule === "simulation" && selectedProduct && (
<>
{comparisonProduct && !isPlaying &&
{selectedVersion && !isPlaying &&
<div className="initial-selectLayout-wrapper">
<RegularDropDown
header={selectedVersion.versionName}
options={versionHistory.map((v) => v.versionName)} // Pass layout names as options
onSelect={handleSelectVersion}
search={false}
/>
<br />
<RegularDropDown
header={selectedProduct.productName}
options={products.map((l) => l.productName)} // Pass layout names as options
onSelect={handleSelectLayout}
onSelect={handleSelectProduct}
search={false}
/>
</div>

View File

@@ -1,7 +1,16 @@
import { useEffect } from 'react';
import { ProductProvider } from '../../../modules/simulation/products/productContext'
import ComparisonScene from './ComparisonScene';
import { useSceneContext } from '../../../modules/scene/sceneContext';
function ComparisonSceneProvider() {
const { assetStore } = useSceneContext();
const { clearAssets } = assetStore();
useEffect(() => {
clearAssets();
}, [])
return (
<ProductProvider>
<ComparisonScene />

View File

@@ -30,15 +30,17 @@ import {
useMainProduct,
} from "../../../store/simulation/useSimulationStore";
import { useProductContext } from "../../../modules/simulation/products/productContext";
import { useProductStore } from "../../../store/simulation/useProductStore";
import RegularDropDown from "../../ui/inputs/RegularDropDown";
import RenameTooltip from "../../ui/features/RenameTooltip";
import { setFloorItemApi } from "../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi";
import { useAssetsStore } from "../../../store/builder/useAssetStore";
import { setAssetsApi } from "../../../services/factoryBuilder/assest/floorAsset/setAssetsApi";
import { useParams } from "react-router-dom";
import { useSceneContext } from "../../../modules/scene/sceneContext";
import { useVersionHistoryStore } from "../../../store/builder/useVersionHistoryStore";
import { useVersionContext } from "../../../modules/builder/version/versionContext";
import VersionSaved from "../sidebarRight/versionHisory/VersionSaved";
import Footer from "../../footer/Footer";
function MainScene() {
const { products } = useProductStore();
const { setMainProduct } = useMainProduct();
const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
@@ -54,9 +56,14 @@ function MainScene() {
const { setFloatingWidget } = useFloatingWidget();
const { clearComparisonProduct } = useComparisonProduct();
const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem();
const { setName } = useAssetsStore();
const { assetStore, productStore } = useSceneContext();
const { products } = productStore();
const { setName } = assetStore();
const { projectId } = useParams()
const { isRenameMode, setIsRenameMode } = useRenameModeStore();
const { versionHistory } = useVersionHistoryStore();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion, setSelectedVersion } = selectedVersionStore();
useEffect(() => {
if (activeModule !== 'simulation') {
@@ -65,22 +72,33 @@ function MainScene() {
}
}, [activeModule])
const handleSelectLayout = (option: string) => {
useEffect(() => {
if (versionHistory.length > 0) {
setSelectedVersion(versionHistory[0])
}
}, [versionHistory])
const handleSelectVersion = (option: string) => {
const version = versionHistory.find((version) => version.versionName === option);
if (version) {
setSelectedVersion(version);
}
};
const handleSelectProduct = (option: string) => {
const product = products.find((product) => product.productName === option);
if (product) {
setMainProduct(product.productUuid, product.productName);
}
};
const handleObjectRename = async (newName: string) => {
if (!projectId) return
const email = localStorage.getItem("email") ?? "";
const organization = email?.split("@")[1]?.split(".")[0];
let response = await setFloorItemApi(
organization,
selectedFloorItem.userData.modelUuid,
newName,
let response = await setAssetsApi({
modelUuid: selectedFloorItem.userData.modelUuid,
modelName: newName,
projectId
);
});
selectedFloorItem.userData = {
...selectedFloorItem.userData,
modelName: newName
@@ -98,7 +116,7 @@ function MainScene() {
{loadingProgress > 0 && <LoadingPage progress={loadingProgress} />}
{!isPlaying && (
<>
{toggleThreeD && <ModuleToggle />}
{toggleThreeD && !isVersionSaved && <ModuleToggle />}
<SideBarLeft />
<SideBarRight />
</>
@@ -137,6 +155,8 @@ function MainScene() {
selectedZone,
setFloatingWidget,
event,
projectId,
versionId: selectedVersion?.versionId || '',
})
}
onDragOver={(event) => event.preventDefault()}
@@ -144,16 +164,28 @@ function MainScene() {
<Scene layout="Main Layout" />
</div>
{selectedProduct && isVersionSaved && !isPlaying && activeModule === "simulation" && (
{selectedProduct && selectedVersion && isVersionSaved && !isPlaying && activeModule === "simulation" && (
<div className="selectLayout-wrapper">
<RegularDropDown
header={selectedVersion.versionName}
options={versionHistory.map((v) => v.versionName)} // Pass layout names as options
onSelect={handleSelectVersion}
search={false}
/>
<br />
<RegularDropDown
header={selectedProduct.productName}
options={products.map((l) => l.productName)} // Pass layout names as options
onSelect={handleSelectLayout}
onSelect={handleSelectProduct}
search={false}
/>
</div>
)}
{activeModule !== "market" && !selectedUser && <Footer />}
<VersionSaved />
</>
);
}

View File

@@ -1,7 +1,16 @@
import { useEffect } from 'react'
import { ProductProvider } from '../../../modules/simulation/products/productContext'
import MainScene from './MainScene'
import { useSceneContext } from '../../../modules/scene/sceneContext';
function MainSceneProvider() {
const { assetStore } = useSceneContext();
const { clearAssets } = assetStore();
useEffect(() => {
clearAssets();
}, [])
return (
<ProductProvider>
<MainScene />

View File

@@ -14,7 +14,7 @@ const Header: React.FC = () => {
return (
<div className="header-container">
<div className="header-content">
<button className="logo-container" onClick={()=>navigate("/Dashboard")}>
<button className="logo-container" onClick={() => navigate("/Dashboard")} title="Back to Dashboard">
<LogoIcon />
</button>
<div className="header-title">

View File

@@ -7,7 +7,7 @@ const Outline: React.FC = () => {
const handleSearchChange = (value: string) => {
setSearchValue(value);
console.log(value); // Log the search value if needed
// console.log(value); // Log the search value if needed
};
const dropdownItems = [

View File

@@ -30,7 +30,7 @@ const SideBarLeft: React.FC = () => {
const handleSearchChange = (value: string) => {
// Log the search value for now
console.log(value);
// console.log(value);
};
return (

View File

@@ -8,10 +8,11 @@ import { useSelectedUserStore } from "../../../store/collaboration/useCollabStor
import { useToggleStore } from "../../../store/useUIToggleStore";
import { ToggleSidebarIcon } from "../../icons/HeaderIcons";
import useModuleStore from "../../../store/useModuleStore";
import { getUserData } from "../../../functions/getUserData";
const Header: React.FC = () => {
const { activeUsers } = useActiveUsers();
const userName = localStorage.getItem("userName") ?? "Anonymous";
const { userName } = getUserData();
const { toggleUILeft, toggleUIRight, setToggleUI } = useToggleStore();
const { activeModule } = useModuleStore();
@@ -113,7 +114,7 @@ const Header: React.FC = () => {
))}
</div>
<div className="user-profile-container">
<div className="user-profile">{userName[0]}</div>
<div className="user-profile">{userName?.charAt(0).toUpperCase()}</div>
<div className="user-organization">
<img src={orgImg} alt="" />
</div>

View File

@@ -13,7 +13,7 @@ import { useToggleStore } from "../../../store/useUIToggleStore";
import Visualization from "./visualization/Visualization";
import Analysis from "./analysis/Analysis";
import Simulations from "./simulation/Simulations";
import useVersionHistoryStore, {
import useVersionHistoryVisibleStore, {
useSaveVersion,
useSelectedFloorItem,
useToolMode,
@@ -38,7 +38,7 @@ const SideBarRight: React.FC = () => {
const { selectedFloorItem } = useSelectedFloorItem();
const { selectedEventData } = useSelectedEventData();
const { selectedEventSphere } = useSelectedEventSphere();
const { viewVersionHistory, setVersionHistory } = useVersionHistoryStore();
const { viewVersionHistory, setVersionHistoryVisible } = useVersionHistoryVisibleStore();
const { isVersionSaved } = useSaveVersion();
// Reset activeList whenever activeModule changes
@@ -81,7 +81,7 @@ const SideBarRight: React.FC = () => {
}`}
onClick={() => {
setSubModule("properties");
setVersionHistory(false);
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">properties</div>
@@ -96,7 +96,7 @@ const SideBarRight: React.FC = () => {
}`}
onClick={() => {
setSubModule("simulations");
setVersionHistory(false);
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">simulations</div>
@@ -108,7 +108,7 @@ const SideBarRight: React.FC = () => {
}`}
onClick={() => {
setSubModule("mechanics");
setVersionHistory(false);
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">mechanics</div>
@@ -120,7 +120,7 @@ const SideBarRight: React.FC = () => {
}`}
onClick={() => {
setSubModule("analysis");
setVersionHistory(false);
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">analysis</div>

View File

@@ -24,7 +24,7 @@ const Vector3Input: React.FC<PositionInputProps> = ({
if (!value) return;
const updatedValue = [...value] as [number, number, number];
updatedValue[index] = parseFloat(newValue) || 0;
console.log('updatedValue: ', updatedValue);
// console.log('updatedValue: ', updatedValue);
onChange(updatedValue);
};

View File

@@ -20,6 +20,7 @@ import {
import { setEnvironment } from "../../../../services/factoryBuilder/environment/setEnvironment";
import * as CONSTANTS from "../../../../types/world/worldConstants";
import { useParams } from "react-router-dom";
import { getUserData } from "../../../../functions/getUserData";
const GlobalProperties: React.FC = () => {
const { toggleView, setToggleView } = useToggleView();
const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
@@ -38,14 +39,13 @@ const GlobalProperties: React.FC = () => {
const [limitGridDistance, setLimitGridDistance] = useState(false);
const [gridDistance, setGridDistance] = useState<number>(3);
const { projectId } = useParams();
const { email, userId, organization } = getUserData();
const optimizeScene = async (value: any) => {
const email = localStorage.getItem("email");
const organization = email?.split("@")[1]?.split(".")[0] || "defaultOrg";
setEnvironment(
organization,
localStorage.getItem("userId")!,
userId,
wallVisibility,
roofVisibility,
shadows,
@@ -58,13 +58,11 @@ const GlobalProperties: React.FC = () => {
};
const limitRenderDistance = async () => {
const email = localStorage.getItem("email");
const organization = email?.split("@")[1]?.split(".")[0] || "defaultOrg";
if (limitDistance) {
setEnvironment(
organization,
localStorage.getItem("userId")!,
userId,
wallVisibility,
roofVisibility,
shadows,
@@ -76,7 +74,7 @@ const GlobalProperties: React.FC = () => {
} else {
setEnvironment(
organization,
localStorage.getItem("userId")!,
userId,
wallVisibility,
roofVisibility,
shadows,
@@ -104,13 +102,11 @@ const GlobalProperties: React.FC = () => {
}
const updatedDist = async (value: number) => {
const email = localStorage.getItem("email");
const organization = email?.split("@")[1]?.split(".")[0] || "defaultOrg";
setRenderDistance(value);
// setDistance(value);
const data = await setEnvironment(
organization,
localStorage.getItem("userId")!,
userId,
wallVisibility,
roofVisibility,
shadows,
@@ -122,13 +118,11 @@ const GlobalProperties: React.FC = () => {
// Function to toggle roof visibility
const changeRoofVisibility = async () => {
const email = localStorage.getItem("email");
const organization = email!.split("@")[1].split(".")[0];
//using REST
const data = await setEnvironment(
organization,
localStorage.getItem("userId")!,
userId,
wallVisibility,
!roofVisibility,
shadows,
@@ -153,12 +147,10 @@ const GlobalProperties: React.FC = () => {
};
// Function to toggle wall visibility
const changeWallVisibility = async () => {
const email = localStorage.getItem("email");
const organization = email!.split("@")[1].split(".")[0];
//using REST
const data = await setEnvironment(
organization,
localStorage.getItem("userId")!,
userId,
!wallVisibility,
roofVisibility,
shadows,
@@ -182,12 +174,10 @@ const GlobalProperties: React.FC = () => {
};
const shadowVisibility = async () => {
const email = localStorage.getItem("email");
const organization = email!.split("@")[1].split(".")[0];
//using REST
const data = await setEnvironment(
organization,
localStorage.getItem("userId")!,
userId,
wallVisibility,
roofVisibility,
!shadows,

View File

@@ -10,6 +10,7 @@ import {
} from "../../../../store/builder/store";
import { zoneCameraUpdate } from "../../../../services/visulization/zone/zoneCameraUpdation";
import { useParams } from "react-router-dom";
import { getUserData } from "../../../../functions/getUserData";
const ZoneProperties: React.FC = () => {
const { Edit, setEdit } = useEditPosition();
@@ -17,7 +18,8 @@ const ZoneProperties: React.FC = () => {
const { zonePosition, setZonePosition } = usezonePosition();
const { zoneTarget, setZoneTarget } = usezoneTarget();
const { zones, setZones } = useZones();
const { projectId } = useParams()
const { projectId } = useParams();
const { userName, userId, organization, email } = getUserData();
useEffect(() => {
setZonePosition(selectedZone.zoneViewPortPosition);
@@ -26,8 +28,6 @@ const ZoneProperties: React.FC = () => {
async function handleSetView() {
try {
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
let zonesdata = {
zoneUuid: selectedZone.zoneUuid,
@@ -36,7 +36,7 @@ const ZoneProperties: React.FC = () => {
};
let response = await zoneCameraUpdate(zonesdata, organization, projectId);
console.log('response: ', response);
// console.log('response: ', response);
if (response.message === "zone updated") {
setEdit(false);
} else {
@@ -52,8 +52,6 @@ const ZoneProperties: React.FC = () => {
}
async function handleZoneNameChange(newName: string) {
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
const zonesdata = {
zoneUuid: selectedZone.zoneUuid,
zoneName: newName,

View File

@@ -3,7 +3,6 @@ import {
useSelectedEventData,
useSelectedEventSphere,
} from "../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../store/simulation/useProductStore";
import ConveyorMechanics from "./mechanics/conveyorMechanics";
import VehicleMechanics from "./mechanics/vehicleMechanics";
import RoboticArmMechanics from "./mechanics/roboticArmMechanics";
@@ -11,21 +10,22 @@ import MachineMechanics from "./mechanics/machineMechanics";
import StorageMechanics from "./mechanics/storageMechanics";
import { AddIcon } from "../../../../icons/ExportCommonIcons";
import { handleAddEventToProduct } from "../../../../../modules/simulation/events/points/functions/handleAddEventToProduct";
import { useEventsStore } from "../../../../../store/simulation/useEventsStore";
import { useProductContext } from "../../../../../modules/simulation/products/productContext";
import { useParams } from "react-router-dom";
import { useVersionContext } from "../../../../../modules/builder/version/versionContext";
import { useSceneContext } from "../../../../../modules/scene/sceneContext";
const EventProperties: React.FC = () => {
const { selectedEventData } = useSelectedEventData();
const { getEventByModelUuid } = useProductStore();
const { selectedProductStore } = useProductContext();
const { eventStore, productStore } = useSceneContext();
const { selectedProduct } = selectedProductStore();
const [currentEventData, setCurrentEventData] = useState<EventsSchema | null>(
null
);
const [currentEventData, setCurrentEventData] = useState<EventsSchema | null>(null);
const [assetType, setAssetType] = useState<string | null>(null);
const { products, addEvent } = useProductStore();
const { products, addEvent, getEventByModelUuid } = productStore();
const { selectedEventSphere } = useSelectedEventSphere();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const { projectId } = useParams();
useEffect(() => {
@@ -102,14 +102,15 @@ const EventProperties: React.FC = () => {
onClick={() => {
if (selectedEventData) {
handleAddEventToProduct({
event: useEventsStore
event: eventStore
.getState()
.getEventByModelUuid(
selectedEventData?.data.modelUuid
),
addEvent,
selectedProduct,
projectId: projectId || ''
projectId: projectId || '',
versionId: selectedVersion?.versionId || '',
});
}
}}

View File

@@ -13,23 +13,26 @@ type Material = {
textureName: string;
};
// Initial and default material
const initialMaterial: Material = {
texture: wallTexture1,
textureName: "Grunge Concrete Wall",
};
// Default and initial materials
const defaultMaterial: Material = {
texture: defaultTexture,
textureName: "Default Material",
};
const initialMaterial: Material = {
texture: wallTexture1,
textureName: "Grunge Concrete Wall",
};
const WallProperties = () => {
const { wallHeight, wallThickness, setWallHeight, setWallThickness } = useBuilderStore();
const [activeSide, setActiveSide] = useState<"side1" | "side2">("side1");
const [materials, setMaterials] = useState<Material[]>([initialMaterial]);
const [materials, setMaterials] = useState<Material[]>([
defaultMaterial,
initialMaterial,
]);
const [selectedMaterials, setSelectedMaterials] = useState<{
side1: Material | null;
@@ -39,11 +42,11 @@ const WallProperties = () => {
side2: null,
});
// Select initial material for both sides on mount
// Set default material initially for both sides
useEffect(() => {
setSelectedMaterials({
side1: initialMaterial,
side2: initialMaterial,
side1: defaultMaterial,
side2: defaultMaterial,
});
}, []);
@@ -71,21 +74,16 @@ const WallProperties = () => {
};
const handleRemoveMaterial = (index: number) => {
const updatedMaterials = materials.filter((_, i) => i !== index);
const removedTexture = materials[index].texture;
// Ensure there's always at least one material
const newMaterials =
updatedMaterials.length === 0 ? [defaultMaterial] : updatedMaterials;
const updatedMaterials = materials.filter((_, i) => i !== index);
const newMaterials = updatedMaterials.length === 0 ? [defaultMaterial] : updatedMaterials;
setMaterials(newMaterials);
// Deselect the material if it's the one removed
setSelectedMaterials((prev) => {
const updated = { ...prev };
["side1", "side2"].forEach((side) => {
if (
updated[side as "side1" | "side2"]?.texture ===
materials[index].texture
) {
if (updated[side as "side1" | "side2"]?.texture === removedTexture) {
updated[side as "side1" | "side2"] = defaultMaterial;
}
});
@@ -119,42 +117,43 @@ const WallProperties = () => {
<div className="material-preview">
<div className="sides-wrapper">
<div
className={`side-wrapper ${activeSide === "side1" ? "active" : ""
}`}
<button
className={`side-wrapper ${activeSide === "side1" ? "active" : ""}`}
onClick={() => setActiveSide("side1")}
>
<div className="label">Side 1</div>
<div className="texture-image">
{selectedMaterials.side1 && (
<img
draggable={false}
src={selectedMaterials.side1.texture}
alt={selectedMaterials.side1.textureName}
/>
)}
</div>
</div>
</button>
<div
className={`side-wrapper ${activeSide === "side2" ? "active" : ""
}`}
<button
className={`side-wrapper ${activeSide === "side2" ? "active" : ""}`}
onClick={() => setActiveSide("side2")}
>
<div className="label">Side 2</div>
<div className="texture-image">
{selectedMaterials.side2 && (
<img
draggable={false}
src={selectedMaterials.side2.texture}
alt={selectedMaterials.side2.textureName}
/>
)}
</div>
</div>
</button>
</div>
<div className="preview">
{selectedMaterials[activeSide] && (
<img
draggable={false}
src={selectedMaterials[activeSide]!.texture}
alt={selectedMaterials[activeSide]!.textureName}
/>
@@ -167,29 +166,37 @@ const WallProperties = () => {
<div className="no-materials">No materials added yet.</div>
) : (
<div className="material-container">
{materials.map((material, index) => (
<div
className="material-wrapper"
key={`${material.textureName}_${index}`}
onClick={() => handleSelectMaterial(material)}
>
<div className="material-property">
<div className="material-image">
<img src={material.texture} alt={material.textureName} />
</div>
<div className="material-name">{material.textureName}</div>
</div>
<div
className="delete-material"
onClick={(e) => {
e.stopPropagation();
handleRemoveMaterial(index);
}}
{materials.map((material, index) => {
const isSelected = selectedMaterials[activeSide]?.texture === material.texture;
return (
<button
className={`material-wrapper ${isSelected ? "selectedMaterial" : ""}`}
key={`${material.textureName}_${index}`}
onClick={() => handleSelectMaterial(material)}
>
<RemoveIcon />
</div>
</div>
))}
<div className="material-property">
<div className="material-image">
<img
draggable={false}
src={material.texture}
alt={material.textureName}
/>
</div>
<div className="material-name">{material.textureName}</div>
</div>
<button
className="delete-material"
onClick={(e) => {
e.stopPropagation();
handleRemoveMaterial(index);
}}
>
<RemoveIcon />
</button>
</button>
);
})}
</div>
)}
</div>

View File

@@ -9,10 +9,11 @@ import { handleResize } from "../../../../../../functions/handleResizePannel";
import {
useSelectedAction,
} from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
import { useParams } from "react-router-dom";
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
interface ActionsListProps {
selectedPointData: any;
@@ -30,10 +31,14 @@ const ActionsList: React.FC<ActionsListProps> = ({
const actionsContainerRef = useRef<HTMLDivElement>(null);
// store
const { renameAction } = useProductStore();
const { productStore } = useSceneContext();
const { renameAction } = productStore();
const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { selectedAction, setSelectedAction } = useSelectedAction();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const { projectId } = useParams();
const handleRenameAction = (newName: string) => {
@@ -50,6 +55,7 @@ const ActionsList: React.FC<ActionsListProps> = ({
productUuid: selectedProduct.productUuid,
projectId,
eventDatas: event,
versionId: selectedVersion?.versionId || '',
});
}
};

View File

@@ -9,21 +9,25 @@ import SpawnAction from "../actions/SpawnAction";
import DefaultAction from "../actions/DefaultAction";
import Trigger from "../trigger/Trigger";
import { useSelectedAction, useSelectedEventData } from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import ActionsList from "../components/ActionsList";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
import { useParams } from "react-router-dom";
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
function ConveyorMechanics() {
const [activeOption, setActiveOption] = useState<"default" | "spawn" | "swap" | "delay" | "despawn">("default");
const [selectedPointData, setSelectedPointData] = useState<ConveyorPointSchema | undefined>();
const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction } = useProductStore();
const { productStore } = useSceneContext();
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction } = productStore();
const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { setSelectedAction, clearSelectedAction } = useSelectedAction();
const { projectId } = useParams();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
useEffect(() => {
if (selectedEventData) {
@@ -52,7 +56,8 @@ function ConveyorMechanics() {
productName: productName,
productUuid: productUuid,
projectId: projectId,
eventDatas: eventData
eventDatas: eventData,
versionId: selectedVersion?.versionId || '',
})
}
@@ -66,7 +71,7 @@ function ConveyorMechanics() {
updateBackend(
selectedProduct.productName,
selectedProduct.productUuid,
projectId ||'',
projectId || '',
event
);
}
@@ -85,7 +90,7 @@ function ConveyorMechanics() {
updateBackend(
selectedProduct.productName,
selectedProduct.productUuid,
projectId ||'',
projectId || '',
event
);
}
@@ -99,7 +104,7 @@ function ConveyorMechanics() {
updateBackend(
selectedProduct.productName,
selectedProduct.productUuid,
projectId ||'',
projectId || '',
event
);
}
@@ -115,7 +120,7 @@ function ConveyorMechanics() {
updateBackend(
selectedProduct.productName,
selectedProduct.productUuid,
projectId ||'',
projectId || '',
event
);
}
@@ -131,7 +136,7 @@ function ConveyorMechanics() {
updateBackend(
selectedProduct.productName,
selectedProduct.productUuid,
projectId ||'',
projectId || '',
event
);
}
@@ -145,7 +150,7 @@ function ConveyorMechanics() {
updateBackend(
selectedProduct.productName,
selectedProduct.productUuid,
projectId ||'',
projectId || '',
event
);
}
@@ -161,7 +166,7 @@ function ConveyorMechanics() {
updateBackend(
selectedProduct.productName,
selectedProduct.productUuid,
projectId ||'',
projectId || '',
event
);
}

View File

@@ -3,22 +3,25 @@ import RenameInput from "../../../../../ui/inputs/RenameInput";
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import Trigger from "../trigger/Trigger";
import { useSelectedAction, useSelectedEventData } from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import ProcessAction from "../actions/ProcessAction";
import ActionsList from "../components/ActionsList";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
import { useParams } from "react-router-dom";
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
function MachineMechanics() {
const [activeOption, setActiveOption] = useState<"default" | "process">("default");
const [selectedPointData, setSelectedPointData] = useState<MachinePointSchema | undefined>();
const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, updateAction } = useProductStore();
const { productStore } = useSceneContext();
const { getPointByUuid, updateAction } = productStore();
const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { setSelectedAction, clearSelectedAction } = useSelectedAction();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const { projectId } = useParams();
useEffect(() => {
@@ -48,7 +51,8 @@ function MachineMechanics() {
productName: productName,
productUuid: productUuid,
projectId: projectId,
eventDatas: eventData
eventDatas: eventData,
versionId: selectedVersion?.versionId || '',
})
}

View File

@@ -5,22 +5,25 @@ import RenameInput from "../../../../../ui/inputs/RenameInput";
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import Trigger from "../trigger/Trigger";
import { useSelectedEventData, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import PickAndPlaceAction from "../actions/PickAndPlaceAction";
import ActionsList from "../components/ActionsList";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
import { useParams } from "react-router-dom";
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
function RoboticArmMechanics() {
const [activeOption, setActiveOption] = useState<"default" | "pickAndPlace">("default");
const [selectedPointData, setSelectedPointData] = useState<RoboticArmPointSchema | undefined>();
const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction, addAction, removeAction, } = useProductStore();
const { productStore } = useSceneContext();
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction, addAction, removeAction, } = productStore();
const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const { projectId } = useParams();
useEffect(() => {
@@ -58,6 +61,7 @@ function RoboticArmMechanics() {
productUuid: productUuid,
projectId: projectId,
eventDatas: eventData,
versionId: selectedVersion?.versionId || '',
});
};

View File

@@ -5,21 +5,24 @@ import Trigger from "../trigger/Trigger";
import StorageAction from "../actions/StorageAction";
import ActionsList from "../components/ActionsList";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import { useSelectedAction, useSelectedEventData } from "../../../../../../store/simulation/useSimulationStore";
import * as THREE from 'three';
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
import { useParams } from "react-router-dom";
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
function StorageMechanics() {
const [activeOption, setActiveOption] = useState<"default" | "store" | "spawn">("default");
const [selectedPointData, setSelectedPointData] = useState<StoragePointSchema | undefined>();
const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, updateAction } = useProductStore();
const { productStore } = useSceneContext();
const { getPointByUuid, updateAction } = productStore();
const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { setSelectedAction, clearSelectedAction } = useSelectedAction();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const { projectId } = useParams();
const updateSelectedPointData = () => {
@@ -66,7 +69,8 @@ function StorageMechanics() {
productName: productName,
productUuid: productUuid,
projectId: projectId,
eventDatas: eventData
eventDatas: eventData,
versionId: selectedVersion?.versionId || '',
})
}

View File

@@ -7,22 +7,25 @@ import {
useSelectedAction,
useSelectedEventData,
} from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import TravelAction from "../actions/TravelAction";
import ActionsList from "../components/ActionsList";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
import { useParams } from "react-router-dom";
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
function VehicleMechanics() {
const [activeOption, setActiveOption] = useState<"default" | "travel">("default");
const [selectedPointData, setSelectedPointData] = useState<VehiclePointSchema | undefined>();
const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction } = useProductStore();
const { productStore } = useSceneContext();
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction } = productStore();
const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { setSelectedAction, clearSelectedAction } = useSelectedAction();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const { projectId } = useParams();
useEffect(() => {
@@ -54,6 +57,7 @@ function VehicleMechanics() {
productUuid: productUuid,
projectId: projectId,
eventDatas: eventData,
versionId: selectedVersion?.versionId || '',
});
};

View File

@@ -4,11 +4,12 @@ import { AddIcon, RemoveIcon, ResizeHeightIcon } from "../../../../../icons/Expo
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import RenameInput from "../../../../../ui/inputs/RenameInput";
import { handleResize } from "../../../../../../functions/handleResizePannel";
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import { useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
import { useParams } from "react-router-dom";
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
type TriggerProps = {
selectedPointData?: PointsScheme | undefined;
@@ -19,13 +20,15 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
const [currentAction, setCurrentAction] = useState<string | undefined>();
const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { getActionByUuid, getEventByModelUuid, getPointByUuid, getTriggerByUuid, addTrigger, removeTrigger, updateTrigger, renameTrigger, getProductById, } = useProductStore();
const { productStore } = useSceneContext();
const { getActionByUuid, getEventByModelUuid, getPointByUuid, getTriggerByUuid, addTrigger, removeTrigger, updateTrigger, renameTrigger, getProductById, } = productStore();
const [triggers, setTriggers] = useState<TriggerSchema[]>([]);
const [selectedTrigger, setSelectedTrigger] = useState<TriggerSchema | undefined>();
const [activeOption, setActiveOption] = useState<"onComplete" | "onStart" | "onStop" | "delay" | "onError">("onComplete");
const triggersContainerRef = useRef<HTMLDivElement>(null);
const { selectedAction } = useSelectedAction();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const { projectId } = useParams();
useEffect(() => {
@@ -53,6 +56,7 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
productUuid: productUuid,
projectId: projectId,
eventDatas: eventData,
versionId: selectedVersion?.versionId || '',
});
};

View File

@@ -3,12 +3,10 @@ import { AddIcon, ArrowIcon, RemoveIcon, ResizeHeightIcon, } from "../../../icon
import RenameInput from "../../../ui/inputs/RenameInput";
import { handleResize } from "../../../../functions/handleResizePannel";
import { useMainProduct, useSelectedAsset } from "../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../store/simulation/useProductStore";
import { generateUUID } from "three/src/math/MathUtils";
import RenderOverlay from "../../../templates/Overlay";
import EditWidgetOption from "../../../ui/menu/EditWidgetOption";
import { handleAddEventToProduct } from "../../../../modules/simulation/events/points/functions/handleAddEventToProduct";
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
import { deleteEventDataApi } from "../../../../services/simulation/products/deleteEventDataApi";
import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi";
import { deleteProductApi } from "../../../../services/simulation/products/deleteProductApi";
@@ -19,6 +17,8 @@ import { useCompareStore, useSaveVersion, } from "../../../../store/builder/stor
import { useToggleStore } from "../../../../store/useUIToggleStore";
import { useProductContext } from "../../../../modules/simulation/products/productContext";
import { useParams } from "react-router-dom";
import { useVersionContext } from "../../../../modules/builder/version/versionContext";
import { useSceneContext } from "../../../../modules/scene/sceneContext";
interface Event {
modelName: string;
@@ -39,17 +39,19 @@ const List: React.FC<ListProps> = ({ val }) => {
const Simulations: React.FC = () => {
const productsContainerRef = useRef<HTMLDivElement>(null);
const { products, addProduct, removeProduct, renameProduct, addEvent, removeEvent, getProductById, } = useProductStore();
const { eventStore, productStore } = useSceneContext();
const { products, addProduct, removeProduct, renameProduct, addEvent, removeEvent, getProductById, } = productStore();
const { selectedProductStore } = useProductContext();
const { selectedProduct, setSelectedProduct } = selectedProductStore();
const { getEventByModelUuid } = useEventsStore();
const { getEventByModelUuid } = eventStore();
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
const [openObjects, setOpenObjects] = useState(true);
const [processes, setProcesses] = useState<Event[][]>();
const { setToggleUI } = useToggleStore();
const { projectId } = useParams();
const { setMainProduct } = useMainProduct();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const { comparePopUp, setComparePopUp } = useCompareStore();
const { setIsVersionSaved } = useSaveVersion();
@@ -67,6 +69,7 @@ const Simulations: React.FC = () => {
productName: name,
productUuid: id,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
});
};
@@ -99,13 +102,14 @@ const Simulations: React.FC = () => {
removeProduct(productUuid);
deleteProductApi({
productUuid,
versionId: selectedVersion?.versionId || '',
projectId
});
};
const handleRenameProduct = (productUuid: string, newName: string) => {
renameProduct(productUuid, newName);
renameProductApi({ productName: newName, productUuid, projectId: projectId || '' });
renameProductApi({ productName: newName, productUuid, projectId: projectId || '', versionId: selectedVersion?.versionId || '' });
if (selectedProduct.productUuid === productUuid) {
setSelectedProduct(productUuid, newName);
setMainProduct(productUuid, newName);
@@ -118,6 +122,7 @@ const Simulations: React.FC = () => {
deleteEventDataApi({
productUuid: selectedProduct.productUuid,
modelUuid: selectedAsset.modelUuid,
versionId: selectedVersion?.versionId || '',
projectId: projectId,
});
removeEvent(selectedProduct.productUuid, selectedAsset.modelUuid);
@@ -265,7 +270,8 @@ const Simulations: React.FC = () => {
addEvent,
selectedProduct,
clearSelectedAsset,
projectId: projectId || ''
projectId: projectId || '',
versionId: selectedVersion?.versionId || '',
});
} else {
handleRemoveEventFromProduct();

View File

@@ -1,147 +1,156 @@
import React, { useState } from "react";
import {
AddIcon,
ArrowIcon,
CloseIcon,
KebabIcon,
LocationIcon,
AddIcon,
ArrowIcon,
CloseIcon,
KebabIcon,
LocationIcon,
} from "../../../icons/ExportCommonIcons";
import RenameInput from "../../../ui/inputs/RenameInput";
import { useVersionStore } from "../../../../store/builder/store";
import { generateUniqueId } from "../../../../functions/generateUniqueId";
import { useVersionHistoryStore } from "../../../../store/builder/useVersionHistoryStore";
import { useSubModuleStore } from "../../../../store/useModuleStore";
import useVersionHistoryVisibleStore from "../../../../store/builder/store";
import { useParams } from "react-router-dom";
import { getVersionDataApi } from "../../../../services/factoryBuilder/versionControl/getVersionDataApi";
import { useVersionContext } from "../../../../modules/builder/version/versionContext";
const VersionHistory = () => {
const userName = localStorage.getItem("userName") ?? "Anonymous";
const { versions, addVersion, setVersions, updateVersion } =
useVersionStore();
const [selectedVersion, setSelectedVersion] = useState(
versions.length > 0 ? versions[0] : null
);
const { setSubModule } = useSubModuleStore();
const { setVersionHistoryVisible } = useVersionHistoryVisibleStore();
const { versionHistory, setCreateNewVersion } = useVersionHistoryStore();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion, setSelectedVersion } = selectedVersionStore();
const { projectId } = useParams();
const addNewVersion = () => {
const newVersion = {
id: generateUniqueId(),
versionLabel: `v${versions.length + 1}.0`,
versionName: "",
timestamp: new Date().toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "2-digit",
}),
savedBy: userName,
const addNewVersion = () => {
setCreateNewVersion(true);
};
const newVersions = [newVersion, ...versions];
addVersion(newVersion);
setSelectedVersion(newVersion);
setVersions(newVersions);
};
const handleSelectVersion = (version: Version) => {
if (!projectId) return;
const handleSelectVersion = (version: any) => {
setSelectedVersion(version);
const reordered = [version, ...versions.filter((v) => v.id !== version.id)];
setVersions(reordered);
};
getVersionDataApi(projectId, version.versionId).then((verdionData) => {
setSelectedVersion(version);
console.log(verdionData);
}).catch((err) => {
console.log(err);
})
};
const handleVersionNameChange = (newName: string, versionId: string) => {
const updated = versions.map((v) =>
v.id === versionId ? { ...v, versionName: newName } : v
);
setVersions(updated);
updateVersion(versionId, { versionName: newName });
};
const handleVersionNameChange = (newName: string, versionId: string) => {
return (
<div className="version-history-container">
{/* Header */}
<div className="version-history-header">
<div className="version-history-title">Version History</div>
<div className="version-history-icons">
<button
id="add-version"
className="icon add-icon"
onClick={addNewVersion}
>
<AddIcon />
</button>
<div id="version-kebab" className="icon kebab-icon">
<KebabIcon />
</div>
<div id="version-close" className="icon close-icon">
<CloseIcon />
</div>
</div>
</div>
};
{/* Shortcut Info */}
<div className="version-history-shortcut-info">
<div className="info-icon">i</div>
<div className="shortcut-text">
Press Ctrl + Alt + S to add to version history while editing
</div>
</div>
{/* Current Version Display */}
{selectedVersion && (
<div className="version-history-location">
<div className="location-label">
<LocationIcon />
</div>
<div className="location-details">
<div className="current-version">
Current Version ({selectedVersion.versionLabel})
</div>
<div className="saved-history-count">
{versions.length} Saved History
</div>
</div>
</div>
)}
{/* Versions List */}
<div className="saved-versions-list">
{versions.length === 0 ? (
<div className="no-versions-message">No saved versions</div>
) : (
versions.map((version) => (
<button
key={version.id}
className="saved-version"
onClick={() => handleSelectVersion(version)}
>
<div className="version-name">{version.versionLabel}</div>
<div className="version-details">
<div className="details">
<span className="timestamp">
{version.versionName ? (
<RenameInput
value={version.versionName}
onRename={(newName) =>
handleVersionNameChange(newName, version.id)
}
/>
) : (
<RenameInput
value={version.timestamp}
onRename={(newName) =>
handleVersionNameChange(newName, version.id)
}
/>
)}
</span>
<span className="saved-by">
<div className="user-profile">{version.savedBy[0]}</div>
<div className="user-name">{version.savedBy}</div>
</span>
return (
<div className="version-history-container">
{/* Header */}
<div className="version-history-header">
<div className="version-history-title">Version History</div>
<div className="version-history-icons">
<button
id="add-version"
className="icon add-icon"
onClick={addNewVersion}
>
<AddIcon />
</button>
<div id="version-kebab" className="icon kebab-icon">
<KebabIcon />
</div>
<div
id="version-close"
className="icon close-icon"
onClick={() => {
setSubModule("properties");
setVersionHistoryVisible(false);
}}
>
<CloseIcon />
</div>
</div>
<ArrowIcon />
</div>
</button>
))
)}
</div>
</div>
);
</div>
{/* Shortcut Info */}
<div className="version-history-shortcut-info">
<div className="info-icon">i</div>
<div className="shortcut-text">
Press Ctrl + Alt + S to add to version history while editing
</div>
</div>
{/* Current Version Display */}
{selectedVersion && (
<div className="version-history-location">
<div className="location-label">
<LocationIcon />
</div>
<div className="location-details">
<div className="current-version">
Current Version ({selectedVersion.version})
</div>
<div className="saved-history-count">
{versionHistory.length} Saved History
</div>
</div>
</div>
)}
{/* Versions List */}
<div className="saved-versions-list">
{versionHistory.length === 0 ? (
<div className="no-versions-message">No saved versions</div>
) : (
versionHistory.map((version) => {
const key = `version-${version.versionId}`;
return (
<VersionHistoryItem
key={key}
version={version}
onSelect={handleSelectVersion}
onRename={handleVersionNameChange}
/>
);
})
)}
</div>
</div>
);
};
export default VersionHistory;
type VersionHistoryItemProps = {
version: Version;
onSelect: (version: Version) => void;
onRename: (newName: string, versionId: string) => void;
};
const VersionHistoryItem: React.FC<VersionHistoryItemProps> = ({ version, onSelect, onRename }) => {
return (
<button
className="saved-version"
>
<div
className="version-name"
onClick={() => onSelect(version)}
>
v {version.version}
</div>
<div className="version-details">
<div className="details">
<span className="timestamp">
<RenameInput
value={version.versionName ? version.versionName : version.timeStamp}
onRename={(newName) => onRename(newName, version.versionId)}
/>
</span>
<span className="saved-by">
<div className="user-profile">{version.createdBy[0]}</div>
<div className="user-name">{version.createdBy}</div>
</span>
</div>
<ArrowIcon />
</div>
</button>
);
};

View File

@@ -1,148 +1,100 @@
import React, { useState, useEffect, useRef } from "react";
import { useVersionStore } from "../../../../store/builder/store";
import { useEffect, useState } from "react";
import {
CloseIcon,
FinishEditIcon,
RenameVersionIcon,
SaveIcon,
SaveVersionIcon,
} from "../../../icons/ExportCommonIcons";
import RenderOverlay from "../../../templates/Overlay";
import { useVersionHistoryStore } from "../../../../store/builder/useVersionHistoryStore";
import { createVersionApi } from "../../../../services/factoryBuilder/versionControl/addVersionApi";
import { useParams } from "react-router-dom";
import { getUserData } from "../../../../functions/getUserData";
import { useVersionContext } from "../../../../modules/builder/version/versionContext";
const VersionSaved = () => {
const { versions, updateVersion } = useVersionStore();
const [isEditing, setIsEditing] = useState(false);
const [shouldDismiss, setShouldDismiss] = useState(false);
const [showNotification, setShowNotification] = useState(false);
const [newName, setNewName] = useState("");
const { versionHistory, addVersion, createNewVersion, setCreateNewVersion } = useVersionHistoryStore();
const { selectedVersionStore } = useVersionContext();
const { setSelectedVersion } = selectedVersionStore();
const [newName, setNewName] = useState(new Date().toLocaleString("en-US", {
month: "short",
day: "numeric",
year: "numeric",
hour: "numeric",
minute: "2-digit",
}));
const [description, setDescription] = useState("");
const [showEditedFinish, setShowEditedFinish] = useState(false);
const [editedVersionName, setEditedVersionName] = useState("");
const prevVersionCount = useRef(versions.length);
const dismissTimerRef = useRef<NodeJS.Timeout | null>(null);
const [showSaveFinish, setSaveFinish] = useState(false);
const { projectId } = useParams();
const { userId } = getUserData();
const latestVersion = versions?.[0];
const latestVersion = versionHistory?.[0];
useEffect(() => {
return () => {
if (dismissTimerRef.current) clearTimeout(dismissTimerRef.current);
};
}, []);
useEffect(() => {
if (versions.length > prevVersionCount.current && latestVersion) {
setShowNotification(true);
setShouldDismiss(false);
setIsEditing(false);
setNewName(latestVersion.versionName ?? "");
setDescription(latestVersion.description ?? "");
setEditedVersionName(latestVersion.versionName ?? ""); // Initialize editedVersionName
if (!isEditing) {
startDismissTimer();
}
prevVersionCount.current = versions.length;
} else if (versions.length < prevVersionCount.current) {
prevVersionCount.current = versions.length;
if (createNewVersion) {
const defaultName = new Date().toLocaleString("en-US", {
month: "short",
day: "numeric",
year: "numeric",
hour: "numeric",
minute: "2-digit",
});
setNewName(defaultName);
setDescription("");
}
}, [versions, isEditing, latestVersion]);
}, [createNewVersion]);
const startDismissTimer = (delay = 5000) => {
if (dismissTimerRef.current) clearTimeout(dismissTimerRef.current);
dismissTimerRef.current = setTimeout(() => {
setShouldDismiss(true);
}, delay);
};
const handleSave = () => {
if (!latestVersion || !projectId) return;
useEffect(() => {
if (shouldDismiss) {
const timer = setTimeout(() => setShowNotification(false), 200);
return () => clearTimeout(timer);
}
}, [shouldDismiss]);
const updatedName = (newName.trim() || latestVersion.versionName) ?? latestVersion.timeStamp;
const updatedDescription = (description.trim() || latestVersion.versionName) ?? latestVersion.timeStamp;
const handleEditName = () => {
if (!latestVersion) return;
createVersionApi(projectId, userId, latestVersion.versionId, updatedName, updatedDescription).then((data) => {
setSaveFinish(true);
setCreateNewVersion(false);
setIsEditing(true);
setNewName(latestVersion.versionName ?? "");
setDescription(latestVersion.description ?? "");
if (dismissTimerRef.current) {
clearTimeout(dismissTimerRef.current);
dismissTimerRef.current = null;
}
};
addVersion({
version: data.version,
versionId: data.versionId,
versionName: data.versionName,
versionDescription: data.description,
timeStamp: data.createdAt,
createdBy: data.createdBy.userName
})
const handleFinishEdit = () => {
if (!latestVersion) return;
setSelectedVersion({
version: data.version,
versionId: data.versionId,
versionName: data.versionName,
versionDescription: data.description,
timeStamp: data.createdAt,
createdBy: data.createdBy.userName
})
const updatedName =
(newName.trim() || latestVersion.versionName) ?? latestVersion.timestamp;
updateVersion(latestVersion.id, {
versionName: updatedName,
description,
});
setEditedVersionName(updatedName);
setIsEditing(false);
setShowEditedFinish(true);
setTimeout(() => {
setShowEditedFinish(false);
}, 5000);
startDismissTimer();
setTimeout(() => {
setSaveFinish(false);
}, 3000);
}).catch((err) => {
setSaveFinish(false);
setCreateNewVersion(false);
})
};
const handleCancel = () => {
setIsEditing(false);
startDismissTimer();
setSaveFinish(false);
setCreateNewVersion(false);
};
const handleClose = () => {
setShouldDismiss(true);
if (dismissTimerRef.current) clearTimeout(dismissTimerRef.current);
};
if (!showNotification || !latestVersion) return null;
if (!latestVersion) return null;
return (
<div className={`versionSaved ${shouldDismiss ? "dismissing" : ""}`}>
{!isEditing && !showEditedFinish && (
<div className="versionSaved-wrapper">
<div className="version-header">
<div className="header-wrapper">
<div className="icon">
<SaveIcon />
</div>
<span>Saved New Version</span>
</div>
<button className="close-btn" onClick={handleClose}>
<CloseIcon />
</button>
</div>
<div className="version-details">
<SaveVersionIcon />
<div className="details">
<div className="details-wrapper">
New Version Created {latestVersion.versionLabel}{" "}
{latestVersion.timestamp.toUpperCase()}
</div>
<button onClick={handleEditName}>Edit name</button>
</div>
</div>
</div>
)}
{isEditing && (
<div className={`versionSaved`}>
{createNewVersion &&
<RenderOverlay>
<div className="edit-version-popup-wrapper">
<div className="details-wrapper-popup-container">
<div className="header-wrapper">
<RenameVersionIcon />
<div className="label">Rename Version</div>
<div className="label">Create Version</div>
</div>
<div className="details-wrapper">
<div className="version-name">
@@ -153,13 +105,10 @@ const VersionSaved = () => {
placeholder="Enter new version name"
/>
<div className="label">
by @{latestVersion.savedBy}{" "}
{new Date(latestVersion.timestamp).toLocaleString("en-US", {
month: "short",
day: "numeric",
year: "2-digit",
hour: "numeric",
minute: "2-digit",
by @{latestVersion.createdBy}{" "}{new Date(latestVersion.timeStamp).toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "2-digit",
})}
</div>
</div>
@@ -176,16 +125,16 @@ const VersionSaved = () => {
<button className="cancel" onClick={handleCancel}>
Cancel
</button>
<button className="save" onClick={handleFinishEdit}>
<button className="save" onClick={handleSave}>
Save
</button>
</div>
</div>
</div>
</RenderOverlay>
)}
}
{showEditedFinish && (
{showSaveFinish && (
<RenderOverlay>
<div className="finishEdit-version-popup-wrapper">
<div className="finishEdit-wrapper-popup-container">
@@ -193,7 +142,7 @@ const VersionSaved = () => {
<FinishEditIcon />
</div>
<div className="versionname">
{editedVersionName || latestVersion.versionName}
{newName.trim()}
</div>
<div className="success-message">Saved Successfully!</div>
</div>

View File

@@ -9,6 +9,9 @@ import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
import { useParams } from "react-router-dom";
import { useSocketStore } from "../../../../../store/builder/store";
import { getUserData } from "../../../../../functions/getUserData";
import { addingWidgets } from "../../../../../services/visulization/zone/addWidgets";
import { useVersionContext } from "../../../../../modules/builder/version/versionContext";
type Props = {};
@@ -23,12 +26,12 @@ const BarChartInput = (props: Props) => {
const { selectedZone } = useSelectedZoneStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
const { userName, userId, organization, email } = getUserData();
const [isLoading, setLoading] = useState<boolean>(true);
const { projectId } = useParams();
const { visualizationSocket } = useSocketStore();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
useEffect(() => {
const fetchZoneData = async () => {
@@ -36,15 +39,15 @@ const BarChartInput = (props: Props) => {
setLoading(true);
const response = await axios.get(`http://${iotApiUrl}/floatinput`);
if (response.status === 200) {
// console.log("dropdown data:", response.data);
//
setDropDownData(response.data);
setLoading(false);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
echo.log("Failed to fetch zone data");
console.error("There was an error!", error);
}
};
fetchZoneData();
@@ -55,7 +58,7 @@ const BarChartInput = (props: Props) => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/data?widgetID=${selectedChartId.id}&zoneUuid=${selectedZone.zoneUuid}&projectId=${projectId}`,
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/data?widgetID=${selectedChartId.id}&zoneUuid=${selectedZone.zoneUuid}&projectId=${projectId}&versionId=${selectedVersion?.versionId || ""}`,
{
headers: {
Authorization: "Bearer <access_token>",
@@ -66,15 +69,16 @@ const BarChartInput = (props: Props) => {
}
);
if (response.status === 200) {
setSelections(response.data.Data.measurements);
setDuration(response.data.Data.duration);
setSelections(response.data.Datastructure.measurements);
setDuration(response.data.Datastructure.duration);
setWidgetName(response.data.widgetName);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch saved inputs");
console.error("There was an error!", error);
}
}
};
@@ -95,15 +99,15 @@ const BarChartInput = (props: Props) => {
inputName: any
) => {
// const userId = localStorage.getItem("userId");
// let newWidget = {
// id: selectedChartId.id,
// panel: selectedChartId.panel,
// widgetName: inputName,
// Data: {
// measurements: inputMeasurement,
// duration: inputDuration,
// }
// }
let newWidget = {
id: selectedChartId.id,
panel: selectedChartId.panel,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
}
}
// const adding3dWidget = {
// organization: organization,
// widget: newWidget,
@@ -112,43 +116,49 @@ const BarChartInput = (props: Props) => {
// };
// if (visualizationSocket) {
// visualizationSocket.emit("v1:viz-3D-widget:add", adding3dWidget);
// }
try {
const response = await axios.post(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/save`,
{
headers: {
Authorization: "Bearer <access_token>",
"Content-Type": "application/json",
token: localStorage.getItem("token") || "",
refresh_token: localStorage.getItem("refreshToken") || "",
},
},
{
organization: organization,
zoneUuid: selectedZone.zoneUuid,
widget: {
id: selectedChartId.id,
panel: selectedChartId.panel,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
},
},
} as any
);
if (response.status === 200) {
return true;
} else {
console.log("Unexpected response:", response);
return false;
}
} catch (error) {
echo.error("Failed to send input");
console.error("There was an error!", error);
let response = await addingWidgets(selectedZone.zoneUuid, organization, newWidget,projectId);
if(response.message==="Widget updated successfully"){
return true;
}else{
return false;
}
};
// try {
// const response = await axios.post(
// `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/save`,
// {
// headers: {
// Authorization: "Bearer <access_token>",
// "Content-Type": "application/json",
// token: localStorage.getItem("token") || "",
// refresh_token: localStorage.getItem("refreshToken") || "",
// },
// },
// {
// zoneUuid: selectedZone.zoneUuid,
// organization: organization,
// widget: {
// id: selectedChartId.id,
// panel: selectedChartId.panel,
// widgetName: inputName,
// Data: {
// measurements: inputMeasurement,
// duration: inputDuration,
// },
// },
// } as any
// );
// } catch (error) {
// echo.error("Failed to send input");
//
// return false;
// }
};
const handleSelect = async (
@@ -163,7 +173,7 @@ const BarChartInput = (props: Props) => {
newSelections[inputKey] = selectedData;
}
// setMeasurements(newSelections); // Update Zustand store
// console.log(newSelections);
//
if (await sendInputes(newSelections, duration, widgetName)) {
setSelections(newSelections);
}
@@ -180,7 +190,7 @@ const BarChartInput = (props: Props) => {
};
const handleNameChange = async (name: any) => {
console.log("name change requested", name);
if (await sendInputes(selections, duration, name)) {
setWidgetName(name);

View File

@@ -7,6 +7,9 @@ import { useSelectedZoneStore } from "../../../../../store/visualization/useZone
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
import { getUserData } from "../../../../../functions/getUserData";
import { addingFloatingWidgets } from "../../../../../services/visulization/zone/addFloatingWidgets";
import { useParams } from "react-router-dom";
type Props = {};
@@ -22,11 +25,12 @@ const FleetEfficiencyInputComponent = (props: Props) => {
const { selectedZone } = useSelectedZoneStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
const { userName, userId, organization, email } = getUserData();
const [isLoading, setLoading] = useState<boolean>(true);
const isSelected = () => {};
const { projectId } = useParams()
const isSelected = () => { };
useEffect(() => {
const fetchZoneData = async () => {
@@ -38,7 +42,7 @@ const FleetEfficiencyInputComponent = (props: Props) => {
setDropDownData(response.data);
setLoading(false);
} else {
console.log("Unexpected response:", response);
// console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch zone data");
@@ -53,14 +57,22 @@ const FleetEfficiencyInputComponent = (props: Props) => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${selectedChartId.id}/${organization}`
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${selectedChartId.id}/${organization}`,
{
headers: {
Authorization: "Bearer <access_token>",
"Content-Type": "application/json",
token: localStorage.getItem("token") || "",
refresh_token: localStorage.getItem("refreshToken") || "",
},
}
);
if (response.status === 200) {
setSelections(response.data.Data.measurements);
setDuration(response.data.Data.duration);
setWidgetName(response.data.header);
} else {
console.log("Unexpected response:", response);
// console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch saved inputs");
@@ -85,34 +97,51 @@ const FleetEfficiencyInputComponent = (props: Props) => {
inputDuration: any,
inputName: any
) => {
try {
const response = await axios.post(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/floatWidget/save`,
{
organization: organization,
zoneUuid: selectedZone.zoneUuid,
widget: {
id: selectedChartId.id,
header: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
},
},
} as any
);
if (response.status === 200) {
return true;
} else {
console.log("Unexpected response:", response);
return false;
}
} catch (error) {
echo.error("Failed to send input");
console.error("There was an error!", error);
let newWidget = {
id: selectedChartId.id,
header: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
},
}
const response = await addingFloatingWidgets(selectedZone.zoneUuid, organization, newWidget, projectId)
// console.log('response: ', response);
if (response.message === "Widget updated successfully") {
return true;
} else {
console.log("Unexpected response:", response);
return false;
}
// try {
// const response = await axios.post(
// `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/floatWidget/save`,
// {
// organization: organization,
// zoneUuid: selectedZone.zoneUuid,
// widget: {
// id: selectedChartId.id,
// header: inputName,
// Data: {
// measurements: inputMeasurement,
// duration: inputDuration,
// },
// },
// } as any
// );
// if (response.status === 200) {
// return true;
// } else {
// console.log("Unexpected response:", response);
// return false;
// }
// } catch (error) {
// echo.error("Failed to send input");
// console.error("There was an error!", error);
// return false;
// }
};
const handleSelect = async (

View File

@@ -7,6 +7,9 @@ import { useSelectedZoneStore } from "../../../../../store/visualization/useZone
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
import { getUserData } from "../../../../../functions/getUserData";
import { addingFloatingWidgets } from "../../../../../services/visulization/zone/addFloatingWidgets";
import { useParams } from "react-router-dom";
type Props = {};
@@ -22,9 +25,9 @@ const FlotingWidgetInput = (props: Props) => {
const { selectedZone } = useSelectedZoneStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
const { userName, userId, organization, email } = getUserData();
const [isLoading, setLoading] = useState<boolean>(true);
const { projectId } = useParams()
useEffect(() => {
const fetchZoneData = async () => {
@@ -36,7 +39,7 @@ const FlotingWidgetInput = (props: Props) => {
setDropDownData(response.data);
setLoading(false);
} else {
console.log("Unexpected response:", response);
// console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch zone data");
@@ -52,14 +55,22 @@ const FlotingWidgetInput = (props: Props) => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${selectedChartId.id}/${organization}`
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${selectedChartId.id}/${organization}`,
{
headers: {
Authorization: "Bearer <access_token>",
"Content-Type": "application/json",
token: localStorage.getItem("token") || "",
refresh_token: localStorage.getItem("refreshToken") || "",
},
}
);
if (response.status === 200) {
setSelections(response.data.Data.measurements);
setDuration(response.data.Data.duration);
setWidgetName(response.data.header);
} else {
console.log("Unexpected response:", response);
// console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch saved inputs");
@@ -84,34 +95,51 @@ const FlotingWidgetInput = (props: Props) => {
inputDuration: any,
inputName: any
) => {
try {
const response = await axios.post(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/floatWidget/save`,
{
organization: organization,
zoneUuid: selectedZone.zoneUuid,
widget: {
id: selectedChartId.id,
header: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
},
},
} as any
);
if (response.status === 200) {
return true;
} else {
console.log("Unexpected response:", response);
return false;
}
} catch (error) {
echo.error("Failed to send input");
let newWidget = {
id: selectedChartId.id,
header: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
},
}
console.error("There was an error!", error);
const response = await addingFloatingWidgets(selectedZone.zoneUuid, organization, newWidget, projectId)
// console.log('response: ', response);
if (response.message === "Widget updated successfully") {
return true;
} else {
// console.log("Unexpected response:", response);
return false;
}
// try {
// const response = await axios.post(
// `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/floatWidget/save`,
// {
// organization: organization,
// zoneUuid: selectedZone.zoneUuid,
// widget: {
// id: selectedChartId.id,
// header: inputName,
// Data: {
// measurements: inputMeasurement,
// duration: inputDuration,
// },
// },
// } as any
// );
// if (response.status === 200) {
// return true;
// } else {
// console.log("Unexpected response:", response);
// return false;
// }
// } catch (error) {
// echo.error("Failed to send input");
// console.error("There was an error!", error);
// return false;
// }
};
const handleSelect = async (

View File

@@ -23,20 +23,20 @@
// try {
// const response = await axios.get(`http://${iotApiUrl}/getinput`);
// if (response.status === 200) {
// console.log('dropdown data:', response.data);
//
// setDropDownData(response.data)
// } else {
// console.log('Unexpected response:', response);
//
// }
// } catch (error) {
// console.error('There was an error!', error);
//
// }
// };
// fetchZoneData();
// }, []);
// useEffect(() => {
// console.log(selections);
//
// }, [selections])
// const handleSelect = (inputKey: string, selectedData: { name: string, fields: string } | null) => {
@@ -125,6 +125,9 @@ import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
import { useParams } from "react-router-dom";
import { useSocketStore } from "../../../../../store/builder/store";
import { getUserData } from "../../../../../functions/getUserData";
import { addingWidgets } from "../../../../../services/visulization/zone/addWidgets";
import { useVersionContext } from "../../../../../modules/builder/version/versionContext";
type Props = {};
@@ -139,11 +142,12 @@ const LineGrapInput = (props: Props) => {
const { selectedZone } = useSelectedZoneStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
const { userName, userId, organization, email } = getUserData();
const [isLoading, setLoading] = useState<boolean>(true);
const { projectId } = useParams();
const { visualizationSocket } = useSocketStore();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
useEffect(() => {
const fetchZoneData = async () => {
@@ -151,15 +155,15 @@ const LineGrapInput = (props: Props) => {
setLoading(true);
const response = await axios.get(`http://${iotApiUrl}/floatinput`);
if (response.status === 200) {
// console.log("dropdown data:", response.data);
//
setDropDownData(response.data);
setLoading(false);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch zone data");
console.error("There was an error!", error);
}
};
fetchZoneData();
@@ -170,7 +174,7 @@ const LineGrapInput = (props: Props) => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/data?widgetID=${selectedChartId.id}&zoneUuid=${selectedZone.zoneUuid}&projectId=${projectId}`,
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/data?widgetID=${selectedChartId.id}&zoneUuid=${selectedZone.zoneUuid}&projectId=${projectId}&versionId=${selectedVersion?.versionId || ""}`,
{
headers: {
Authorization: "Bearer <access_token>",
@@ -181,15 +185,16 @@ const LineGrapInput = (props: Props) => {
}
);
if (response.status === 200) {
setSelections(response.data.Data.measurements);
setDuration(response.data.Data.duration);
setSelections(response.data.Datastructure.measurements);
setDuration(response.data.Datastructure.duration);
setWidgetName(response.data.widgetName);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch saved inputs");
console.error("There was an error!", error);
}
}
};
@@ -210,15 +215,16 @@ const LineGrapInput = (props: Props) => {
inputName: any
) => {
// const userId = localStorage.getItem("userId");
// let newWidget = {
// id: selectedChartId.id,
// panel: selectedChartId.panel,
// widgetName: inputName,
// Data: {
// measurements: inputMeasurement,
// duration: inputDuration,
// }
// }
let newWidget = {
id: selectedChartId.id,
panel: selectedChartId.panel,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
}
}
// const adding3dWidget = {
// organization: organization,
// widget: newWidget,
@@ -228,42 +234,46 @@ const LineGrapInput = (props: Props) => {
// if (visualizationSocket) {
// visualizationSocket.emit("v1:viz-3D-widget:add", adding3dWidget);
// }
try {
const response = await axios.post(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/save`,
{
headers: {
Authorization: "Bearer <access_token>",
"Content-Type": "application/json",
token: localStorage.getItem("token") || "",
refresh_token: localStorage.getItem("refreshToken") || "",
},
},
{
organization: organization,
zoneUuid: selectedZone.zoneUuid,
widget: {
id: selectedChartId.id,
panel: selectedChartId.panel,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
},
},
} as any
);
if (response.status === 200) {
return true;
} else {
console.log("Unexpected response:", response);
return false;
}
} catch (error) {
echo.error("Failed to send input");
console.error("There was an error!", error);
let response = await addingWidgets(selectedZone.zoneUuid, organization, newWidget, projectId);
if (response.message === "Widget updated successfully") {
return true;
} else {
return false;
}
// try {
// const response = await axios.post(
// `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/save`,
// {
// headers: {
// Authorization: "Bearer <access_token>",
// "Content-Type": "application/json",
// token: localStorage.getItem("token") || "",
// refresh_token: localStorage.getItem("refreshToken") || "",
// },
// },
// {
// zoneUuid: selectedZone.zoneUuid,
// organization: organization,
// widget: {
// id: selectedChartId.id,
// panel: selectedChartId.panel,
// widgetName: inputName,
// Data: {
// measurements: inputMeasurement,
// duration: inputDuration,
// },
// },
// } as any
// );
// } catch (error) {
// echo.error("Failed to send input");
//
// return false;
// }
};
const handleSelect = async (
@@ -278,7 +288,7 @@ const LineGrapInput = (props: Props) => {
newSelections[inputKey] = selectedData;
}
// setMeasurements(newSelections); // Update Zustand store
// console.log(newSelections);
//
if (await sendInputes(newSelections, duration, widgetName)) {
setSelections(newSelections);
}
@@ -295,7 +305,7 @@ const LineGrapInput = (props: Props) => {
};
const handleNameChange = async (name: any) => {
console.log("name change requested", name);
if (await sendInputes(selections, duration, name)) {
setWidgetName(name);

View File

@@ -9,6 +9,9 @@ import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
import { useParams } from "react-router-dom";
import { useSocketStore } from "../../../../../store/builder/store";
import { getUserData } from "../../../../../functions/getUserData";
import { addingWidgets } from "../../../../../services/visulization/zone/addWidgets";
import { useVersionContext } from "../../../../../modules/builder/version/versionContext";
type Props = {};
@@ -23,12 +26,12 @@ const PieChartInput = (props: Props) => {
const { selectedZone } = useSelectedZoneStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
const { userName, userId, organization, email } = getUserData();
const [isLoading, setLoading] = useState<boolean>(true);
const { projectId } = useParams();
const { visualizationSocket } = useSocketStore();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
useEffect(() => {
const fetchZoneData = async () => {
@@ -36,15 +39,15 @@ const PieChartInput = (props: Props) => {
setLoading(true);
const response = await axios.get(`http://${iotApiUrl}/floatinput`);
if (response.status === 200) {
// console.log("dropdown data:", response.data);
//
setDropDownData(response.data);
setLoading(false);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch zone data");
console.error("There was an error!", error);
}
};
fetchZoneData();
@@ -55,7 +58,7 @@ const PieChartInput = (props: Props) => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/data?widgetID=${selectedChartId.id}&zoneUuid=${selectedZone.zoneUuid}&projectId=${projectId}`,
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/data?widgetID=${selectedChartId.id}&zoneUuid=${selectedZone.zoneUuid}&projectId=${projectId}&versionId=${selectedVersion?.versionId || ""}`,
{
headers: {
Authorization: "Bearer <access_token>",
@@ -66,15 +69,16 @@ const PieChartInput = (props: Props) => {
}
);
if (response.status === 200) {
setSelections(response.data.Data.measurements);
setDuration(response.data.Data.duration);
setSelections(response.data.Datastructure.measurements);
setDuration(response.data.Datastructure.duration);
setWidgetName(response.data.widgetName);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch saved inputs");
console.error("There was an error!", error);
}
}
};
@@ -96,15 +100,15 @@ const PieChartInput = (props: Props) => {
) => {
// const userId = localStorage.getItem("userId");
// let newWidget = {
// id: selectedChartId.id,
// panel: selectedChartId.panel,
// widgetName: inputName,
// Data: {
// measurements: inputMeasurement,
// duration: inputDuration,
// },
// }
let newWidget = {
id: selectedChartId.id,
panel: selectedChartId.panel,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
},
}
// const adding3dWidget = {
// organization: organization,
// widget: newWidget,
@@ -114,42 +118,48 @@ const PieChartInput = (props: Props) => {
// if (visualizationSocket) {
// visualizationSocket.emit("v1:viz-3D-widget:add", adding3dWidget);
// }
try {
const response = await axios.post(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/save`,
{
headers: {
Authorization: "Bearer <access_token>",
"Content-Type": "application/json",
token: localStorage.getItem("token") || "",
refresh_token: localStorage.getItem("refreshToken") || "",
},
},
{
organization: organization,
zoneUuid: selectedZone.zoneUuid,
widget: {
id: selectedChartId.id,
panel: selectedChartId.panel,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
},
},
} as any
);
if (response.status === 200) {
return true;
} else {
console.log("Unexpected response:", response);
return false;
}
} catch (error) {
echo.error("Failed to send input");
console.error("There was an error!", error);
let response = await addingWidgets(selectedZone.zoneUuid, organization, newWidget, projectId);
if (response.message === "Widget updated successfully") {
return true;
} else {
return false;
}
// try {
// const response = await axios.post(
// `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/save`,
// {
// headers: {
// Authorization: "Bearer <access_token>",
// "Content-Type": "application/json",
// token: localStorage.getItem("token") || "",
// refresh_token: localStorage.getItem("refreshToken") || "",
// },
// },
// {
// zoneUuid: selectedZone.zoneUuid,
// organization: organization,
// widget: {
// id: selectedChartId.id,
// panel: selectedChartId.panel,
// widgetName: inputName,
// Data: {
// measurements: inputMeasurement,
// duration: inputDuration,
// },
// },
// } as any
// );
// } catch (error) {
// echo.error("Failed to send input");
//
// return false;
// }
};
const handleSelect = async (
@@ -164,7 +174,7 @@ const PieChartInput = (props: Props) => {
newSelections[inputKey] = selectedData;
}
// setMeasurements(newSelections); // Update Zustand store
// console.log(newSelections);
//
if (await sendInputes(newSelections, duration, widgetName)) {
setSelections(newSelections);
}
@@ -181,7 +191,7 @@ const PieChartInput = (props: Props) => {
};
const handleNameChange = async (name: any) => {
console.log("name change requested", name);
if (await sendInputes(selections, duration, name)) {
setWidgetName(name);

View File

@@ -9,6 +9,9 @@ import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
import { useParams } from "react-router-dom";
import { useSocketStore } from "../../../../../store/builder/store";
import { getUserData } from "../../../../../functions/getUserData";
import { addingWidgets } from "../../../../../services/visulization/zone/addWidgets";
import { useVersionContext } from "../../../../../modules/builder/version/versionContext";
type Props = {};
@@ -23,12 +26,12 @@ const Progress1Input = (props: Props) => {
const { selectedZone } = useSelectedZoneStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
const { userName, userId, organization, email } = getUserData();
const [isLoading, setLoading] = useState<boolean>(true);
const { projectId } = useParams();
const { visualizationSocket } = useSocketStore();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
useEffect(() => {
const fetchZoneData = async () => {
@@ -36,15 +39,15 @@ const Progress1Input = (props: Props) => {
setLoading(true);
const response = await axios.get(`http://${iotApiUrl}/floatinput`);
if (response.status === 200) {
// console.log("dropdown data:", response.data);
//
setDropDownData(response.data);
setLoading(false);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch zone data");
console.error("There was an error!", error);
}
};
fetchZoneData();
@@ -55,7 +58,7 @@ const Progress1Input = (props: Props) => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/data?widgetID=${selectedChartId.id}&zoneUuid=${selectedZone.zoneUuid}&projectId=${projectId}`,
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/data?widgetID=${selectedChartId.id}&zoneUuid=${selectedZone.zoneUuid}&projectId=${projectId}&versionId=${selectedVersion?.versionId || ""}`,
{
headers: {
Authorization: "Bearer <access_token>",
@@ -66,15 +69,16 @@ const Progress1Input = (props: Props) => {
}
);
if (response.status === 200) {
setSelections(response.data.Data.measurements);
setDuration(response.data.Data.duration);
setSelections(response.data.Datastructure.measurements);
setDuration(response.data.Datastructure.duration);
setWidgetName(response.data.widgetName);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch saved inputs");
console.error("There was an error!", error);
}
}
};
@@ -95,15 +99,15 @@ const Progress1Input = (props: Props) => {
inputName: any
) => {
// const userId = localStorage.getItem("userId");
// let newWidget = {
// id: selectedChartId.id,
// panel: selectedChartId.panel,
// widgetName: inputName,
// Data: {
// measurements: inputMeasurement,
// duration: inputDuration,
// },
// }
let newWidget = {
id: selectedChartId.id,
panel: selectedChartId.panel,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
},
}
// const adding3dWidget = {
// organization: organization,
// widget: newWidget,
@@ -113,42 +117,47 @@ const Progress1Input = (props: Props) => {
// if (visualizationSocket) {
// visualizationSocket.emit("v1:viz-3D-widget:add", adding3dWidget);
// }
try {
const response = await axios.post(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/save`,
{
headers: {
Authorization: "Bearer <access_token>",
"Content-Type": "application/json",
token: localStorage.getItem("token") || "",
refresh_token: localStorage.getItem("refreshToken") || "",
},
},
{
organization: organization,
zoneUuid: selectedZone.zoneUuid,
widget: {
id: selectedChartId.id,
panel: selectedChartId.panel,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
},
},
} as any
);
if (response.status === 200) {
return true;
} else {
console.log("Unexpected response:", response);
return false;
}
} catch (error) {
echo.error("Failed to send input");
console.error("There was an error!", error);
let response = await addingWidgets(selectedZone.zoneUuid, organization, newWidget, projectId);
if (response.message === "Widget updated successfully") {
return true;
} else {
return false;
}
// try {
// const response = await axios.post(
// `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/save`,
// {
// headers: {
// Authorization: "Bearer <access_token>",
// "Content-Type": "application/json",
// token: localStorage.getItem("token") || "",
// refresh_token: localStorage.getItem("refreshToken") || "",
// },
// },
// {
// zoneUuid: selectedZone.zoneUuid,
// organization: organization,
// widget: {
// id: selectedChartId.id,
// panel: selectedChartId.panel,
// widgetName: inputName,
// Data: {
// measurements: inputMeasurement,
// duration: inputDuration,
// },
// },
// } as any
// );
// } catch (error) {
// echo.error("Failed to send input");
//
// return false;
// }
};
const handleSelect = async (
@@ -163,7 +172,7 @@ const Progress1Input = (props: Props) => {
newSelections[inputKey] = selectedData;
}
// setMeasurements(newSelections); // Update Zustand store
// console.log(newSelections);
//
if (await sendInputes(newSelections, duration, widgetName)) {
setSelections(newSelections);
}

View File

@@ -9,6 +9,9 @@ import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
import { useParams } from "react-router-dom";
import { useSocketStore } from "../../../../../store/builder/store";
import { getUserData } from "../../../../../functions/getUserData";
import { addingWidgets } from "../../../../../services/visulization/zone/addWidgets";
import { useVersionContext } from "../../../../../modules/builder/version/versionContext";
type Props = {};
@@ -23,12 +26,12 @@ const Progress2Input = (props: Props) => {
const { selectedZone } = useSelectedZoneStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
const { userName, userId, organization, email } = getUserData();
const [isLoading, setLoading] = useState<boolean>(true);
const { projectId } = useParams();
const { visualizationSocket } = useSocketStore();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
useEffect(() => {
const fetchZoneData = async () => {
@@ -36,15 +39,15 @@ const Progress2Input = (props: Props) => {
setLoading(true);
const response = await axios.get(`http://${iotApiUrl}/floatinput`);
if (response.status === 200) {
// console.log("dropdown data:", response.data);
//
setDropDownData(response.data);
setLoading(false);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch zone data");
console.error("There was an error!", error);
}
};
fetchZoneData();
@@ -55,7 +58,7 @@ const Progress2Input = (props: Props) => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/data?widgetID=${selectedChartId.id}&zoneUuid=${selectedZone.zoneUuid}&projectId=${projectId}`,
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/data?widgetID=${selectedChartId.id}&zoneUuid=${selectedZone.zoneUuid}&projectId=${projectId}&versionId=${selectedVersion?.versionId || ""}`,
{
headers: {
Authorization: "Bearer <access_token>",
@@ -66,15 +69,16 @@ const Progress2Input = (props: Props) => {
}
);
if (response.status === 200) {
setSelections(response.data.Data.measurements);
setDuration(response.data.Data.duration);
setSelections(response.data.Datastructure.measurements);
setDuration(response.data.Datastructure.duration);
setWidgetName(response.data.widgetName);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch saved inputs");
console.error("There was an error!", error);
}
}
};
@@ -95,15 +99,16 @@ const Progress2Input = (props: Props) => {
inputName: any
) => {
// const userId = localStorage.getItem("userId");
// let newWidget = {
// id: selectedChartId.id,
// panel: selectedChartId.panel,
// widgetName: inputName,
// Data: {
// measurements: inputMeasurement,
// duration: inputDuration,
// }
// }
let newWidget = {
id: selectedChartId.id,
panel: selectedChartId.panel,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
}
}
// const adding3dWidget = {
// organization: organization,
// widget: newWidget,
@@ -113,42 +118,48 @@ const Progress2Input = (props: Props) => {
// if (visualizationSocket) {
// visualizationSocket.emit("v1:viz-3D-widget:add", adding3dWidget);
// }
try {
const response = await axios.post(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/save`,
{
headers: {
Authorization: "Bearer <access_token>",
"Content-Type": "application/json",
token: localStorage.getItem("token") || "",
refresh_token: localStorage.getItem("refreshToken") || "",
},
},
{
organization: organization,
zoneUuid: selectedZone.zoneUuid,
widget: {
id: selectedChartId.id,
panel: selectedChartId.panel,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
},
},
} as any
);
if (response.status === 200) {
return true;
} else {
console.log("Unexpected response:", response);
return false;
}
} catch (error) {
echo.error("Failed to send input");
console.error("There was an error!", error);
let response = await addingWidgets(selectedZone.zoneUuid, organization, newWidget,projectId);
if(response.message==="Widget updated successfully"){
return true;
}else{
return false;
}
// try {
// const response = await axios.post(
// `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/save`,
// {
// headers: {
// Authorization: "Bearer <access_token>",
// "Content-Type": "application/json",
// token: localStorage.getItem("token") || "",
// refresh_token: localStorage.getItem("refreshToken") || "",
// },
// },
// {
// zoneUuid: selectedZone.zoneUuid,
// organization: organization,
// widget: {
// id: selectedChartId.id,
// panel: selectedChartId.panel,
// widgetName: inputName,
// Data: {
// measurements: inputMeasurement,
// duration: inputDuration,
// },
// },
// } as any
// );
// } catch (error) {
// echo.error("Failed to send input");
//
// return false;
// }
};
const handleSelect = async (
@@ -163,7 +174,7 @@ const Progress2Input = (props: Props) => {
newSelections[inputKey] = selectedData;
}
// setMeasurements(newSelections); // Update Zustand store
// console.log(newSelections);
//
if (await sendInputes(newSelections, duration, widgetName)) {
setSelections(newSelections);
}

View File

@@ -7,6 +7,9 @@ import { useSelectedZoneStore } from "../../../../../store/visualization/useZone
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
import { getUserData } from "../../../../../functions/getUserData";
import { addingFloatingWidgets } from "../../../../../services/visulization/zone/addFloatingWidgets";
import { useParams } from "react-router-dom";
type Props = {};
@@ -22,9 +25,9 @@ const WarehouseThroughputInputComponent = (props: Props) => {
const { selectedZone } = useSelectedZoneStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
const { userName, userId, organization, email } = getUserData();
const [isLoading, setLoading] = useState<boolean>(true);
const { projectId } = useParams();
useEffect(() => {
const fetchZoneData = async () => {
@@ -36,7 +39,7 @@ const WarehouseThroughputInputComponent = (props: Props) => {
setDropDownData(response.data);
setLoading(false);
} else {
console.log("Unexpected response:", response);
// console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch zone data");
@@ -51,14 +54,22 @@ const WarehouseThroughputInputComponent = (props: Props) => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${selectedChartId.id}/${organization}`
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${selectedChartId.id}/${organization}`,
{
headers: {
Authorization: "Bearer <access_token>",
"Content-Type": "application/json",
token: localStorage.getItem("token") || "",
refresh_token: localStorage.getItem("refreshToken") || "",
},
}
);
if (response.status === 200) {
setSelections(response.data.Data.measurements);
setDuration(response.data.Data.duration);
setWidgetName(response.data.header);
} else {
console.log("Unexpected response:", response);
// console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch saved inputs");
@@ -82,33 +93,45 @@ const WarehouseThroughputInputComponent = (props: Props) => {
inputDuration: any,
inputName: any
) => {
try {
const response = await axios.post(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/floatWidget/save`,
{
organization: organization,
zoneUuid: selectedZone.zoneUuid,
widget: {
id: selectedChartId.id,
header: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
},
},
} as any
);
if (response.status === 200) {
return true;
} else {
console.log("Unexpected response:", response);
return false;
}
} catch (error) {
echo.error("Failed to send input");
console.error("There was an error!", error);
let newWidget = {
id: selectedChartId.id,
header: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration,
},
}
const response = await addingFloatingWidgets(selectedZone.zoneUuid, organization, newWidget,projectId)
// console.log('response: ', response);
if (response.message === "Widget updated successfully") {
return true;
} else {
// console.log("Unexpected response:", response);
return false;
}
// try {
// const response = await axios.post(
// `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/floatWidget/save`,
// {
// organization: organization,
// zoneUuid: selectedZone.zoneUuid,
// widget: {
// id: selectedChartId.id,
// header: inputName,
// Data: {
// measurements: inputMeasurement,
// duration: inputDuration,
// },
// },
// } as any
// );
// } catch (error) {
// echo.error("Failed to send input");
// console.error("There was an error!", error);
// return false;
// }
};
const handleSelect = async (
@@ -140,7 +163,7 @@ const WarehouseThroughputInputComponent = (props: Props) => {
};
const handleNameChange = async (name: any) => {
console.log("name change requested", name);
// console.log("name change requested", name);
if (await sendInputes(selections, duration, name)) {
setWidgetName(name);

View File

@@ -7,6 +7,7 @@ import { useSelectedZoneStore } from "../../../../../store/visualization/useZone
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
import { getUserData } from "../../../../../functions/getUserData";
type Props = {};
@@ -21,8 +22,7 @@ const Widget2InputCard3D = (props: Props) => {
>({});
const { selectedZone } = useSelectedZoneStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
const { userName, userId, organization, email } = getUserData();
const [isLoading, setLoading] = useState<boolean>(true);
useEffect(() => {
@@ -35,7 +35,7 @@ const Widget2InputCard3D = (props: Props) => {
setDropDownData(response.data);
setLoading(false);
} else {
console.log("Unexpected response:", response);
// console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch zone data");
@@ -57,7 +57,7 @@ const Widget2InputCard3D = (props: Props) => {
setDuration(response.data.Data.duration);
setWidgetName(response.data.widgetName);
} else {
console.log("Unexpected response:", response);
// console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch saved inputs");
@@ -85,7 +85,7 @@ const Widget2InputCard3D = (props: Props) => {
const response = await axios.post(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget3d/save`,
{
organization: organization,
organization,
zoneUuid: selectedZone.zoneUuid,
widget: {
id: selectedChartId.id,

View File

@@ -7,6 +7,7 @@ import { useSelectedZoneStore } from "../../../../../store/visualization/useZone
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
import { getUserData } from "../../../../../functions/getUserData";
const Widget3InputCard3D = () => {
const { selectedChartId } = useWidgetStore();
@@ -19,8 +20,7 @@ const Widget3InputCard3D = () => {
>({});
const { selectedZone } = useSelectedZoneStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
const { userName, userId, organization, email } = getUserData();
const [isLoading, setLoading] = useState<boolean>(true);
useEffect(() => {
@@ -33,7 +33,7 @@ const Widget3InputCard3D = () => {
setDropDownData(response.data);
setLoading(false);
} else {
console.log("Unexpected response:", response);
// console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch zone data");
@@ -55,7 +55,7 @@ const Widget3InputCard3D = () => {
setDuration(response.data.Data.duration);
setWidgetName(response.data.widgetName);
} else {
console.log("Unexpected response:", response);
// console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch saved inputs");
@@ -82,7 +82,7 @@ const Widget3InputCard3D = () => {
const response = await axios.post(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget3d/save`,
{
organization: organization,
organization,
zoneUuid: selectedZone.zoneUuid,
widget: {
id: selectedChartId.id,
@@ -97,7 +97,7 @@ const Widget3InputCard3D = () => {
if (response.status === 200) {
return true;
} else {
console.log("Unexpected response:", response);
// console.log("Unexpected response:", response);
return false;
}
} catch (error) {

View File

@@ -7,6 +7,7 @@ import { useSelectedZoneStore } from "../../../../../store/visualization/useZone
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
import { getUserData } from "../../../../../functions/getUserData";
type Props = {};
@@ -21,8 +22,7 @@ const Widget4InputCard3D = (props: Props) => {
>({});
const { selectedZone } = useSelectedZoneStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
const { userName, userId, organization, email } = getUserData();
const [isLoading, setLoading] = useState<boolean>(true);
useEffect(() => {
@@ -35,7 +35,7 @@ const Widget4InputCard3D = (props: Props) => {
setDropDownData(response.data);
setLoading(false);
} else {
console.log("Unexpected response:", response);
// console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch zone data");
@@ -57,7 +57,7 @@ const Widget4InputCard3D = (props: Props) => {
setDuration(response.data.Data.duration);
setWidgetName(response.data.widgetName);
} else {
console.log("Unexpected response:", response);
// console.log("Unexpected response:", response);
}
} catch (error) {
echo.error("Failed to fetch saved inputs");
@@ -85,7 +85,7 @@ const Widget4InputCard3D = (props: Props) => {
const response = await axios.post(
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget3d/save`,
{
organization: organization,
organization,
zoneUuid: selectedZone.zoneUuid,
widget: {
id: selectedChartId.id,
@@ -100,7 +100,7 @@ const Widget4InputCard3D = (props: Props) => {
if (response.status === 200) {
return true;
} else {
console.log("Unexpected response:", response);
// console.log("Unexpected response:", response);
return false;
}
} catch (error) {

View File

@@ -44,7 +44,7 @@ const Design = () => {
};
useEffect(() => {
console.log("Styles", styles);
// console.log("Styles", styles);
}, [styles]);
return (

View File

@@ -6,6 +6,7 @@ import RegularDropDown from "../ui/inputs/RegularDropDown";
import { access } from "fs";
import MultiEmailInvite from "../ui/inputs/MultiEmailInvite";
import { useActiveUsers } from "../../store/builder/store";
import { getUserData } from "../../functions/getUserData";
interface UserListTemplateProps {
user: User;
@@ -59,10 +60,10 @@ const CollaborationPopup: React.FC<CollaborateProps> = ({
setUserManagement,
}) => {
const { activeUsers } = useActiveUsers();
const { userName } = getUserData();
useEffect(() => {
console.log("activeUsers: ", activeUsers);
// console.log("activeUsers: ", activeUsers);
}, [activeUsers]);
const userName = localStorage.getItem("userName") || "Anonymous";
const users = [
{
name: "Alice Johnson",
@@ -140,7 +141,7 @@ const CollaborationPopup: React.FC<CollaborateProps> = ({
<div className="users-list-container">
<div className="you-container">
<div className="your-name">
<div className="user-profile">{userName[0].toUpperCase()}</div>
<div className="user-profile">{userName && userName[0].toUpperCase()}</div>
{userName}
</div>
<div className="indicater">you</div>

View File

@@ -5,6 +5,7 @@ import { useParams } from "react-router-dom";
import { useProjectName } from "../../store/builder/store";
import { getAllProjects } from "../../services/dashboard/getAllProjects";
import { useComparisonProduct } from "../../store/simulation/useSimulationStore";
import { getUserData } from "../../functions/getUserData";
interface LoadingPageProps {
progress: number; // Expect progress as a percentage (0-100)
@@ -14,42 +15,28 @@ const LoadingPage: React.FC<LoadingPageProps> = ({ progress }) => {
const { projectName, setProjectName } = useProjectName();
const { projectId } = useParams();
const { comparisonProduct } = useComparisonProduct();
const { userId, organization } = getUserData();
const validatedProgress = Math.min(100, Math.max(0, progress));
const generateThumbnail = async () => {
const email = localStorage.getItem("email");
const userId = localStorage.getItem("userId");
try {
if (!email || !userId) {
console.error("User data not found in localStorage");
return;
}
const emailParts = email.split("@");
if (emailParts.length < 2) {
console.error("Invalid email format");
return;
}
const domainParts = emailParts[1].split(".");
const Organization = domainParts[0];
const projects = await getAllProjects(userId, Organization);
const filterProject = projects?.Projects.find(
(val: any) => val.projectUuid === projectId || val._id === projectId
);
setProjectName(filterProject.projectName);
} catch {}
};
useEffect(() => {
generateThumbnail();
if (!userId) return;
getAllProjects(userId, organization).then((projects) => {
const filterProject = projects?.Projects.find((val: any) => val.projectUuid === projectId || val._id === projectId);
if (filterProject) {
setProjectName(filterProject.projectName);
}
}).catch((error) => {
console.log(error);
})
}, []);
return (
<RenderOverlay>
<div
className={`loading-wrapper ${
comparisonProduct != null ? "comparisionLoading" : ""
}`}
className={`loading-wrapper ${comparisonProduct != null ? "comparisionLoading" : ""
}`}
>
<div className="loading-container">
<div className="project-name">{projectName}</div>

View File

@@ -7,130 +7,102 @@ import { useProjectName, useSocketStore } from "../../store/builder/store";
import { useParams } from "react-router-dom";
import { getAllProjects } from "../../services/dashboard/getAllProjects";
import { updateProject } from "../../services/dashboard/updateProject";
import { getUserData } from "../../functions/getUserData";
const FileMenu: React.FC = () => {
const [openMenu, setOpenMenu] = useState(false);
const containerRef = useRef<HTMLButtonElement>(null);
let clickTimeout: NodeJS.Timeout | null = null;
const { projectName, setProjectName } = useProjectName();
const { dashBoardSocket } = useSocketStore();
const { projectId } = useParams();
const [openMenu, setOpenMenu] = useState(false);
const containerRef = useRef<HTMLButtonElement>(null);
let clickTimeout: NodeJS.Timeout | null = null;
const { projectName, setProjectName } = useProjectName();
const { dashBoardSocket } = useSocketStore();
const { projectId } = useParams();
const { userId, organization, email } = getUserData();
const handleClick = () => {
if (clickTimeout) return;
setOpenMenu((prev) => !prev);
clickTimeout = setTimeout(() => {
clickTimeout = null;
}, 800);
};
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (
containerRef.current &&
!containerRef.current.contains(event.target as Node)
) {
setOpenMenu(false);
}
const handleClick = () => {
if (clickTimeout) return;
setOpenMenu((prev) => !prev);
clickTimeout = setTimeout(() => {
clickTimeout = null;
}, 800);
};
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (
containerRef.current &&
!containerRef.current.contains(event.target as Node)
) {
setOpenMenu(false);
}
};
// project
// const [projectName, setProjectName] = useState("Demo Project");
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);
// Load project name from localStorage on mount
// useEffect(() => {
// const savedName = localStorage.getItem("projectName");
// if (savedName) {
// setProjectName(savedName);
// }
// }, []);
const handleProjectRename = async (projectName: string) => {
setProjectName(projectName);
if (!projectId) return
// const handleProjectRename = (newName: string) => {
// setProjectName(newName);
// localStorage.setItem("projectName", newName);
// };
const handleProjectRename = async (projectName: string) => {
setProjectName(projectName);
if (!projectId) return
// localStorage.setItem("projectName", newName);
try {
const email = localStorage.getItem("email");
const userId = localStorage.getItem("userId");
// localStorage.setItem("projectName", newName);
if (!email || !userId) {
try {
return;
}
if (!email || !userId) return;
const emailParts = email.split("@");
if (emailParts.length < 2) {
const projects = await getAllProjects(userId, organization);
// console.log('projects: ', projects);
let projectUuid = projects.Projects.find((val: any) => val.projectUuid === projectId || val._id === projectId)
return;
}
const updateProjects = {
projectId: projectUuid,
organization,
userId,
projectName,
thumbnail: undefined
}
const domainParts = emailParts[1].split(".");
const Organization = domainParts[0];
const projects = await getAllProjects(
userId, Organization
);
console.log('projects: ', projects);
let projectUuid = projects.Projects.find((val: any) => val.projectUuid === projectId || val._id
=== projectId)
const updateProjects = {
projectId: projectUuid,
organization: Organization,
userId,
projectName,
thumbnail: undefined
}
// if (dashBoardSocket) {
// const handleResponse = (data: any) => {
// console.log('Project update response:', data);
// dashBoardSocket.off("v1-project:response:update", handleResponse); // Clean up
// };
// dashBoardSocket.on("v1-project:response:update", handleResponse);
// dashBoardSocket.emit("v1:project:update", updateProjects);
// }
// if (dashBoardSocket) {
// const handleResponse = (data: any) => {
// console.log('Project update response:', data);
// dashBoardSocket.off("v1-project:response:update", handleResponse); // Clean up
// };
// dashBoardSocket.on("v1-project:response:update", handleResponse);
// dashBoardSocket.emit("v1:project:update", updateProjects);
// }
//API for projects rename
const updatedProjectName = await updateProject(
projectId,
userId,
Organization,
undefined,
projectName
);
//
} catch (error) {
}
};
return (
<button
id="project-dropdown-button"
className="project-dropdowm-container"
ref={containerRef}
onClick={handleClick}
>
<div className="project-name">
<div className="icon">
<ProjectIcon />
</div>
<RenameInput value={projectName} onRename={handleProjectRename} />
</div>
<div className="more-options-button">
<ArrowIcon />
{openMenu && <MenuBar setOpenMenu={setOpenMenu} />}
</div>
</button>
);
//API for projects rename
const updatedProjectName = await updateProject(
projectId,
userId,
organization,
undefined,
projectName
);
//
} catch (error) {
console.error("Error updating project name:", error);
}
};
return (
<button
id="project-dropdown-button"
className="project-dropdowm-container"
ref={containerRef}
onClick={handleClick}
>
<div className="project-name">
<div className="icon">
<ProjectIcon />
</div>
<RenameInput value={projectName} onRename={handleProjectRename} />
</div>
<div className="more-options-button">
<ArrowIcon />
{openMenu && <MenuBar setOpenMenu={setOpenMenu} />}
</div>
</button>
);
};
export default FileMenu;

View File

@@ -12,7 +12,7 @@ import useVersionHistoryStore from "../../store/builder/store";
const ModuleToggle: React.FC = () => {
const { activeModule, setActiveModule } = useModuleStore();
const { setToggleUI } = useToggleStore();
const { setVersionHistory } = useVersionHistoryStore();
const { setVersionHistoryVisible } = useVersionHistoryStore();
return (
<div className="module-toggle-container">
@@ -21,7 +21,7 @@ const ModuleToggle: React.FC = () => {
className={`module-list ${activeModule === "builder" ? "active" : ""}`}
onClick={() => {
setActiveModule("builder");
setVersionHistory(false);
setVersionHistoryVisible(false);
setToggleUI(
localStorage.getItem("navBarUiLeft")
? localStorage.getItem("navBarUiLeft") === "true"
@@ -44,7 +44,7 @@ const ModuleToggle: React.FC = () => {
}`}
onClick={() => {
setActiveModule("simulation");
setVersionHistory(false);
setVersionHistoryVisible(false);
setToggleUI(
localStorage.getItem("navBarUiLeft")
? localStorage.getItem("navBarUiLeft") === "true"
@@ -67,7 +67,7 @@ const ModuleToggle: React.FC = () => {
}`}
onClick={() => {
setActiveModule("visualization");
setVersionHistory(false);
setVersionHistoryVisible(false);
setToggleUI(
localStorage.getItem("navBarUiLeft")
? localStorage.getItem("navBarUiLeft") === "true"
@@ -88,7 +88,7 @@ const ModuleToggle: React.FC = () => {
className={`module-list ${activeModule === "market" ? "active" : ""}`}
onClick={() => {
setActiveModule("market");
setVersionHistory(false);
setVersionHistoryVisible(false);
setToggleUI(false, false);
}}
>

View File

@@ -36,6 +36,7 @@ import {
useFloatingWidget,
} from "../../store/visualization/useDroppedObjectsStore";
import { useParams } from "react-router-dom";
import { useVersionContext } from "../../modules/builder/version/versionContext";
// Utility component
const ToolButton = ({
@@ -86,6 +87,8 @@ const Tools: React.FC = () => {
const dropdownRef = useRef<HTMLButtonElement>(null);
const [openDrop, setOpenDrop] = useState(false);
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const { projectId } = useParams();
// 1. Set UI toggles on initial render
@@ -250,7 +253,8 @@ const Tools: React.FC = () => {
selectedZone,
templates,
visualizationSocket,
projectId
projectId,
versionId: selectedVersion?.versionId || ''
})
}
/>

View File

@@ -1,13 +1,21 @@
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor";
import { getUserData } from "../../../functions/getUserData";
import { getAllThreads } from "../../../services/factoryBuilder/comments/getAllThreads";
import { useParams } from "react-router-dom";
import { useCommentStore } from "../../../store/collaboration/useCommentStore";
import { getRelativeTime } from "./function/getRelativeTime";
import { useSelectedComment } from "../../../store/builder/store";
interface CommentThreadsProps {
commentClicked: () => void;
comment?: CommentSchema
}
const CommentThreads: React.FC<CommentThreadsProps> = ({ commentClicked }) => {
const CommentThreads: React.FC<CommentThreadsProps> = ({ commentClicked, comment }) => {
const [expand, setExpand] = useState(false);
const commentsedUsers = [{ creatorId: "1" }];
const { userName } = getUserData();
const CommentDetails = {
state: "active",
@@ -16,26 +24,26 @@ const CommentThreads: React.FC<CommentThreadsProps> = ({ commentClicked }) => {
createdAt: "2 hours ago",
comment: "Thread check",
lastUpdatedAt: "string",
replies: [
comments: [
{
replyId: "string",
creatorId: "string",
createdAt: "string",
lastUpdatedAt: "string",
reply: "string",
comment: "string",
},
{
replyId: "string",
creatorId: "string",
createdAt: "string",
lastUpdatedAt: "string",
reply: "string",
comment: "string",
},
],
};
function getUsername(userId: string) {
const UserName = "username";
const UserName = userName?.charAt(0).toUpperCase() || "user";
return UserName;
}
@@ -48,15 +56,15 @@ const CommentThreads: React.FC<CommentThreadsProps> = ({ commentClicked }) => {
}
}
return (
<div className="comments-threads-wrapper">
<button
onPointerEnter={() => getDetails()}
onPointerLeave={() => getDetails()}
onClick={() => getDetails("clicked")}
className={`comments-threads-container ${
expand ? "open" : "closed"
} unread`}
className={`comments-threads-container ${expand ? "open" : "closed"
} unread`}
>
<div className="users-commented">
{commentsedUsers.map((val, i) => (
@@ -70,24 +78,37 @@ const CommentThreads: React.FC<CommentThreadsProps> = ({ commentClicked }) => {
{getUsername(val.creatorId)[0]}
</div>
))}
{/* {commentsedUsers.map((val, i) => (
<div
className="users"
key={val.creatorId}
style={{
background: getAvatarColor(i, getUsername(val.creatorId)),
}}
>
{getUsername(val.creatorId)[0]}
</div>
))} */}
</div>
<div className={`last-comment-details ${expand ? "expand" : ""}`}>
<div className="header">
<div className="user-name">
{getUsername(CommentDetails.creatorId)}
{userName}
{/* {getUsername(CommentDetails.creatorId)} */}
</div>
<div className="time">{CommentDetails.createdAt}</div>
<div className="time">{comment?.createdAt && getRelativeTime(comment.createdAt)}</div>
</div>
<div className="message">{CommentDetails.comment}</div>
{CommentDetails.replies.length > 0 && (
<div className="replies">
{CommentDetails.replies.length}{" "}
{CommentDetails.replies.length === 1 ? "reply" : "replies"}
<div className="message">{comment?.threadTitle}</div>
{comment && comment?.comments.length > 0 && (
<div className="comments">
{comment && comment?.comments.length}{" "}
{comment && comment?.comments.length === 1 ? "comment" : "replies"}
</div>
)}
</div>
</button>
</div>
);
};

View File

@@ -2,44 +2,181 @@ import React, { useEffect, useRef, useState } from "react";
import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor";
import { KebabIcon } from "../../icons/ExportCommonIcons";
import { adjustHeight } from "./function/textAreaHeightAdjust";
import { getUserData } from "../../../functions/getUserData";
import { useParams } from "react-router-dom";
import { deleteCommentApi } from "../../../services/factoryBuilder/comments/deleteCommentApi";
import { addCommentsApi } from "../../../services/factoryBuilder/comments/addCommentsApi";
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";
interface MessageProps {
val: Reply | CommentSchema;
// val: Reply | CommentSchema;
i: number;
setMessages?: React.Dispatch<React.SetStateAction<Reply[]>>
setIsEditable?: React.Dispatch<React.SetStateAction<boolean>>
setEditedThread?: React.Dispatch<React.SetStateAction<boolean>>
setMode?: React.Dispatch<React.SetStateAction<'create' | 'edit' | null>>
isEditable?: boolean;
isEditableThread?: boolean
editedThread?: boolean;
mode?: 'create' | 'edit' | null
}
const Messages: React.FC<MessageProps> = ({ val, i }) => {
const [isEditing, setIsEditing] = useState(false);
const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEditable, setEditedThread, editedThread, isEditableThread, setMode }) => {
const { comments, updateComment, updateReply, removeReply } = useCommentStore();
const [openOptions, setOpenOptions] = useState(false);
const { projectId } = useParams();
const { threadSocket } = useSocketStore();
const { userName, userId, organization } = getUserData();
const [isEditComment, setIsEditComment] = useState(false)
const { selectedComment, setCommentPositionState } = useSelectedComment();
// input
const [value, setValue] = useState<string>(
"reply" in val ? val.reply : val.comment
"comment" in val ? val.comment : val.threadTitle
);
const textareaRef = useRef<HTMLTextAreaElement>(null);
const currentUser = "1";
const UserName = "username";
// const UserName = "username";
useEffect(() => {
if (textareaRef.current) adjustHeight(textareaRef.current);
}, [value]);
function handleCancelAction() {
setIsEditing(false);
setCommentPositionState(null)
setIsEditable && setIsEditable(true);
setIsEditComment(false)
}
function handleSaveAction() {
setIsEditing(false);
const handleSaveAction = async () => {
if (!projectId) return
if (isEditableThread && editedThread) {
try {
// const editThreadTitle = await editThreadTitleApi(projectId, (val as CommentSchema).threadId, value)
// if (editThreadTitle.message == "ThreadTitle updated Successfully") {
// const editedThread: CommentSchema = {
// state: 'active',
// threadId: editThreadTitle.data.replyId,
// creatorId: userId,
// createdAt: getRelativeTime(editThreadTitle.data.createdAt),
// threadTitle: value,
// lastUpdatedAt: new Date().toISOString(),
// position: editThreadTitle.data.position,
// rotation: [0, 0, 0],
// comments: []
// }
// updateComment((val as CommentSchema).threadId, editedThread)
// }
// projectId, userId, threadTitle, organization, threadId
const threadEdit = {
projectId,
userId,
threadTitle: value,
organization,
threadId: (val as CommentSchema).threadId
}
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 commentData = {
// replyId: `${editComments.data?.replyId}`,
// creatorId: `${userId}`,
// createdAt: getRelativeTime(editComments.data?.createdAt),
// lastUpdatedAt: "2 hrs ago",
// comment: value,
// }
// updateReply((val as CommentSchema).threadId, (val as Reply)?.replyId, commentData);
if (threadSocket) {
// projectId, userId, comment, organization, threadId
const editComment = {
projectId,
userId,
comment: value,
organization,
threadId: selectedComment?.threadId,
commentId: (val as Reply).replyId ?? ""
}
threadSocket.emit("v1-Comment:add", editComment);
setIsEditable && setIsEditable(true);
setEditedThread && setEditedThread(false)
}
} catch {
}
}
}
// setValue("");
setIsEditComment(false);
}
function handleDeleteAction() {
const handleDeleteAction = async (replyID: any) => {
if (!projectId) return
setOpenOptions(false);
try {
// const deletedComment = await deleteCommentApi(projectId, selectedComment?.threadId, (val as Reply).replyId)
//
// if (deletedComment === "'Thread comment deleted Successfully'") {
// setMessages && setMessages(prev => prev.filter(message => message.replyId !== replyID));
// removeReply(val.creatorId, replyID)
// }
if (threadSocket && setMessages) {
// projectId, userId, commentId, organization, threadId
const deleteComment = {
projectId,
userId,
commentId: (val as Reply).replyId,
organization,
threadId: selectedComment?.threadId
}
setMessages(prev => 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 {
}
}
const handleFocus = (e: React.FocusEvent<HTMLTextAreaElement>) => {
requestAnimationFrame(() => {
if (textareaRef.current) {
const length = textareaRef.current.value.length;
textareaRef.current.setSelectionRange(length, length);
}
});
};
return (
<>
{isEditing ? (
{isEditComment ? (
<div className="edit-container">
<div className="input-container">
<textarea
@@ -49,6 +186,7 @@ const Messages: React.FC<MessageProps> = ({ val, i }) => {
value={value}
onChange={(e) => setValue(e.target.value)}
style={{ resize: "none" }}
onFocus={handleFocus}
/>
</div>
<div className="actions-container">
@@ -77,16 +215,16 @@ const Messages: React.FC<MessageProps> = ({ val, i }) => {
<div className="message-container">
<div
className="profile"
style={{ background: getAvatarColor(i, UserName) }}
style={{ background: getAvatarColor(i, userName) }}
>
{UserName[0]}
{userName?.charAt(0).toUpperCase() || "user"}
</div>
<div className="content">
<div className="user-details">
<div className="user-name">{UserName}</div>
<div className="time">{val.createdAt}</div>
<div className="user-name">{userName}</div>
<div className="time">{isEditableThread ? getRelativeTime(val.createdAt) : val.createdAt}</div>
</div>
{val.creatorId === currentUser && (
{(val as Reply).creatorId === userId && (
<div className="more-options">
<button
className="more-options-button"
@@ -100,30 +238,33 @@ const Messages: React.FC<MessageProps> = ({ val, i }) => {
<div className="options-list">
<button
className="option"
onClick={() => {
onClick={(e) => {
e.preventDefault();
setMode && setMode("edit")
setOpenOptions(false);
setIsEditing(true);
setEditedThread && setEditedThread(true);
setIsEditComment(true)
}}
>
Edit
</button>
<button
{!(isEditableThread) && <button
className="option"
onClick={() => {
handleDeleteAction();
handleDeleteAction((val as Reply).replyId);
}}
>
Delete
</button>
</button>}
</div>
)}
</div>
)}
<div className="message">
{"reply" in val ? val.reply : val.comment}
{"comment" in val ? val.comment : val.threadTitle}
</div>
</div>
</div>
</div >
)}
</>
);

View File

@@ -3,36 +3,67 @@ import { CloseIcon, KebabIcon } from "../../icons/ExportCommonIcons";
import Messages from "./Messages";
import { ExpandIcon } from "../../icons/SimulationIcons";
import { adjustHeight } from "./function/textAreaHeightAdjust";
import { useParams } from "react-router-dom";
import { useSelectedComment, useSocketStore } from "../../../store/builder/store";
import { useCommentStore } from "../../../store/collaboration/useCommentStore";
import { getUserData } from "../../../functions/getUserData";
import ThreadSocketResponsesDev from "../../../modules/collaboration/socket/threadSocketResponses.dev";
import { addCommentsApi } from "../../../services/factoryBuilder/comments/addCommentsApi";
import { deleteThreadApi } from "../../../services/factoryBuilder/comments/deleteThreadApi";
import { createThreadApi } from "../../../services/factoryBuilder/comments/createThreadApi";
import { getRelativeTime } from "./function/getRelativeTime";
const ThreadChat: React.FC = () => {
const { userId, organization } = getUserData();
const [openThreadOptions, setOpenThreadOptions] = useState(false);
const [inputActive, setInputActive] = useState(false);
const [value, setValue] = useState<string>("");
const { addComment, removeReply, removeComment, addReply, comments } = useCommentStore();
const { selectedComment, setSelectedComment, setCommentPositionState, commentPositionState, position2Dstate } = useSelectedComment()
const [mode, setMode] = useState<'create' | 'edit' | null>('create');
const [isEditable, setIsEditable] = useState(false);
const [editedThread, setEditedThread] = useState(false);
const textareaRef = useRef<HTMLTextAreaElement>(null);
const wrapperRef = useRef<HTMLDivElement>(null);
const [messages, setMessages] = useState<Reply[]>([])
const { projectId } = useParams();
const [dragging, setDragging] = useState(false);
const [selectedDiv, setSelectedDiv] = useState(true);
const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
const [position, setPosition] = useState({ x: 100, y: 100 });
const [position, setPosition] = useState({ x: position2Dstate.x, y: position2Dstate.y });
const { threadSocket } = useSocketStore();
const modeRef = useRef<'create' | 'edit' | null>(null);
const messagesRef = useRef<HTMLDivElement>(null);
const messages = [
{
replyId: "user 1",
creatorId: "1",
createdAt: "2 hrs ago",
lastUpdatedAt: "2 hrs ago",
reply:
"reply testing reply content 1, reply testing reply content 1reply testing reply content 1",
},
{
replyId: "user 2",
creatorId: "2",
createdAt: "2 hrs ago",
lastUpdatedAt: "2 hrs ago",
reply: "reply 2",
},
];
useEffect(() => {
modeRef.current = mode;
}, [mode]);
useEffect(() => {
if (comments.length > 0 && selectedComment) {
const allMessages = comments
.flatMap((val: any) =>
val?.threadId === selectedComment?.threadId ? val.comments : []
)
.map((c) => {
return {
replyId: c._id ?? "",
creatorId: c.creatorId || c.userId,
createdAt: c.createdAt,
lastUpdatedAt: "1 hr ago",
comment: c.comment,
_id: c._id ?? "",
};
});
setMessages(allMessages);
}
}, [selectedComment])
useEffect(() => {
if (textareaRef.current) adjustHeight(textareaRef.current);
@@ -44,6 +75,19 @@ const ThreadChat: React.FC = () => {
const handlePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {
if (event.button !== 0) return;
// Avoid dragging if a button, icon, textarea etc. was clicked
const target = event.target as HTMLElement;
if (
target.closest("button") ||
target.closest(".sent-button") ||
target.closest("textarea") ||
target.closest(".options-button") ||
target.closest(".options-list") ||
target.closest(".send-message-wrapper") ||
target.closest(".options delete")
) {
return;
}
const wrapper = wrapperRef.current;
if (!wrapper) return;
@@ -58,18 +102,20 @@ const ThreadChat: React.FC = () => {
wrapper.setPointerCapture(event.pointerId);
};
const handlePointerMove = (event: React.PointerEvent<HTMLDivElement>) => {
if (!dragging) return;
const updatePosition = (
{ clientX, clientY }: { clientX: number; clientY: number },
allowMove: boolean = true
) => {
if (!allowMove || !wrapperRef.current) return;
const container = document.getElementById("work-space-three-d-canvas");
const wrapper = wrapperRef.current;
if (!container || !wrapper) return;
const containerRect = container.getBoundingClientRect();
const wrapperRect = wrapper.getBoundingClientRect();
let newX = event.clientX - containerRect.left - dragOffset.x;
let newY = event.clientY - containerRect.top - dragOffset.y;
let newX = clientX - containerRect.left - dragOffset.x;
let newY = clientY - containerRect.top - dragOffset.y;
const maxX = containerRect.width - wrapper.offsetWidth;
const maxY = containerRect.height - wrapper.offsetHeight;
@@ -80,6 +126,15 @@ const ThreadChat: React.FC = () => {
setPosition({ x: newX, y: newY });
};
const handlePointerMove = (e: { clientX: number; clientY: number }) => {
if (dragging) updatePosition(e, true);
};
useEffect(() => {
updatePosition({ clientX: position.x, clientY: position.y }, true);
}, [selectedComment]);
const handlePointerUp = (event: React.PointerEvent<HTMLDivElement>) => {
if (!dragging) return;
setDragging(false);
@@ -87,12 +142,146 @@ const ThreadChat: React.FC = () => {
if (wrapper) wrapper.releasePointerCapture(event.pointerId);
};
const handleCreateComments = async (e: any) => {
e.preventDefault();
try {
// const createComments = await addCommentsApi(projectId, value, selectedComment?.threadId)/
// if (createComments.message === 'Thread comments add Successfully' && createComments.data) {
// const commentData = {
// replyId: `${createComments.data?._id}`,
// creatorId: `${selectedComment?.threadId}`,
// createdAt: "2 hrs ago",
// lastUpdatedAt: "2 hrs ago",
// comment: value,
// }
// setMessages((prevMessages) => [
// ...prevMessages,
// commentData,
// ]);
// addReply(selectedComment?.threadId, commentData)
// }
if (threadSocket && mode === "create") {
const addComment = {
projectId,
userId,
comment: value,
organization,
threadId: selectedComment?.threadId
}
threadSocket.emit("v1-Comment:add", addComment);
}
} catch {
}
setInputActive(false)
}
const handleDeleteThread = async () => {
if (!projectId) return;
try {
// const deleteThread = await deleteThreadApi(projectId, selectedComment?.threadId)
//
// if (deleteThread.message === "Thread deleted Successfully") {
// removeComment(selectedComment?.threadId)
// setSelectedComment([])
// }
if (threadSocket) {
// projectId, userId, organization, threadId
const deleteThread = {
projectId,
userId,
organization,
threadId: selectedComment?.threadId
}
setSelectedComment(null)
removeComment(selectedComment?.threadId)
threadSocket.emit("v1:thread:delete", deleteThread);
}
}
catch {
}
}
const handleCreateThread = async (e: any) => {
e.preventDefault();
if (!projectId) return;
try {
// try {
// const thread = await createThreadApi(
// projectId,
// "active",
// commentPositionState[0].position,
// [0, 0, 0],
// value
// );
//
//
// if (thread.message === "Thread created Successfully" && thread?.threadData) {
//
// const comment: CommentSchema = {
// state: 'active',
// threadId: thread?.threadData?._id,
// creatorId: userId,
// createdAt: getRelativeTime(thread.threadData?.createdAt),
// threadTitle: value,
// lastUpdatedAt: new Date().toISOString(),
// position: commentPositionState[0].position,
// rotation: [0, 0, 0],
// comments: []
// }
// addComment(comment);
// setCommentPositionState(null);
// setInputActive(false);
// setSelectedComment([])
// }
const createThread = {
projectId,
userId,
organization,
state: "active",
position: commentPositionState.position,
rotation: [0, 0, 0],
threadTitle: value
};
if (threadSocket) {
setInputActive(false);
threadSocket.emit("v1:thread:create", createThread);
}
} catch (err) {
}
};
const scrollToBottom = () => {
const messagesWrapper = document.querySelector(".messages-wrapper");
if (messagesWrapper) {
messagesWrapper.scrollTop = messagesWrapper.scrollHeight;
}
};
useEffect(() => {
if (messages.length > 0)
scrollToBottom();
}, [messages])
return (
<div
ref={wrapperRef}
className="thread-chat-wrapper"
onPointerDown={handlePointerDown}
onPointerMove={handlePointerMove}
onPointerMove={(e) => handlePointerMove({ clientX: e.clientX, clientY: e.clientY })}
onPointerUp={handlePointerUp}
style={{
position: "absolute",
@@ -107,49 +296,94 @@ const ThreadChat: React.FC = () => {
<div className="header-wrapper">
<div className="header">Comment</div>
<div className="header-options">
<button
<div
className="options-button"
onClick={() => setOpenThreadOptions(!openThreadOptions)}
style={{ cursor: "pointer" }}
onClick={(e) => {
e.preventDefault();
setOpenThreadOptions((prev) => !prev);
}}
>
<KebabIcon />
</button>
</div>
{openThreadOptions && (
<div className="options-list">
<div className="options">Mark as Unread</div>
<div className="options">Mark as Resolved</div>
<div className="options delete">Delete Thread</div>
<div className="options delete" onClick={handleDeleteThread}>Delete Thread</div>
</div>
)}
<button className="close-button">
<button className="close-button" onClick={() => {
setSelectedComment(null)
setCommentPositionState(null)
}}>
<CloseIcon />
</button>
</div>
</div>
<div className="messages-wrapper">
{messages.map((val, i) => (
<Messages val={val as any} i={i} key={val.replyId} />
<div className="messages-wrapper" ref={messagesRef}>
{selectedComment &&
<Messages val={selectedComment} i={1} key={selectedComment.creatorId} isEditableThread={true} setEditedThread={setEditedThread} editedThread={editedThread} />
}
{messages && messages.map((val, i) => (
<Messages val={val as any} i={i} key={val.replyId} setMessages={setMessages} setIsEditable={setIsEditable} isEditable={isEditable} isEditableThread={false} setMode={setMode} mode={mode} />
))}
</div>
<div className="send-message-wrapper">
<div className={`input-container ${inputActive ? "active" : ""}`}>
<textarea
placeholder="type something"
placeholder={commentPositionState && selectedComment === null ? "Type Thread Title" : "type something"}
ref={textareaRef}
value={value}
onChange={(e) => setValue(e.target.value)}
onFocus={() => setInputActive(true)}
onKeyDown={(e) => {
if (e.key === "Enter") {
e.preventDefault();
if (commentPositionState && selectedComment === null) {
handleCreateThread(e);
} else {
setMode("create");
handleCreateComments(e);
textareaRef.current?.blur();
}
setValue('')
}
if (e.key === "Escape") {
textareaRef.current?.blur();
}
}}
onClick={() => {
if (!commentPositionState && selectedComment !== null) {
setMode("create");
}
}}
autoFocus={selectedComment === null}
onBlur={() => setInputActive(false)}
onFocus={() => setInputActive(true)}
style={{ resize: "none" }}
/>
<div className={`sent-button ${value === "" ? "disable-send-btn" : ""}`}>
<div
className={`sent-button ${value === "" ? "disable-send-btn" : ""}`}
onClick={(e) => {
if (commentPositionState && selectedComment === null) {
handleCreateThread(e);
} else {
setMode("create");
handleCreateComments(e);
}
setValue('')
}}
>
<ExpandIcon />
</div>
</div>
</div>
</div>
</div>
<ThreadSocketResponsesDev setMessages={setMessages} modeRef={modeRef} messages={messages} />
</div >
);
};

View File

@@ -0,0 +1,27 @@
type RelativeTimeFormatUnit = any;
export function getRelativeTime(dateString: string): string {
const date = new Date(dateString);
const now = new Date();
const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);
const intervals: Record<RelativeTimeFormatUnit, number> = {
year: 31536000,
month: 2592000,
week: 604800,
day: 86400,
hour: 3600,
minute: 60,
second: 1,
};
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
for (const key in intervals) {
const unit = key as RelativeTimeFormatUnit;
const diff = Math.floor(diffInSeconds / intervals[unit]);
if (diff >= 1) {
return rtf.format(-diff, unit);
}
}
return "just now";
}

View File

@@ -10,15 +10,22 @@ import {
} from "../../../store/builder/store";
import Search from "../inputs/Search";
import OuterClick from "../../../utils/outerClick";
import { useProductStore } from "../../../store/simulation/useProductStore";
import Scene from "../../../modules/scene/scene";
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore";
import { usePauseButtonStore, usePlayButtonStore } from "../../../store/usePlayButtonStore";
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
import { useVersionHistoryStore } from "../../../store/builder/useVersionHistoryStore";
import { useVersionContext } from "../../../modules/builder/version/versionContext";
import { useSceneContext } from "../../../modules/scene/sceneContext";
import { getAllProductsApi } from "../../../services/simulation/products/getallProductsApi";
import { useParams } from "react-router-dom";
const CompareLayOut = () => {
const { comparisonProduct, setComparisonProduct, clearComparisonProduct } =
useComparisonProduct();
const { products } = useProductStore();
const { clearComparisonProduct, comparisonProduct, setComparisonProduct } = useComparisonProduct();
const { productStore } = useSceneContext();
const { products } = productStore();
const { versionHistory } = useVersionHistoryStore();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion, setSelectedVersion, clearSelectedVersion } = selectedVersionStore();
const { setLoadingProgress } = useLoadingProgress();
const [width, setWidth] = useState("50vw");
const [isResizing, setIsResizing] = useState(false);
@@ -29,7 +36,13 @@ const CompareLayOut = () => {
const { setIsVersionSaved } = useSaveVersion();
const { loadingProgress } = useLoadingProgress();
const { setIsPlaying } = usePlayButtonStore();
const { setIsPaused } = usePauseButtonStore();
const { projectId } = useParams();
useEffect(() => {
if (!comparisonProduct) {
clearSelectedVersion();
}
}, [comparisonProduct])
OuterClick({
contextClassName: ["displayLayouts-container", "selectLayout"],
@@ -113,12 +126,14 @@ const CompareLayOut = () => {
return () => window.removeEventListener("resize", handleResize);
}, [isResizing]);
const handleSelectLayout = (option: string) => {
const product = products.find((product) => product.productName === option);
if (product) {
setComparisonProduct(product.productUuid, product.productName);
setLoadingProgress(1);
}
const handleSelectLayout = (version: Version) => {
getAllProductsApi(projectId || '', version.versionId || '').then((data) => {
if (data && data.length > 0) {
setSelectedVersion(version);
setComparisonProduct(data[0].productUuid, data[0].productName);
setLoadingProgress(1);
}
})
};
return (
@@ -127,7 +142,7 @@ const CompareLayOut = () => {
ref={wrapperRef}
style={{ width }}
>
{loadingProgress == 0 && (
{loadingProgress == 0 && selectedVersion?.versionId && (
<button
title="resize-canvas"
id="compare-resize-slider-btn"
@@ -138,7 +153,7 @@ const CompareLayOut = () => {
</button>
)}
<div className="chooseLayout-container">
{comparisonProduct && (
{selectedVersion?.versionId && (
<div className="compare-layout-canvas-container">
<Suspense fallback={null}>
<Scene layout="Comparison Layout" />
@@ -147,35 +162,35 @@ const CompareLayOut = () => {
)}
{width !== "0px" &&
!comparisonProduct && ( // Show only if no layout selected
!selectedVersion?.versionId && ( // Show only if no layout selected
<div className="chooseLayout-wrapper">
<div className="icon">
<CompareLayoutIcon />
</div>
<div className="value">Choose Layout to compare</div>
<div className="value">Choose Version to compare</div>
<button
className="selectLayout"
onClick={() => setShowLayoutDropdown(!showLayoutDropdown)}
>
Select Layout
Select Version
</button>
{showLayoutDropdown && (
<div className="displayLayouts-container">
<div className="header">Layouts</div>
<Search onChange={() => {}} />
<div className="header">Versions</div>
<Search onChange={() => { }} />
<div className="layouts-container">
{products.map((layout) => (
{versionHistory.map((version) => (
<button
key={layout.productUuid}
key={version.versionId}
className="layout-wrapper"
onClick={() => {
handleSelectLayout(layout.productName);
handleSelectLayout(version);
setShowLayoutDropdown(false);
}}
>
<LayoutIcon />
<div className="layout">{layout.productName}</div>
<div className="layout">{version.versionName}</div>
</button>
))}
</div>

View File

@@ -133,7 +133,7 @@ const ComparisonResult = () => {
<div className="compare-result-container">
<div className="header">Performance Comparison</div>
<div className="compare-result-wrapper">
<EnergyUsage />
<EnergyUsage comparedProducts={comparedProducts}/>
<div className="throughPutCard-container comparisionCard">
<h4>Throughput (units/hr)</h4>
<div className="layers-wrapper">
@@ -153,7 +153,7 @@ const ComparisonResult = () => {
<div className="cycle-time-container comparisionCard">
<div className="cycle-main">
<div className="cycle-header">Cycle Time</div>
<h4 className="cycle-header">Cycle Time</h4>
<div className="layers-wrapper">
<div className="layers">
<div className="layer-name">{comparedProducts[0]?.productName}</div>
@@ -202,7 +202,7 @@ const ComparisonResult = () => {
</div>
{/*
<div className="overallDowntime-container comparisionCard">
<div className="overallDowntime-header">Overall Downtime</div>
<h4 className="overallDowntime-header">Overall Downtime</h4>
<div className="totalDownTime-wrapper">
<div className="totalDownTime">
<div className="totalDownTime-right">
@@ -221,7 +221,7 @@ const ComparisonResult = () => {
</div> */}
<div className="overallScrapRate comparisionCard">
<div className="overallScrapRate-header">Production Capacity</div>
<h4 className="overallScrapRate-header">Production Capacity</h4>
<div className="overallScrapRate-wrapper">
<div className="overallScrapRate-value">
<div className="overallScrapRate-label">{highestProductivityProduct?.productName}</div>

View File

@@ -19,7 +19,7 @@ ChartJS.register(
Legend
);
const EnergyUsage = () => {
const EnergyUsage = ({comparedProducts}:any) => {
const data = useMemo(() => {
const randomizeData = () =>
Array.from({ length: 5 }, () => Math.floor(Math.random() * (2000 - 300 + 1)) + 300);
@@ -90,14 +90,14 @@ const EnergyUsage = () => {
<div className="simulation-wrapper sim-1">
<div className="icon"></div>
<div className="simulation-details-wrapper">
<div className="label">Simulation 1</div>
<div className="label">{comparedProducts[0]?.productName}</div>
<div className="value">98%</div>
</div>
</div>
<div className="simulation-wrapper sim-2">
<div className="icon"></div>
<div className="simulation-details-wrapper">
<div className="label">Simulation 2</div>
<div className="label">{comparedProducts[1]?.productName}</div>
<div className="value">97%</div>
</div>
</div>

View File

@@ -13,7 +13,7 @@ const PerformanceResult = ({ comparedProducts }: any) => {
<div className="icon">
<PerformanceIcon />
</div>
<div className="head">Performance result</div>
<h4 className="head">Performance result</h4>
</div>
<div className="metrics-container">
@@ -56,7 +56,7 @@ const PerformanceResult = ({ comparedProducts }: any) => {
</div>
</div>
<div className="simulation-tag">Simulation 1</div>
<div className="simulation-tag">{ProfitProduct.productName}</div>
</div>
);
};

View File

@@ -3,7 +3,7 @@ import List from "./List";
import { AddIcon, ArrowIcon, FocusIcon } from "../../icons/ExportCommonIcons";
import KebabMenuListMultiSelect from "./KebebMenuListMultiSelect";
import { useZones } from "../../../store/builder/store";
import { useAssetsStore } from "../../../store/builder/useAssetStore";
import { useSceneContext } from "../../../modules/scene/sceneContext";
interface DropDownListProps {
value?: string; // Value to display in the DropDownList
@@ -51,8 +51,9 @@ const DropDownList: React.FC<DropDownListProps> = ({
};
const [zoneDataList, setZoneDataList] = useState<ZoneData[]>([]);
const { assets } = useAssetsStore();
const { assetStore } = useSceneContext();
const { assets } = assetStore();
const isPointInsidePolygon = (
point: [number, number],
polygon: [number, number][]
@@ -129,7 +130,7 @@ const DropDownList: React.FC<DropDownListProps> = ({
title="collapse-btn"
className="collapse-icon option"
style={{ transform: isOpen ? "rotate(0deg)" : "rotate(-90deg)" }}
// onClick={handleToggle}
// onClick={handleToggle}
>
<ArrowIcon />
</button>

View File

@@ -17,9 +17,10 @@ import {
useZones,
} from "../../../store/builder/store";
import { zoneCameraUpdate } from "../../../services/visulization/zone/zoneCameraUpdation";
import { setFloorItemApi } from "../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi";
import { setAssetsApi } from "../../../services/factoryBuilder/assest/floorAsset/setAssetsApi";
import { useParams } from "react-router-dom";
import { useAssetsStore } from "../../../store/builder/useAssetStore";
import { getUserData } from "../../../functions/getUserData";
import { useSceneContext } from "../../../modules/scene/sceneContext";
interface Asset {
id: string;
@@ -46,12 +47,11 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
const { zoneAssetId, setZoneAssetId } = useZoneAssetId();
const { zones, setZones } = useZones();
const { setSubModule } = useSubModuleStore();
const [expandedZones, setExpandedZones] = useState<Record<string, boolean>>(
{}
);
const [expandedZones, setExpandedZones] = useState<Record<string, boolean>>({});
const { projectId } = useParams();
const { setName } = useAssetsStore();
const { assetStore } = useSceneContext();
const { setName } = assetStore();
const { organization } = getUserData();
useEffect(() => {
useSelectedZoneStore.getState().setSelectedZone({
@@ -81,9 +81,6 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
setSubModule("zoneProperties");
const email = localStorage.getItem("email");
const organization = email?.split("@")[1]?.split(".")[0] ?? "";
let response = await getZoneData(id, organization, projectId);
setSelectedZone({
zoneName: response?.zoneName,
@@ -100,14 +97,12 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
console.log(error);
}
}
function handleAssetClick(asset: Asset) {
setZoneAssetId(asset);
}
async function handleZoneNameChange(newName: string) {
const email = localStorage.getItem("email") ?? "";
const organization = email?.split("@")[1]?.split(".")[0];
const isDuplicate = zones.some(
(zone: any) =>
zone.zoneName?.trim().toLowerCase() === newName?.trim().toLowerCase() &&
@@ -136,18 +131,14 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
}
async function handleZoneAssetName(newName: string) {
const email = localStorage.getItem("email") ?? "";
const organization = email?.split("@")[1]?.split(".")[0];
if (zoneAssetId?.id) {
let response = await setFloorItemApi(
organization,
zoneAssetId.id,
newName,
let response = await setAssetsApi({
modelUuid: zoneAssetId.id,
modelName: newName,
projectId
);
});
// console.log("response: ", response);
console.log(' zoneAssetId.id,: ', zoneAssetId.id,);
setName(zoneAssetId.id, response.modelName);
}
@@ -207,20 +198,23 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
id: '',
name: '',
});
setSubModule("properties")
}
}
};
document.addEventListener('mousedown', onMouseDown);
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
if (selectedZone.zoneName! === '' && activeModule === 'Builder') {
document.addEventListener('mousedown', onMouseDown);
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
}
return () => {
document.removeEventListener('mousedown', onMouseDown);
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
};
}, []);
}, [selectedZone, activeModule]);
return (

View File

@@ -2,12 +2,11 @@ import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
import { ArrowIcon } from "../../icons/ExportCommonIcons";
import { toggleTheme } from "../../../utils/theme";
import useVersionHistoryStore, {
import useVersionHistoryVisibleStore, {
useShortcutStore,
useVersionStore,
} from "../../../store/builder/store";
import { useSubModuleStore } from "../../../store/useModuleStore";
import { generateUniqueId } from "../../../functions/generateUniqueId";
import useModuleStore, { useSubModuleStore } from "../../../store/useModuleStore";
import { useVersionHistoryStore } from "../../../store/builder/useVersionHistoryStore";
interface MenuBarProps {
setOpenMenu: (isOpen: boolean) => void;
@@ -22,16 +21,15 @@ interface MenuItem {
}
const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
const userName = localStorage.getItem("userName") ?? "Anonymous";
const navigate = useNavigate();
const [activeMenu, setActiveMenu] = useState<string | null>(null);
const [activeSubMenu, setActiveSubMenu] = useState<string | null>(null);
const [selectedItems, setSelectedItems] = useState<Record<string, boolean>>(
{}
);
const [selectedItems, setSelectedItems] = useState<Record<string, boolean>>({});
const { setVersionHistory } = useVersionHistoryStore();
const { setCreateNewVersion } = useVersionHistoryStore();
const { setVersionHistoryVisible } = useVersionHistoryVisibleStore();
const { setActiveModule } = useModuleStore();
const { setSubModule } = useSubModuleStore();
const { showShortcuts, setShowShortcuts } = useShortcutStore();
@@ -59,35 +57,21 @@ const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
setShowShortcuts(!showShortcuts);
}
function handleVersionCreation() {
setCreateNewVersion(true);
setVersionHistoryVisible(true);
setSubModule("properties");
setActiveModule('builder');
}
const menus: Record<string, MenuItem[]> = {
File: [
{ label: "New File", shortcut: "Ctrl + N" },
{ label: "Open Local File", shortcut: "Ctrl + O" },
{
label: "Save Version",
action: () => {
const versionStore = useVersionStore.getState();
const versionCount = versionStore.versions.length;
const newVersion = {
id: generateUniqueId(),
versionLabel: `v${versionCount + 1}.0`,
timestamp: `${new Date().toLocaleTimeString("en-US", {
hour: "numeric",
minute: "2-digit",
hour12: true,
})} ${new Date().toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "2-digit",
})}`,
savedBy: userName,
};
console.log("newVersion: ", newVersion);
versionStore.addVersion(newVersion);
},
shortcut: "Ctrl + Alt + S",
action: handleVersionCreation,
},
{ label: "Make a Copy" },
{ label: "Share" },
@@ -236,11 +220,14 @@ const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
setActiveSubMenu(null);
}}
onClick={() => {
setVersionHistory(true);
setVersionHistoryVisible(true);
setSubModule("properties");
setActiveModule('builder');
}}
>
<div className="menu-button">Version history</div>
<div className="menu-button">
Version history <div className="value">Ctrl + H</div>
</div>
</button>
{/* Theme */}

View File

@@ -13,6 +13,7 @@ interface AssetDetailsCardInterface {
enableStatue?: boolean;
count?: number;
totalCapacity?: number;
activeTime?: any;
assetDetails?: {
assetName: string;
const: string;
@@ -59,6 +60,7 @@ const AssetDetailsCard: React.FC<AssetDetailsCardInterface> = ({
status,
count,
totalCapacity,
activeTime,
assetDetails,
}) => {
const [moreDetails, setMoreDetails] = useState(false);
@@ -75,7 +77,10 @@ const AssetDetailsCard: React.FC<AssetDetailsCardInterface> = ({
<div className="content">
<div className="name">{name}</div>
{enableStatue && (
<div className="status-container">{GetStatus(status)}</div>
<>
<div className="active-time">Active Time : <span className="value">{activeTime}</span></div>
<div className="status-container">{GetStatus(status)}</div>
</>
)}
{!enableStatue && totalCapacity && (
<div className="storage-container">Storage/Inventory</div>

View File

@@ -167,7 +167,7 @@ const SimulationPlayer: React.FC = () => {
return (
<>
{isPlaying && activeModule === "simulation" && (
<div className="label-toogler">
<div className="label-toogler "> {/* bottom */}
<InputToggle
value={viewSceneLabels}
inputKey="1"
@@ -187,7 +187,7 @@ const SimulationPlayer: React.FC = () => {
<div className="icon">
<HourlySimulationIcon />
</div>
<div className="label">ThroughPut</div>
<h4 className="label">ThroughPut</h4>
</div>
<div className="progress-wrapper">
<div