updated visualization panel ui and added outer click
This commit is contained in:
commit
ed6edef24e
app/src
components
layout
sidebarLeft/visualization
sidebarRight
ui
modules
builder
agv
geomentries/floors
groups
scene
IntialLoad
controls/selection
simulation/path
visualization
pages
services
store
styles
types/world
utils
|
@ -3,13 +3,10 @@ import { useDroppedObjectsStore } from "../../../../store/useDroppedObjectsStore
|
||||||
import useTemplateStore from "../../../../store/useTemplateStore";
|
import useTemplateStore from "../../../../store/useTemplateStore";
|
||||||
import { useSelectedZoneStore } from "../../../../store/useZoneStore";
|
import { useSelectedZoneStore } from "../../../../store/useZoneStore";
|
||||||
import { getTemplateData } from "../../../../services/realTimeVisulization/zoneData/getTemplate";
|
import { getTemplateData } from "../../../../services/realTimeVisulization/zoneData/getTemplate";
|
||||||
import { deleteTemplateApi } from "../../../../services/realTimeVisulization/zoneData/deleteTemplate";
|
|
||||||
import { loadTempleteApi } from "../../../../services/realTimeVisulization/zoneData/loadTemplate";
|
|
||||||
import { useSocketStore } from "../../../../store/store";
|
import { useSocketStore } from "../../../../store/store";
|
||||||
|
|
||||||
const Templates = () => {
|
const Templates = () => {
|
||||||
const { templates, removeTemplate } = useTemplateStore();
|
const { templates, removeTemplate, setTemplates } = useTemplateStore();
|
||||||
const { setTemplates } = useTemplateStore();
|
|
||||||
const { setSelectedZone, selectedZone } = useSelectedZoneStore();
|
const { setSelectedZone, selectedZone } = useSelectedZoneStore();
|
||||||
const { visualizationSocket } = useSocketStore();
|
const { visualizationSocket } = useSocketStore();
|
||||||
|
|
||||||
|
@ -35,15 +32,11 @@ const Templates = () => {
|
||||||
let deleteTemplate = {
|
let deleteTemplate = {
|
||||||
organization: organization,
|
organization: organization,
|
||||||
templateID: id,
|
templateID: id,
|
||||||
}
|
};
|
||||||
if (visualizationSocket) {
|
if (visualizationSocket) {
|
||||||
visualizationSocket.emit("v2:viz-template:deleteTemplate", deleteTemplate)
|
visualizationSocket.emit("v2:viz-template:deleteTemplate", deleteTemplate);
|
||||||
}
|
}
|
||||||
removeTemplate(id);
|
removeTemplate(id);
|
||||||
// let response = await deleteTemplateApi(id, organization);
|
|
||||||
|
|
||||||
// if (response.message === "Template deleted successfully") {
|
|
||||||
// }
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error deleting template:", error);
|
console.error("Error deleting template:", error);
|
||||||
}
|
}
|
||||||
|
@ -60,16 +53,12 @@ const Templates = () => {
|
||||||
organization: organization,
|
organization: organization,
|
||||||
zoneId: selectedZone.zoneId,
|
zoneId: selectedZone.zoneId,
|
||||||
templateID: template.id,
|
templateID: template.id,
|
||||||
}
|
};
|
||||||
console.log('template: ', template);
|
|
||||||
console.log('loadingTemplate: ', loadingTemplate);
|
|
||||||
|
|
||||||
if (visualizationSocket) {
|
if (visualizationSocket) {
|
||||||
visualizationSocket.emit("v2:viz-template:addToZone", loadingTemplate)
|
visualizationSocket.emit("v2:viz-template:addToZone", loadingTemplate);
|
||||||
}
|
}
|
||||||
// let response = await loadTempleteApi(template.id, selectedZone.zoneId, organization);
|
|
||||||
|
|
||||||
// if (response.message === "Template placed in Zone") {
|
|
||||||
setSelectedZone({
|
setSelectedZone({
|
||||||
panelOrder: template.panelOrder,
|
panelOrder: template.panelOrder,
|
||||||
activeSides: Array.from(new Set(template.panelOrder)), // No merging with previous `activeSides`
|
activeSides: Array.from(new Set(template.panelOrder)), // No merging with previous `activeSides`
|
||||||
|
@ -83,91 +72,35 @@ const Templates = () => {
|
||||||
useDroppedObjectsStore.getState().addObject(selectedZone.zoneName, val);
|
useDroppedObjectsStore.getState().addObject(selectedZone.zoneName, val);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error loading template:", error);
|
console.error("Error loading template:", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="template-list">
|
||||||
className="template-list"
|
|
||||||
style={{
|
|
||||||
display: "grid",
|
|
||||||
gridTemplateColumns: "repeat(auto-fill, minmax(180px, 1fr))",
|
|
||||||
gap: "1rem",
|
|
||||||
padding: "1rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{templates.map((template) => (
|
{templates.map((template) => (
|
||||||
<div
|
<div key={template.id} className="template-item">
|
||||||
key={template.id}
|
|
||||||
className="template-item"
|
|
||||||
style={{
|
|
||||||
border: "1px solid #e0e0e0",
|
|
||||||
borderRadius: "8px",
|
|
||||||
padding: "1rem",
|
|
||||||
transition: "box-shadow 0.3s ease",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{template?.snapshot && (
|
{template?.snapshot && (
|
||||||
<div style={{ position: "relative", paddingBottom: "56.25%" }}>
|
<div className="template-image-container">
|
||||||
{" "}
|
|
||||||
{/* 16:9 aspect ratio */}
|
|
||||||
<img
|
<img
|
||||||
src={template.snapshot} // Corrected from template.image to template.snapshot
|
src={template.snapshot}
|
||||||
alt={`${template.name} preview`}
|
alt={`${template.name} preview`}
|
||||||
style={{
|
className="template-image"
|
||||||
position: "absolute",
|
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
objectFit: "contain",
|
|
||||||
borderRadius: "4px",
|
|
||||||
cursor: "pointer",
|
|
||||||
transition: "transform 0.3s ease",
|
|
||||||
// ':hover': {
|
|
||||||
// transform: 'scale(1.05)'
|
|
||||||
// }
|
|
||||||
}}
|
|
||||||
onClick={() => handleLoadTemplate(template)}
|
onClick={() => handleLoadTemplate(template)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div
|
<div className="template-details">
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
alignItems: "center",
|
|
||||||
marginTop: "0.5rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
onClick={() => handleLoadTemplate(template)}
|
onClick={() => handleLoadTemplate(template)}
|
||||||
style={{
|
className="template-name"
|
||||||
cursor: "pointer",
|
|
||||||
fontWeight: "500",
|
|
||||||
// ':hover': {
|
|
||||||
// textDecoration: 'underline'
|
|
||||||
// }
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{template.name}
|
{template.name}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleDeleteTemplate(template.id)}
|
onClick={() => handleDeleteTemplate(template.id)}
|
||||||
style={{
|
className="delete-button"
|
||||||
padding: "0.25rem 0.5rem",
|
|
||||||
background: "#ff4444",
|
|
||||||
color: "white",
|
|
||||||
border: "none",
|
|
||||||
borderRadius: "4px",
|
|
||||||
cursor: "pointer",
|
|
||||||
transition: "opacity 0.3s ease",
|
|
||||||
// ':hover': {
|
|
||||||
// opacity: 0.8
|
|
||||||
// }
|
|
||||||
}}
|
|
||||||
aria-label="Delete template"
|
aria-label="Delete template"
|
||||||
>
|
>
|
||||||
Delete
|
Delete
|
||||||
|
@ -176,14 +109,7 @@ const Templates = () => {
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
{templates.length === 0 && (
|
{templates.length === 0 && (
|
||||||
<div
|
<div className="no-templates">
|
||||||
style={{
|
|
||||||
textAlign: "center",
|
|
||||||
color: "#666",
|
|
||||||
padding: "2rem",
|
|
||||||
gridColumn: "1 / -1",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
No saved templates yet. Create one in the visualization view!
|
No saved templates yet. Create one in the visualization view!
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -192,4 +118,3 @@ const Templates = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Templates;
|
export default Templates;
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ const WidgetsFloating = () => {
|
||||||
))} */}
|
))} */}
|
||||||
{/* Floating 1 */}
|
{/* Floating 1 */}
|
||||||
<SimpleCard
|
<SimpleCard
|
||||||
header={"Today’s Money"}
|
header={"Today’s Earnings"}
|
||||||
icon={WalletIcon}
|
icon={WalletIcon}
|
||||||
value={"$53,000"}
|
value={"$53,000"}
|
||||||
per={"+55%"}
|
per={"+55%"}
|
||||||
|
|
|
@ -22,6 +22,8 @@ import GlobalProperties from "./properties/GlobalProperties";
|
||||||
import AsstePropertiies from "./properties/AssetProperties";
|
import AsstePropertiies from "./properties/AssetProperties";
|
||||||
import ZoneProperties from "./properties/ZoneProperties";
|
import ZoneProperties from "./properties/ZoneProperties";
|
||||||
import VehicleMechanics from "./mechanics/VehicleMechanics";
|
import VehicleMechanics from "./mechanics/VehicleMechanics";
|
||||||
|
import StaticMachineMechanics from "./mechanics/StaticMachineMechanics";
|
||||||
|
import ArmBotMechanics from "./mechanics/ArmBotMechanics";
|
||||||
|
|
||||||
const SideBarRight: React.FC = () => {
|
const SideBarRight: React.FC = () => {
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
|
@ -42,8 +44,7 @@ const SideBarRight: React.FC = () => {
|
||||||
<div className="sidebar-actions-container">
|
<div className="sidebar-actions-container">
|
||||||
{/* {activeModule === "builder" && ( */}
|
{/* {activeModule === "builder" && ( */}
|
||||||
<div
|
<div
|
||||||
className={`sidebar-action-list ${
|
className={`sidebar-action-list ${subModule === "properties" ? "active" : ""
|
||||||
subModule === "properties" ? "active" : ""
|
|
||||||
}`}
|
}`}
|
||||||
onClick={() => setSubModule("properties")}
|
onClick={() => setSubModule("properties")}
|
||||||
>
|
>
|
||||||
|
@ -53,24 +54,21 @@ const SideBarRight: React.FC = () => {
|
||||||
{activeModule === "simulation" && (
|
{activeModule === "simulation" && (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className={`sidebar-action-list ${
|
className={`sidebar-action-list ${subModule === "mechanics" ? "active" : ""
|
||||||
subModule === "mechanics" ? "active" : ""
|
|
||||||
}`}
|
}`}
|
||||||
onClick={() => setSubModule("mechanics")}
|
onClick={() => setSubModule("mechanics")}
|
||||||
>
|
>
|
||||||
<MechanicsIcon isActive={subModule === "mechanics"} />
|
<MechanicsIcon isActive={subModule === "mechanics"} />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={`sidebar-action-list ${
|
className={`sidebar-action-list ${subModule === "simulations" ? "active" : ""
|
||||||
subModule === "simulations" ? "active" : ""
|
|
||||||
}`}
|
}`}
|
||||||
onClick={() => setSubModule("simulations")}
|
onClick={() => setSubModule("simulations")}
|
||||||
>
|
>
|
||||||
<SimulationIcon isActive={subModule === "simulations"} />
|
<SimulationIcon isActive={subModule === "simulations"} />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={`sidebar-action-list ${
|
className={`sidebar-action-list ${subModule === "analysis" ? "active" : ""
|
||||||
subModule === "analysis" ? "active" : ""
|
|
||||||
}`}
|
}`}
|
||||||
onClick={() => setSubModule("analysis")}
|
onClick={() => setSubModule("analysis")}
|
||||||
>
|
>
|
||||||
|
@ -132,10 +130,28 @@ const SideBarRight: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{subModule === "mechanics" &&
|
||||||
|
selectedActionSphere &&
|
||||||
|
selectedActionSphere.path.type === "StaticMachine" && (
|
||||||
|
<div className="sidebar-right-container">
|
||||||
|
<div className="sidebar-right-content-container">
|
||||||
|
<StaticMachineMechanics />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{subModule === "mechanics" &&
|
||||||
|
selectedActionSphere &&
|
||||||
|
selectedActionSphere.path.type === "ArmBot" && (
|
||||||
|
<div className="sidebar-right-container">
|
||||||
|
<div className="sidebar-right-content-container">
|
||||||
|
<ArmBotMechanics />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{subModule === "mechanics" && !selectedActionSphere && (
|
{subModule === "mechanics" && !selectedActionSphere && (
|
||||||
<div className="sidebar-right-container">
|
<div className="sidebar-right-container">
|
||||||
<div className="sidebar-right-content-container">
|
<div className="sidebar-right-content-container">
|
||||||
<ConveyorMechanics />
|
<ConveyorMechanics /> {/* default */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
import React, { useRef, useMemo } from "react";
|
||||||
|
import { InfoIcon } from "../../../icons/ExportCommonIcons";
|
||||||
|
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||||
|
import { useEditingPoint, useEyeDropMode, usePreviewPosition, useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store";
|
||||||
|
import * as Types from '../../../../types/world/worldTypes';
|
||||||
|
import PositionInput from "../customInput/PositionInputs";
|
||||||
|
import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt";
|
||||||
|
|
||||||
|
const ArmBotMechanics: React.FC = () => {
|
||||||
|
const { selectedActionSphere } = useSelectedActionSphere();
|
||||||
|
const { simulationStates, setSimulationStates } = useSimulationStates();
|
||||||
|
const { socket } = useSocketStore();
|
||||||
|
|
||||||
|
const propertiesContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
const { selectedPoint, connectedPointUuids } = useMemo(() => {
|
||||||
|
if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null, connectedPointUuids: [] };
|
||||||
|
|
||||||
|
const vehiclePaths = simulationStates.filter(
|
||||||
|
(path): path is Types.ArmBotEventsSchema => path.type === "ArmBot"
|
||||||
|
);
|
||||||
|
|
||||||
|
const points = vehiclePaths.find(
|
||||||
|
(path) => path.points.uuid === selectedActionSphere.points.uuid
|
||||||
|
)?.points;
|
||||||
|
|
||||||
|
if (!points) return { selectedPoint: null, connectedPointUuids: [] };
|
||||||
|
|
||||||
|
const connectedUuids: string[] = [];
|
||||||
|
if (points.connections?.targets) {
|
||||||
|
points.connections.targets.forEach(target => {
|
||||||
|
connectedUuids.push(target.pointUUID);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
selectedPoint: points,
|
||||||
|
connectedPointUuids: connectedUuids
|
||||||
|
};
|
||||||
|
}, [selectedActionSphere, simulationStates]);
|
||||||
|
|
||||||
|
const updateBackend = async (updatedPath: Types.ArmBotEventsSchema | undefined) => {
|
||||||
|
if (!updatedPath) return;
|
||||||
|
const email = localStorage.getItem("email");
|
||||||
|
const organization = email ? email.split("@")[1].split(".")[0] : "";
|
||||||
|
|
||||||
|
// await setEventApi(
|
||||||
|
// organization,
|
||||||
|
// updatedPath.modeluuid,
|
||||||
|
// { type: "ArmBot", points: updatedPath.points }
|
||||||
|
// );
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
organization: organization,
|
||||||
|
modeluuid: updatedPath.modeluuid,
|
||||||
|
eventData: { type: "ArmBot", points: updatedPath.points }
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.emit('v2:model-asset:updateEventData', data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="machine-mechanics-container" key={selectedPoint?.uuid}>
|
||||||
|
<div className="machine-mechanics-header">
|
||||||
|
{selectedActionSphere?.path?.modelName || "ArmBot point not found"}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="machine-mechanics-content-container">
|
||||||
|
<div className="selected-properties-container" ref={propertiesContainerRef}>
|
||||||
|
<div className="properties-header">ArmBot Properties</div>
|
||||||
|
|
||||||
|
{selectedPoint && (
|
||||||
|
<>
|
||||||
|
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="footer">
|
||||||
|
<InfoIcon />
|
||||||
|
Configure armbot properties.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default React.memo(ArmBotMechanics);
|
|
@ -332,9 +332,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
const updatedPath = updatedPaths.find(
|
const updatedPath = updatedPaths.find(
|
||||||
(path): path is Types.ConveyorEventsSchema =>
|
(path): path is Types.ConveyorEventsSchema =>
|
||||||
path.type === "Conveyor" &&
|
path.type === "Conveyor" &&
|
||||||
path.points.some(
|
path.modeluuid === selectedPath.path.modeluuid
|
||||||
(point) => point.uuid === selectedActionSphere.points.uuid
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
updateBackend(updatedPath);
|
updateBackend(updatedPath);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
import React, { useRef, useMemo } from "react";
|
||||||
|
import { InfoIcon } from "../../../icons/ExportCommonIcons";
|
||||||
|
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||||
|
import { useEditingPoint, useEyeDropMode, usePreviewPosition, useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store";
|
||||||
|
import * as Types from '../../../../types/world/worldTypes';
|
||||||
|
import PositionInput from "../customInput/PositionInputs";
|
||||||
|
import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt";
|
||||||
|
|
||||||
|
const StaticMachineMechanics: React.FC = () => {
|
||||||
|
const { selectedActionSphere } = useSelectedActionSphere();
|
||||||
|
const { simulationStates, setSimulationStates } = useSimulationStates();
|
||||||
|
const { socket } = useSocketStore();
|
||||||
|
|
||||||
|
const propertiesContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
const { selectedPoint, connectedPointUuids } = useMemo(() => {
|
||||||
|
if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null, connectedPointUuids: [] };
|
||||||
|
|
||||||
|
const vehiclePaths = simulationStates.filter(
|
||||||
|
(path): path is Types.StaticMachineEventsSchema => path.type === "StaticMachine"
|
||||||
|
);
|
||||||
|
|
||||||
|
const points = vehiclePaths.find(
|
||||||
|
(path) => path.points.uuid === selectedActionSphere.points.uuid
|
||||||
|
)?.points;
|
||||||
|
|
||||||
|
if (!points) return { selectedPoint: null, connectedPointUuids: [] };
|
||||||
|
|
||||||
|
const connectedUuids: string[] = [];
|
||||||
|
if (points.connections?.targets) {
|
||||||
|
points.connections.targets.forEach(target => {
|
||||||
|
connectedUuids.push(target.pointUUID);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
selectedPoint: points,
|
||||||
|
connectedPointUuids: connectedUuids
|
||||||
|
};
|
||||||
|
}, [selectedActionSphere, simulationStates]);
|
||||||
|
|
||||||
|
const updateBackend = async (updatedPath: Types.StaticMachineEventsSchema | undefined) => {
|
||||||
|
if (!updatedPath) return;
|
||||||
|
const email = localStorage.getItem("email");
|
||||||
|
const organization = email ? email.split("@")[1].split(".")[0] : "";
|
||||||
|
|
||||||
|
// await setEventApi(
|
||||||
|
// organization,
|
||||||
|
// updatedPath.modeluuid,
|
||||||
|
// { type: "StaticMachine", points: updatedPath.points }
|
||||||
|
// );
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
organization: organization,
|
||||||
|
modeluuid: updatedPath.modeluuid,
|
||||||
|
eventData: { type: "StaticMachine", points: updatedPath.points }
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.emit('v2:model-asset:updateEventData', data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="machine-mechanics-container" key={selectedPoint?.uuid}>
|
||||||
|
<div className="machine-mechanics-header">
|
||||||
|
{selectedActionSphere?.path?.modelName || "Machine point not found"}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="machine-mechanics-content-container">
|
||||||
|
<div className="selected-properties-container" ref={propertiesContainerRef}>
|
||||||
|
<div className="properties-header">Machine Properties</div>
|
||||||
|
|
||||||
|
{selectedPoint && (
|
||||||
|
<>
|
||||||
|
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="footer">
|
||||||
|
<InfoIcon />
|
||||||
|
Configure machine properties.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default React.memo(StaticMachineMechanics);
|
|
@ -28,9 +28,12 @@ const ZoneProperties: React.FC = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = await zoneCameraUpdate(zonesdata, organization);
|
let response = await zoneCameraUpdate(zonesdata, organization);
|
||||||
console.log('response: ', response);
|
if (response.message === "updated successfully") {
|
||||||
|
|
||||||
setEdit(false);
|
setEdit(false);
|
||||||
|
} else {
|
||||||
|
console.log("Not updated Camera Position and Target");
|
||||||
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error in handleSetView:", error);
|
console.error("Error in handleSetView:", error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import {
|
||||||
import useToggleStore from "../../store/useUIToggleStore";
|
import useToggleStore from "../../store/useUIToggleStore";
|
||||||
import {
|
import {
|
||||||
use3DWidget,
|
use3DWidget,
|
||||||
|
useDroppedObjectsStore,
|
||||||
useFloatingWidget,
|
useFloatingWidget,
|
||||||
} from "../../store/useDroppedObjectsStore";
|
} from "../../store/useDroppedObjectsStore";
|
||||||
|
|
||||||
|
@ -52,8 +53,12 @@ const Tools: React.FC = () => {
|
||||||
const { addTemplate } = useTemplateStore();
|
const { addTemplate } = useTemplateStore();
|
||||||
const { selectedZone } = useSelectedZoneStore();
|
const { selectedZone } = useSelectedZoneStore();
|
||||||
const { floatingWidget } = useFloatingWidget();
|
const { floatingWidget } = useFloatingWidget();
|
||||||
|
|
||||||
const { widgets3D } = use3DWidget();
|
const { widgets3D } = use3DWidget();
|
||||||
|
|
||||||
|
const zones = useDroppedObjectsStore((state) => state.zones);
|
||||||
|
|
||||||
|
|
||||||
// wall options
|
// wall options
|
||||||
const { toggleView, setToggleView } = useToggleView();
|
const { toggleView, setToggleView } = useToggleView();
|
||||||
const { setDeleteModels } = useDeleteModels();
|
const { setDeleteModels } = useDeleteModels();
|
||||||
|
@ -409,10 +414,9 @@ const Tools: React.FC = () => {
|
||||||
widgets3D,
|
widgets3D,
|
||||||
selectedZone,
|
selectedZone,
|
||||||
templates,
|
templates,
|
||||||
visualizationSocket
|
visualizationSocket,
|
||||||
})
|
});
|
||||||
}
|
}}
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<SaveTemplateIcon isActive={false} />
|
<SaveTemplateIcon isActive={false} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -65,6 +65,8 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
|
|
||||||
// Function to toggle lock/unlock a panel
|
// Function to toggle lock/unlock a panel
|
||||||
const toggleLockPanel = (side: Side) => {
|
const toggleLockPanel = (side: Side) => {
|
||||||
|
console.log('side: ', side);
|
||||||
|
//add api
|
||||||
const newLockedPanels = selectedZone.lockedPanels.includes(side)
|
const newLockedPanels = selectedZone.lockedPanels.includes(side)
|
||||||
? selectedZone.lockedPanels.filter((panel) => panel !== side)
|
? selectedZone.lockedPanels.filter((panel) => panel !== side)
|
||||||
: [...selectedZone.lockedPanels, side];
|
: [...selectedZone.lockedPanels, side];
|
||||||
|
@ -92,6 +94,8 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
|
|
||||||
// Function to clean all widgets from a panel
|
// Function to clean all widgets from a panel
|
||||||
const cleanPanel = (side: Side) => {
|
const cleanPanel = (side: Side) => {
|
||||||
|
//add api
|
||||||
|
console.log('side: ', side);
|
||||||
const cleanedWidgets = selectedZone.widgets.filter(
|
const cleanedWidgets = selectedZone.widgets.filter(
|
||||||
(widget) => widget.panel !== side
|
(widget) => widget.panel !== side
|
||||||
);
|
);
|
||||||
|
@ -100,7 +104,6 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
...selectedZone,
|
...selectedZone,
|
||||||
widgets: cleanedWidgets,
|
widgets: cleanedWidgets,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update the selectedZone state
|
// Update the selectedZone state
|
||||||
setSelectedZone(updatedZone);
|
setSelectedZone(updatedZone);
|
||||||
};
|
};
|
||||||
|
|
|
@ -74,6 +74,7 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||||
const [showLeftArrow, setShowLeftArrow] = useState(false);
|
const [showLeftArrow, setShowLeftArrow] = useState(false);
|
||||||
const [showRightArrow, setShowRightArrow] = useState(false);
|
const [showRightArrow, setShowRightArrow] = useState(false);
|
||||||
const { floatingWidget, setFloatingWidget } = useFloatingWidget()
|
const { floatingWidget, setFloatingWidget } = useFloatingWidget()
|
||||||
|
|
||||||
const{setSelectedChartId}=useWidgetStore()
|
const{setSelectedChartId}=useWidgetStore()
|
||||||
|
|
||||||
// Function to calculate overflow state
|
// Function to calculate overflow state
|
||||||
|
@ -178,7 +179,7 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||||
zoneViewPortPosition: response.viewPortposition || {},
|
zoneViewPortPosition: response.viewPortposition || {},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { deleteWidgetApi } from "../../../services/realTimeVisulization/zoneData
|
||||||
import { useClickOutside } from "./functions/handleWidgetsOuterClick";
|
import { useClickOutside } from "./functions/handleWidgetsOuterClick";
|
||||||
import { useSocketStore } from "../../../store/store";
|
import { useSocketStore } from "../../../store/store";
|
||||||
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
||||||
|
import OuterClick from "../../../utils/outerClick";
|
||||||
|
|
||||||
type Side = "top" | "bottom" | "left" | "right";
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
|
@ -89,6 +90,11 @@ export const DraggableWidget = ({
|
||||||
|
|
||||||
const isPanelHidden = hiddenPanels.includes(widget.panel);
|
const isPanelHidden = hiddenPanels.includes(widget.panel);
|
||||||
|
|
||||||
|
OuterClick({
|
||||||
|
contextClassName: ["chart-container", "floating", "sidebar-right-wrapper"],
|
||||||
|
setMenuVisible: () => setSelectedChartId(null),
|
||||||
|
});
|
||||||
|
|
||||||
const deleteSelectedChart = async () => {
|
const deleteSelectedChart = async () => {
|
||||||
try {
|
try {
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
|
@ -251,11 +257,9 @@ export const DraggableWidget = ({
|
||||||
});
|
});
|
||||||
// Track canvas dimensions
|
// Track canvas dimensions
|
||||||
|
|
||||||
|
// Current: Two identical useEffect hooks for canvas dimensions
|
||||||
|
// Remove the duplicate and keep only one
|
||||||
// Current: Two identical useEffect hooks for canvas dimensions
|
useEffect(() => {
|
||||||
// Remove the duplicate and keep only one
|
|
||||||
useEffect(() => {
|
|
||||||
const canvas = document.getElementById("real-time-vis-canvas");
|
const canvas = document.getElementById("real-time-vis-canvas");
|
||||||
if (!canvas) return;
|
if (!canvas) return;
|
||||||
|
|
||||||
|
@ -272,15 +276,16 @@ useEffect(() => {
|
||||||
resizeObserver.observe(canvas);
|
resizeObserver.observe(canvas);
|
||||||
|
|
||||||
return () => resizeObserver.unobserve(canvas);
|
return () => resizeObserver.unobserve(canvas);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<style>
|
<style>
|
||||||
{`
|
{`
|
||||||
:root {
|
:root {
|
||||||
--realTimeViz-container-width: ${canvasDimensions.width * 0.25}px;
|
--realTimeViz-container-width: ${canvasDimensions.width}px;
|
||||||
--realTimeViz-container-height: ${canvasDimensions.height}px;
|
--realTimeViz-container-height: ${canvasDimensions.height}px;
|
||||||
|
|
||||||
}
|
}
|
||||||
`}
|
`}
|
||||||
</style>
|
</style>
|
||||||
|
@ -296,13 +301,12 @@ useEffect(() => {
|
||||||
onDragOver={handleDragOver}
|
onDragOver={handleDragOver}
|
||||||
onDrop={handleDrop}
|
onDrop={handleDrop}
|
||||||
style={{
|
style={{
|
||||||
// Apply styles based on panel position
|
|
||||||
width: ["top", "bottom"].includes(widget.panel)
|
width: ["top", "bottom"].includes(widget.panel)
|
||||||
? `calc(${canvasDimensions.width * 0.16}px - 2px)` // For top/bottom panels, set width
|
? `calc(${canvasDimensions.width}px / 6)`
|
||||||
: undefined, // Don't set width if it's left or right
|
: undefined,
|
||||||
height: ["left", "right"].includes(widget.panel)
|
height: ["left", "right"].includes(widget.panel)
|
||||||
? `calc(${canvasDimensions.height * 0.25}px - 2px)` // For left/right panels, set height
|
? `calc(${canvasDimensions.height - 10}px / 4)`
|
||||||
: undefined, // Don't set height if it's top or bottom
|
: undefined,
|
||||||
}}
|
}}
|
||||||
ref={chartWidget}
|
ref={chartWidget}
|
||||||
onClick={() => setSelectedChartId(widget)}
|
onClick={() => setSelectedChartId(widget)}
|
||||||
|
@ -393,4 +397,4 @@ useEffect(() => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// while resize calculate --realTimeViz-container-height pprperly
|
|
||||||
|
|
|
@ -44,9 +44,7 @@ export default function Dropped3dWidgets() {
|
||||||
const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0)); // Floor plane for horizontal move
|
const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0)); // Floor plane for horizontal move
|
||||||
const verticalPlane = useRef(new THREE.Plane(new THREE.Vector3(0, 0, 1), 0)); // Vertical plane for vertical move
|
const verticalPlane = useRef(new THREE.Plane(new THREE.Vector3(0, 0, 1), 0)); // Vertical plane for vertical move
|
||||||
const planeIntersect = useRef(new THREE.Vector3());
|
const planeIntersect = useRef(new THREE.Vector3());
|
||||||
// const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
|
|
||||||
// const verticalPlane = useRef(new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);
|
|
||||||
// const planeIntersect = useRef(new THREE.Vector3());
|
|
||||||
const rotationStartRef = useRef<[number, number, number]>([0, 0, 0]);
|
const rotationStartRef = useRef<[number, number, number]>([0, 0, 0]);
|
||||||
const mouseStartRef = useRef<{ x: number; y: number }>({ x: 0, y: 0 });
|
const mouseStartRef = useRef<{ x: number; y: number }>({ x: 0, y: 0 });
|
||||||
|
|
||||||
|
@ -60,7 +58,7 @@ export default function Dropped3dWidgets() {
|
||||||
|
|
||||||
async function get3dWidgetData() {
|
async function get3dWidgetData() {
|
||||||
const result = await get3dWidgetZoneData(selectedZone.zoneId, organization);
|
const result = await get3dWidgetZoneData(selectedZone.zoneId, organization);
|
||||||
console.log('result: ', result);
|
|
||||||
setWidgets3D(result);
|
setWidgets3D(result);
|
||||||
|
|
||||||
const formattedWidgets = result.map((widget: WidgetData) => ({
|
const formattedWidgets = result.map((widget: WidgetData) => ({
|
||||||
|
@ -84,8 +82,31 @@ export default function Dropped3dWidgets() {
|
||||||
|
|
||||||
const canvasElement = gl.domElement;
|
const canvasElement = gl.domElement;
|
||||||
|
|
||||||
|
const handleDragEnter = (event: DragEvent) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
console.log("Drag enter");
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDragOver = (event: DragEvent) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDragLeave = (event: DragEvent) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
console.log("Drag leave");
|
||||||
|
// Remove visual feedback
|
||||||
|
canvasElement.style.cursor = "";
|
||||||
|
};
|
||||||
|
|
||||||
const onDrop = async (event: DragEvent) => {
|
const onDrop = async (event: DragEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
canvasElement.style.cursor = ""; // Reset cursor
|
||||||
|
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0];
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
|
@ -93,6 +114,12 @@ export default function Dropped3dWidgets() {
|
||||||
const group1 = scene.getObjectByName("itemsGroup");
|
const group1 = scene.getObjectByName("itemsGroup");
|
||||||
if (!group1) return;
|
if (!group1) return;
|
||||||
|
|
||||||
|
// Update raycaster with current mouse position
|
||||||
|
const rect = canvasElement.getBoundingClientRect();
|
||||||
|
mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
|
||||||
|
mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
|
||||||
|
raycaster.setFromCamera(mouse, camera);
|
||||||
|
|
||||||
const intersects = raycaster.intersectObjects(scene.children, true).filter(
|
const intersects = raycaster.intersectObjects(scene.children, true).filter(
|
||||||
(intersect) =>
|
(intersect) =>
|
||||||
!intersect.object.name.includes("Roof") &&
|
!intersect.object.name.includes("Roof") &&
|
||||||
|
@ -125,12 +152,21 @@ export default function Dropped3dWidgets() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Add all event listeners
|
||||||
|
// canvasElement.addEventListener("dragenter", handleDragEnter);
|
||||||
|
// canvasElement.addEventListener("dragover", handleDragOver);
|
||||||
|
// canvasElement.addEventListener("dragleave", handleDragLeave);
|
||||||
canvasElement.addEventListener("drop", onDrop);
|
canvasElement.addEventListener("drop", onDrop);
|
||||||
return () => {
|
|
||||||
canvasElement.removeEventListener("drop", onDrop);
|
|
||||||
};
|
|
||||||
}, [widgetSelect, activeModule, selectedZone.zoneId, widgetSubOption]);
|
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
// // Clean up all event listeners
|
||||||
|
// canvasElement.removeEventListener("dragenter", handleDragEnter);
|
||||||
|
// canvasElement.removeEventListener("dragover", handleDragOver);
|
||||||
|
// canvasElement.removeEventListener("dragleave", handleDragLeave);
|
||||||
|
canvasElement.removeEventListener("drop", onDrop);
|
||||||
|
canvasElement.style.cursor = ""; // Ensure cursor is reset
|
||||||
|
};
|
||||||
|
}, [widgetSelect, activeModule, selectedZone.zoneId, widgetSubOption, gl.domElement, scene, raycaster, camera]);
|
||||||
const activeZoneWidgets = zoneWidgetData[selectedZone.zoneId] || [];
|
const activeZoneWidgets = zoneWidgetData[selectedZone.zoneId] || [];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -161,7 +197,7 @@ export default function Dropped3dWidgets() {
|
||||||
visualizationSocket.emit("v2:viz-3D-widget:add", adding3dWidget);
|
visualizationSocket.emit("v2:viz-3D-widget:add", adding3dWidget);
|
||||||
}
|
}
|
||||||
// let response = await adding3dWidgets(selectedZone.zoneId, organization, newWidget)
|
// let response = await adding3dWidgets(selectedZone.zoneId, organization, newWidget)
|
||||||
// console.log('response: ', response);
|
//
|
||||||
|
|
||||||
addWidget(selectedZone.zoneId, newWidget);
|
addWidget(selectedZone.zoneId, newWidget);
|
||||||
setRightSelect(null);
|
setRightSelect(null);
|
||||||
|
@ -179,7 +215,7 @@ export default function Dropped3dWidgets() {
|
||||||
zoneId: selectedZone.zoneId,
|
zoneId: selectedZone.zoneId,
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log('deleteWidget: ', deleteWidget);
|
|
||||||
if (visualizationSocket) {
|
if (visualizationSocket) {
|
||||||
visualizationSocket.emit("v2:viz-3D-widget:delete", deleteWidget);
|
visualizationSocket.emit("v2:viz-3D-widget:delete", deleteWidget);
|
||||||
}
|
}
|
||||||
|
@ -190,7 +226,7 @@ export default function Dropped3dWidgets() {
|
||||||
activeZoneWidgets.filter((w: WidgetData) => w.id !== rightClickSelected)
|
activeZoneWidgets.filter((w: WidgetData) => w.id !== rightClickSelected)
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error deleting widget:", error);
|
|
||||||
} finally {
|
} finally {
|
||||||
setRightClickSelected(null);
|
setRightClickSelected(null);
|
||||||
setRightSelect(null);
|
setRightSelect(null);
|
||||||
|
@ -304,20 +340,15 @@ export default function Dropped3dWidgets() {
|
||||||
|
|
||||||
const selectedWidget = zoneWidgetData[selectedZone].find(widget => widget.id === rightClickSelected);
|
const selectedWidget = zoneWidgetData[selectedZone].find(widget => widget.id === rightClickSelected);
|
||||||
if (!selectedWidget) return;
|
if (!selectedWidget) return;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Format values to 2 decimal places
|
// Format values to 2 decimal places
|
||||||
const formatValues = (vals: number[]) => vals.map(val => parseFloat(val.toFixed(2)));
|
const formatValues = (vals: number[]) => vals.map(val => parseFloat(val.toFixed(2)));
|
||||||
|
|
||||||
if (rightSelect === "Horizontal Move" || rightSelect === "Vertical Move") {
|
if (rightSelect === "Horizontal Move" || rightSelect === "Vertical Move") {
|
||||||
console.log(`${rightSelect} Completed - Full Position:`, formatValues(selectedWidget.position));
|
|
||||||
let lastPosition = formatValues(selectedWidget.position) as [number, number, number];
|
let lastPosition = formatValues(selectedWidget.position) as [number, number, number];
|
||||||
// (async () => {
|
// (async () => {
|
||||||
// let response = await update3dWidget(selectedZone, organization, rightClickSelected, lastPosition);
|
// let response = await update3dWidget(selectedZone, organization, rightClickSelected, lastPosition);
|
||||||
// console.log('response: ', response);
|
//
|
||||||
// if (response) {
|
// if (response) {
|
||||||
// console.log("Widget position updated in API:", response);
|
//
|
||||||
// }
|
// }
|
||||||
// })();
|
// })();
|
||||||
let updatingPosition = {
|
let updatingPosition = {
|
||||||
|
@ -333,13 +364,13 @@ export default function Dropped3dWidgets() {
|
||||||
}
|
}
|
||||||
else if (rightSelect.includes("Rotate")) {
|
else if (rightSelect.includes("Rotate")) {
|
||||||
const rotation = selectedWidget.rotation || [0, 0, 0];
|
const rotation = selectedWidget.rotation || [0, 0, 0];
|
||||||
console.log(`${rightSelect} Completed - Full Rotation:`, formatValues(rotation));
|
|
||||||
let lastRotation = formatValues(rotation) as [number, number, number];
|
let lastRotation = formatValues(rotation) as [number, number, number];
|
||||||
// (async () => {
|
// (async () => {
|
||||||
// let response = await update3dWidgetRotation(selectedZone, organization, rightClickSelected, lastRotation);
|
// let response = await update3dWidgetRotation(selectedZone, organization, rightClickSelected, lastRotation);
|
||||||
// console.log('response: ', response);
|
//
|
||||||
// if (response) {
|
// if (response) {
|
||||||
// console.log("Widget position updated in API:", response);
|
//
|
||||||
// }
|
// }
|
||||||
// })();
|
// })();
|
||||||
let updatingRotation = {
|
let updatingRotation = {
|
||||||
|
@ -388,49 +419,13 @@ export default function Dropped3dWidgets() {
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "ui-Widget 1":
|
case "ui-Widget 1":
|
||||||
return (
|
return (<ProductionCapacity key={id} id={id} type={type} position={position} rotation={rotation} onContextMenu={(e) => handleRightClick(e, id)} />);
|
||||||
<ProductionCapacity
|
|
||||||
key={id}
|
|
||||||
id={id}
|
|
||||||
type={type}
|
|
||||||
position={position}
|
|
||||||
rotation={rotation}
|
|
||||||
onContextMenu={(e) => handleRightClick(e, id)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
case "ui-Widget 2":
|
case "ui-Widget 2":
|
||||||
return (
|
return (<ReturnOfInvestment key={id} id={id} type={type} position={position} rotation={rotation} onContextMenu={(e) => handleRightClick(e, id)} />);
|
||||||
<ReturnOfInvestment
|
|
||||||
key={id}
|
|
||||||
id={id}
|
|
||||||
type={type}
|
|
||||||
position={position}
|
|
||||||
rotation={rotation}
|
|
||||||
onContextMenu={(e) => handleRightClick(e, id)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
case "ui-Widget 3":
|
case "ui-Widget 3":
|
||||||
return (
|
return (<StateWorking key={id} id={id} type={type} position={position} rotation={rotation} onContextMenu={(e) => handleRightClick(e, id)} />);
|
||||||
<StateWorking
|
|
||||||
key={id}
|
|
||||||
id={id}
|
|
||||||
type={type}
|
|
||||||
position={position}
|
|
||||||
rotation={rotation}
|
|
||||||
onContextMenu={(e) => handleRightClick(e, id)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
case "ui-Widget 4":
|
case "ui-Widget 4":
|
||||||
return (
|
return (<Throughput key={id} id={id} type={type} position={position} rotation={rotation} onContextMenu={(e) => handleRightClick(e, id)} />);
|
||||||
<Throughput
|
|
||||||
key={id}
|
|
||||||
id={id}
|
|
||||||
type={type}
|
|
||||||
position={position}
|
|
||||||
rotation={rotation}
|
|
||||||
onContextMenu={(e) => handleRightClick(e, id)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,12 +126,11 @@ const DroppedObjects: React.FC = () => {
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0];
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
|
|
||||||
|
|
||||||
let deleteFloatingWidget = {
|
let deleteFloatingWidget = {
|
||||||
floatWidgetID: id,
|
floatWidgetID: id,
|
||||||
organization: organization,
|
organization: organization,
|
||||||
zoneId: zone.zoneId
|
zoneId: zone.zoneId,
|
||||||
}
|
};
|
||||||
|
|
||||||
if (visualizationSocket) {
|
if (visualizationSocket) {
|
||||||
visualizationSocket.emit("v2:viz-float:delete", deleteFloatingWidget);
|
visualizationSocket.emit("v2:viz-float:delete", deleteFloatingWidget);
|
||||||
|
@ -144,9 +143,7 @@ const DroppedObjects: React.FC = () => {
|
||||||
// if (res.message === "FloatingWidget deleted successfully") {
|
// if (res.message === "FloatingWidget deleted successfully") {
|
||||||
// deleteObject(zoneName, id, index); // Call the deleteObject method from the store
|
// deleteObject(zoneName, id, index); // Call the deleteObject method from the store
|
||||||
// }
|
// }
|
||||||
} catch (error) {
|
} catch (error) {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePointerDown = (event: React.PointerEvent, index: number) => {
|
const handlePointerDown = (event: React.PointerEvent, index: number) => {
|
||||||
|
@ -461,15 +458,14 @@ const DroppedObjects: React.FC = () => {
|
||||||
position: boundedPosition,
|
position: boundedPosition,
|
||||||
},
|
},
|
||||||
index: draggingIndex.index,
|
index: draggingIndex.index,
|
||||||
zoneId: zone.zoneId
|
zoneId: zone.zoneId,
|
||||||
}
|
};
|
||||||
if (visualizationSocket) {
|
if (visualizationSocket) {
|
||||||
visualizationSocket.emit("v2:viz-float:add", updateFloatingWidget);
|
visualizationSocket.emit("v2:viz-float:add", updateFloatingWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (response.message === "Widget updated successfully") {
|
// if (response.message === "Widget updated successfully") {
|
||||||
|
|
||||||
console.log('boundedPosition: ', boundedPosition);
|
|
||||||
updateObjectPosition(zoneName, draggingIndex.index, boundedPosition);
|
updateObjectPosition(zoneName, draggingIndex.index, boundedPosition);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@ -503,47 +499,74 @@ const DroppedObjects: React.FC = () => {
|
||||||
setOpenKebabId((prevId) => (prevId === id ? null : id));
|
setOpenKebabId((prevId) => (prevId === id ? null : id));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const containerHeight = getComputedStyle(
|
||||||
|
document.documentElement
|
||||||
|
).getPropertyValue("--realTimeViz-container-height");
|
||||||
|
const containerWidth = getComputedStyle(
|
||||||
|
document.documentElement
|
||||||
|
).getPropertyValue("--realTimeViz-container-width");
|
||||||
|
|
||||||
|
const heightMultiplier = parseFloat(containerHeight) * 0.14;
|
||||||
|
|
||||||
|
const widthMultiplier = parseFloat(containerWidth) * 0.13;
|
||||||
|
|
||||||
|
console.log("zone.objects: ", zone.objects);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
onPointerMove={handlePointerMove}
|
onPointerMove={handlePointerMove}
|
||||||
onPointerUp={handlePointerUp}
|
onPointerUp={handlePointerUp}
|
||||||
className="floating-wrapper"
|
className="floating-wrapper"
|
||||||
>
|
>
|
||||||
{zone.objects.map((obj, index) => (
|
{zone.objects.map((obj, index) => {
|
||||||
|
const topPosition =
|
||||||
|
typeof obj.position.top === "number"
|
||||||
|
? `calc(${obj.position.top}px + ${
|
||||||
|
isPlaying && selectedZone.activeSides.includes("top")
|
||||||
|
? `${heightMultiplier - 55}px`
|
||||||
|
: "0px"
|
||||||
|
})`
|
||||||
|
: "auto";
|
||||||
|
|
||||||
|
const leftPosition =
|
||||||
|
typeof obj.position.left === "number"
|
||||||
|
? `calc(${obj.position.left}px + ${
|
||||||
|
isPlaying && selectedZone.activeSides.includes("left")
|
||||||
|
? `${widthMultiplier - 100}px`
|
||||||
|
: "0px"
|
||||||
|
})`
|
||||||
|
: "auto";
|
||||||
|
|
||||||
|
const rightPosition =
|
||||||
|
typeof obj.position.right === "number"
|
||||||
|
? `calc(${obj.position.right}px + ${
|
||||||
|
isPlaying && selectedZone.activeSides.includes("right")
|
||||||
|
? `${widthMultiplier - 100}px`
|
||||||
|
: "0px"
|
||||||
|
})`
|
||||||
|
: "auto";
|
||||||
|
|
||||||
|
const bottomPosition =
|
||||||
|
typeof obj.position.bottom === "number"
|
||||||
|
? `calc(${obj.position.bottom}px + ${
|
||||||
|
isPlaying && selectedZone.activeSides.includes("bottom")
|
||||||
|
? `${heightMultiplier - 55}px`
|
||||||
|
: "0px"
|
||||||
|
})`
|
||||||
|
: "auto";
|
||||||
|
|
||||||
|
return (
|
||||||
<div
|
<div
|
||||||
key={`${zoneName}-${index}`}
|
key={`${zoneName}-${index}`}
|
||||||
className={`${obj.className} ${selectedChartId?.id === obj.id && "activeChart"}`}
|
className={`${obj.className} ${
|
||||||
|
selectedChartId?.id === obj.id && "activeChart"
|
||||||
|
}`}
|
||||||
ref={chartWidget}
|
ref={chartWidget}
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top:
|
top: topPosition,
|
||||||
typeof obj.position.top === "number"
|
left: leftPosition,
|
||||||
? `calc(${obj.position.top}px + ${isPlaying && selectedZone.activeSides.includes("top")
|
right: rightPosition,
|
||||||
? 90
|
bottom: bottomPosition,
|
||||||
: 0
|
|
||||||
}px)`
|
|
||||||
: "auto",
|
|
||||||
left:
|
|
||||||
typeof obj.position.left === "number"
|
|
||||||
? `calc(${obj.position.left}px + ${isPlaying && selectedZone.activeSides.includes("left")
|
|
||||||
? 90
|
|
||||||
: 0
|
|
||||||
}px)`
|
|
||||||
: "auto",
|
|
||||||
right:
|
|
||||||
typeof obj.position.right === "number"
|
|
||||||
? `calc(${obj.position.right}px + ${isPlaying && selectedZone.activeSides.includes("right")
|
|
||||||
? 90
|
|
||||||
: 0
|
|
||||||
}px)`
|
|
||||||
: "auto",
|
|
||||||
bottom:
|
|
||||||
typeof obj.position.bottom === "number"
|
|
||||||
? `calc(${obj.position.bottom}px + ${isPlaying && selectedZone.activeSides.includes("bottom")
|
|
||||||
? 90
|
|
||||||
: 0
|
|
||||||
}px)`
|
|
||||||
: "auto",
|
|
||||||
}}
|
}}
|
||||||
onPointerDown={(event) => {
|
onPointerDown={(event) => {
|
||||||
setSelectedChartId(obj);
|
setSelectedChartId(obj);
|
||||||
|
@ -551,18 +574,13 @@ const DroppedObjects: React.FC = () => {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{obj.className === "floating total-card" ? (
|
{obj.className === "floating total-card" ? (
|
||||||
<>
|
|
||||||
<TotalCardComponent object={obj} />
|
<TotalCardComponent object={obj} />
|
||||||
</>
|
|
||||||
) : obj.className === "warehouseThroughput floating" ? (
|
) : obj.className === "warehouseThroughput floating" ? (
|
||||||
<>
|
|
||||||
<WarehouseThroughputComponent object={obj} />
|
<WarehouseThroughputComponent object={obj} />
|
||||||
</>
|
|
||||||
) : obj.className === "fleetEfficiency floating" ? (
|
) : obj.className === "fleetEfficiency floating" ? (
|
||||||
<>
|
|
||||||
<FleetEfficiencyComponent object={obj} />
|
<FleetEfficiencyComponent object={obj} />
|
||||||
</>
|
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className="icon kebab"
|
className="icon kebab"
|
||||||
ref={kebabRef}
|
ref={kebabRef}
|
||||||
|
@ -573,6 +591,7 @@ const DroppedObjects: React.FC = () => {
|
||||||
>
|
>
|
||||||
<KebabIcon />
|
<KebabIcon />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{openKebabId === obj.id && (
|
{openKebabId === obj.id && (
|
||||||
<div className="kebab-options" ref={kebabRef}>
|
<div className="kebab-options" ref={kebabRef}>
|
||||||
<div
|
<div
|
||||||
|
@ -602,7 +621,8 @@ const DroppedObjects: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
{/* Render DistanceLines component during drag */}
|
{/* Render DistanceLines component during drag */}
|
||||||
{isPlaying === false &&
|
{isPlaying === false &&
|
||||||
|
|
|
@ -21,7 +21,6 @@ interface PanelProps {
|
||||||
zoneName: string;
|
zoneName: string;
|
||||||
activeSides: Side[];
|
activeSides: Side[];
|
||||||
panelOrder: Side[];
|
panelOrder: Side[];
|
||||||
|
|
||||||
lockedPanels: Side[];
|
lockedPanels: Side[];
|
||||||
zoneId: string;
|
zoneId: string;
|
||||||
zoneViewPortTarget: number[];
|
zoneViewPortTarget: number[];
|
||||||
|
@ -33,7 +32,6 @@ interface PanelProps {
|
||||||
zoneName: string;
|
zoneName: string;
|
||||||
activeSides: Side[];
|
activeSides: Side[];
|
||||||
panelOrder: Side[];
|
panelOrder: Side[];
|
||||||
|
|
||||||
lockedPanels: Side[];
|
lockedPanels: Side[];
|
||||||
zoneId: string;
|
zoneId: string;
|
||||||
zoneViewPortTarget: number[];
|
zoneViewPortTarget: number[];
|
||||||
|
@ -42,7 +40,7 @@ interface PanelProps {
|
||||||
}>
|
}>
|
||||||
>;
|
>;
|
||||||
hiddenPanels: string[];
|
hiddenPanels: string[];
|
||||||
setZonesData: React.Dispatch<React.SetStateAction<any>>; // Add this line
|
setZonesData: React.Dispatch<React.SetStateAction<any>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const generateUniqueId = () =>
|
const generateUniqueId = () =>
|
||||||
|
@ -60,14 +58,13 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
[side in Side]?: { width: number; height: number };
|
[side in Side]?: { width: number; height: number };
|
||||||
}>({});
|
}>({});
|
||||||
const [openKebabId, setOpenKebabId] = useState<string | null>(null);
|
const [openKebabId, setOpenKebabId] = useState<string | null>(null);
|
||||||
|
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
const { visualizationSocket } = useSocketStore();
|
const { visualizationSocket } = useSocketStore();
|
||||||
|
|
||||||
const [canvasDimensions, setCanvasDimensions] = useState({
|
const [canvasDimensions, setCanvasDimensions] = useState({
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Track canvas dimensions
|
// Track canvas dimensions
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const canvas = document.getElementById("real-time-vis-canvas");
|
const canvas = document.getElementById("real-time-vis-canvas");
|
||||||
|
@ -81,42 +78,20 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initial measurement
|
|
||||||
updateCanvasDimensions();
|
updateCanvasDimensions();
|
||||||
|
|
||||||
// Set up ResizeObserver to track changes
|
|
||||||
const resizeObserver = new ResizeObserver(updateCanvasDimensions);
|
const resizeObserver = new ResizeObserver(updateCanvasDimensions);
|
||||||
resizeObserver.observe(canvas);
|
resizeObserver.observe(canvas);
|
||||||
|
|
||||||
return () => {
|
return () => resizeObserver.unobserve(canvas);
|
||||||
resizeObserver.unobserve(canvas);
|
|
||||||
};
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
// Calculate panel size
|
||||||
const canvas = document.getElementById("real-time-vis-canvas");
|
const panelSize = Math.max(
|
||||||
if (!canvas) return;
|
Math.min(canvasDimensions.width * 0.25, canvasDimensions.height * 0.25),
|
||||||
|
170 // Min 170px
|
||||||
const updateCanvasDimensions = () => {
|
);
|
||||||
const rect = canvas.getBoundingClientRect();
|
|
||||||
setCanvasDimensions({
|
|
||||||
width: rect.width,
|
|
||||||
height: rect.height,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initial measurement
|
|
||||||
updateCanvasDimensions();
|
|
||||||
|
|
||||||
// Set up ResizeObserver to track changes
|
|
||||||
const resizeObserver = new ResizeObserver(updateCanvasDimensions);
|
|
||||||
resizeObserver.observe(canvas);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
resizeObserver.unobserve(canvas);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
|
// Define getPanelStyle
|
||||||
const getPanelStyle = useMemo(
|
const getPanelStyle = useMemo(
|
||||||
() => (side: Side) => {
|
() => (side: Side) => {
|
||||||
const currentIndex = selectedZone.panelOrder.indexOf(side);
|
const currentIndex = selectedZone.panelOrder.indexOf(side);
|
||||||
|
@ -126,125 +101,105 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
const topActive = previousPanels.includes("top");
|
const topActive = previousPanels.includes("top");
|
||||||
const bottomActive = previousPanels.includes("bottom");
|
const bottomActive = previousPanels.includes("bottom");
|
||||||
|
|
||||||
// Dynamic panel sizes based on canvas width
|
|
||||||
const panelSizeWidth = Math.max(canvasDimensions.width * 0.165, 200); // Ensure minimum width of 200px
|
|
||||||
const panelSizeHeight = Math.max(canvasDimensions.width * 0.13, 200); // Ensure minimum height of 200px
|
|
||||||
|
|
||||||
switch (side) {
|
switch (side) {
|
||||||
case "top":
|
case "top":
|
||||||
case "bottom":
|
case "bottom":
|
||||||
return {
|
return {
|
||||||
// minWidth: "200px", // Minimum width constraint
|
minWidth: "170px",
|
||||||
width: `calc(100% - ${
|
width: `calc(100% - ${
|
||||||
(leftActive ? panelSizeWidth : 0) +
|
(leftActive ? panelSize : 0) + (rightActive ? panelSize : 0)
|
||||||
(rightActive ? panelSizeWidth : 0)
|
|
||||||
}px)`,
|
}px)`,
|
||||||
minHeight: "150px", // Minimum height constraint
|
minHeight: "170px",
|
||||||
height: `${panelSizeHeight - 2}px`, // Subtracting for border or margin
|
height: `${panelSize}px`,
|
||||||
left: leftActive ? `${panelSizeWidth}px` : "0",
|
left: leftActive ? `${panelSize}px` : "0",
|
||||||
right: rightActive ? `${panelSizeWidth}px` : "0",
|
right: rightActive ? `${panelSize}px` : "0",
|
||||||
[side]: "0",
|
[side]: "0",
|
||||||
};
|
};
|
||||||
|
|
||||||
case "left":
|
case "left":
|
||||||
case "right":
|
case "right":
|
||||||
return {
|
return {
|
||||||
minWidth: "150px", // Minimum width constraint
|
minWidth: "170px",
|
||||||
width: `${panelSizeWidth - 2}px`, // Subtracting for border or margin
|
width: `${panelSize}px`,
|
||||||
// minHeight: "200px", // Minimum height constraint
|
minHeight: "170px",
|
||||||
height: `calc(100% - ${
|
height: `calc(100% - ${
|
||||||
(topActive ? panelSizeHeight : 0) +
|
(topActive ? panelSize : 0) + (bottomActive ? panelSize : 0)
|
||||||
(bottomActive ? panelSizeHeight : 0)
|
|
||||||
}px)`,
|
}px)`,
|
||||||
top: topActive ? `${panelSizeHeight}px` : "0",
|
top: topActive ? `${panelSize}px` : "0",
|
||||||
bottom: bottomActive ? `${panelSizeHeight}px` : "0",
|
bottom: bottomActive ? `${panelSize}px` : "0",
|
||||||
[side]: "0",
|
[side]: "0",
|
||||||
};
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[
|
[selectedZone.panelOrder, panelSize]
|
||||||
selectedZone.panelOrder,
|
|
||||||
isPlaying,
|
|
||||||
canvasDimensions.width,
|
|
||||||
canvasDimensions.height,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Handle drop event
|
||||||
const handleDrop = (e: React.DragEvent, panel: Side) => {
|
const handleDrop = (e: React.DragEvent, panel: Side) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const { draggedAsset } = useWidgetStore.getState();
|
const { draggedAsset } = useWidgetStore.getState();
|
||||||
if (!draggedAsset) return;
|
if (!draggedAsset || isPanelLocked(panel)) return;
|
||||||
if (isPanelLocked(panel)) return;
|
|
||||||
|
|
||||||
const currentWidgetsCount = getCurrentWidgetCount(panel);
|
const currentWidgetsCount = getCurrentWidgetCount(panel);
|
||||||
const maxCapacity = calculatePanelCapacity(panel);
|
const maxCapacity = calculatePanelCapacity(panel);
|
||||||
|
|
||||||
if (currentWidgetsCount >= maxCapacity) return;
|
if (currentWidgetsCount < maxCapacity) {
|
||||||
addWidgetToPanel(draggedAsset, panel);
|
addWidgetToPanel(draggedAsset, panel);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Check if panel is locked
|
||||||
const isPanelLocked = (panel: Side) =>
|
const isPanelLocked = (panel: Side) =>
|
||||||
selectedZone.lockedPanels.includes(panel);
|
selectedZone.lockedPanels.includes(panel);
|
||||||
|
|
||||||
|
// Get current widget count in a panel
|
||||||
const getCurrentWidgetCount = (panel: Side) =>
|
const getCurrentWidgetCount = (panel: Side) =>
|
||||||
selectedZone.widgets.filter((w) => w.panel === panel).length;
|
selectedZone.widgets.filter((w) => w.panel === panel).length;
|
||||||
|
|
||||||
|
// Calculate panel capacity
|
||||||
const calculatePanelCapacity = (panel: Side) => {
|
const calculatePanelCapacity = (panel: Side) => {
|
||||||
const CHART_WIDTH = 170;
|
const CHART_WIDTH = panelSize;
|
||||||
const CHART_HEIGHT = 170;
|
const CHART_HEIGHT = panelSize;
|
||||||
const FALLBACK_HORIZONTAL_CAPACITY = 5;
|
|
||||||
const FALLBACK_VERTICAL_CAPACITY = 3;
|
|
||||||
|
|
||||||
const dimensions = panelDimensions[panel];
|
const dimensions = panelDimensions[panel];
|
||||||
if (!dimensions) {
|
if (!dimensions) {
|
||||||
return panel === "top" || panel === "bottom"
|
return panel === "top" || panel === "bottom" ? 5 : 3; // Fallback capacities
|
||||||
? FALLBACK_HORIZONTAL_CAPACITY
|
|
||||||
: FALLBACK_VERTICAL_CAPACITY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return panel === "top" || panel === "bottom"
|
return panel === "top" || panel === "bottom"
|
||||||
? Math.floor(dimensions.width / CHART_WIDTH)
|
? Math.max(1, Math.floor(dimensions.width / CHART_WIDTH))
|
||||||
: Math.floor(dimensions.height / CHART_HEIGHT);
|
: Math.max(1, Math.floor(dimensions.height / CHART_HEIGHT));
|
||||||
};
|
};
|
||||||
|
|
||||||
// while dublicate check this and add
|
// Add widget to panel
|
||||||
const addWidgetToPanel = async (asset: any, panel: Side) => {
|
const addWidgetToPanel = async (asset: any, panel: Side) => {
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0];
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
|
|
||||||
const newWidget = {
|
const newWidget = {
|
||||||
...asset,
|
...asset,
|
||||||
id: generateUniqueId(),
|
id: generateUniqueId(),
|
||||||
panel,
|
panel,
|
||||||
};
|
};
|
||||||
|
|
||||||
let addWidget = {
|
let addWidget = {
|
||||||
organization: organization,
|
organization: organization,
|
||||||
zoneId: selectedZone.zoneId,
|
zoneId: selectedZone.zoneId,
|
||||||
widget: newWidget,
|
widget: newWidget,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (visualizationSocket) {
|
if (visualizationSocket) {
|
||||||
visualizationSocket.emit("v2:viz-widget:add", addWidget);
|
visualizationSocket.emit("v2:viz-widget:add", addWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSelectedZone((prev) => ({
|
setSelectedZone((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
widgets: [...prev.widgets, newWidget],
|
widgets: [...prev.widgets, newWidget],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
try {
|
|
||||||
// let response = await addingWidgets(selectedZone.zoneId, organization, newWidget);
|
|
||||||
// if (response.message === "Widget created successfully") {
|
|
||||||
// setSelectedZone((prev) => ({
|
|
||||||
// ...prev,
|
|
||||||
// widgets: [...prev.widgets, newWidget],
|
|
||||||
// }));
|
|
||||||
// }
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error adding widget:", error);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Observe panel dimensions
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const observers: ResizeObserver[] = [];
|
const observers: ResizeObserver[] = [];
|
||||||
const currentPanelRefs = panelRefs.current;
|
const currentPanelRefs = panelRefs.current;
|
||||||
|
@ -261,6 +216,7 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
observer.observe(element);
|
observer.observe(element);
|
||||||
observers.push(observer);
|
observers.push(observer);
|
||||||
}
|
}
|
||||||
|
@ -271,22 +227,15 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
};
|
};
|
||||||
}, [selectedZone.activeSides]);
|
}, [selectedZone.activeSides]);
|
||||||
|
|
||||||
|
// Handle widget reordering
|
||||||
const handleReorder = (fromIndex: number, toIndex: number, panel: Side) => {
|
const handleReorder = (fromIndex: number, toIndex: number, panel: Side) => {
|
||||||
if (!selectedZone) return; // Ensure selectedZone is not null
|
|
||||||
|
|
||||||
setSelectedZone((prev) => {
|
setSelectedZone((prev) => {
|
||||||
if (!prev) return prev; // Ensure prev is not null
|
|
||||||
|
|
||||||
// Filter widgets for the specified panel
|
|
||||||
const widgetsInPanel = prev.widgets.filter((w) => w.panel === panel);
|
const widgetsInPanel = prev.widgets.filter((w) => w.panel === panel);
|
||||||
|
|
||||||
// Reorder widgets within the same panel
|
|
||||||
const reorderedWidgets = arrayMove(widgetsInPanel, fromIndex, toIndex);
|
const reorderedWidgets = arrayMove(widgetsInPanel, fromIndex, toIndex);
|
||||||
|
|
||||||
// Merge the reordered widgets back into the full list while preserving the order
|
|
||||||
const updatedWidgets = prev.widgets
|
const updatedWidgets = prev.widgets
|
||||||
.filter((widget) => widget.panel !== panel) // Keep widgets from other panels
|
.filter((widget) => widget.panel !== panel)
|
||||||
.concat(reorderedWidgets); // Add the reordered widgets for the specified panel
|
.concat(reorderedWidgets);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
|
@ -295,12 +244,40 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Calculate capacities and dimensions
|
||||||
|
const topWidth = getPanelStyle("top").width;
|
||||||
|
const bottomWidth = getPanelStyle("bottom").width;
|
||||||
|
const leftHeight = getPanelStyle("left").height;
|
||||||
|
const rightHeight = getPanelStyle("right").height;
|
||||||
|
|
||||||
|
const topCapacity = calculatePanelCapacity("top");
|
||||||
|
const bottomCapacity = calculatePanelCapacity("bottom");
|
||||||
|
const leftCapacity = calculatePanelCapacity("left");
|
||||||
|
const rightCapacity = calculatePanelCapacity("right");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<style>
|
||||||
|
{`
|
||||||
|
:root {
|
||||||
|
--topWidth: ${topWidth};
|
||||||
|
--bottomWidth: ${bottomWidth};
|
||||||
|
--leftHeight: ${leftHeight};
|
||||||
|
--rightHeight: ${rightHeight};
|
||||||
|
|
||||||
|
--topCapacity: ${topCapacity};
|
||||||
|
--bottomCapacity: ${bottomCapacity};
|
||||||
|
--leftCapacity: ${leftCapacity};
|
||||||
|
--rightCapacity: ${rightCapacity};
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
</style>
|
||||||
|
|
||||||
{selectedZone.activeSides.map((side) => (
|
{selectedZone.activeSides.map((side) => (
|
||||||
<div
|
<div
|
||||||
key={side}
|
key={side}
|
||||||
className={`panel ${side}-panel absolute ${isPlaying ? "" : ""} ${
|
id="panel-wrapper"
|
||||||
|
className={`panel ${side}-panel absolute ${
|
||||||
hiddenPanels.includes(side) ? "hidePanel" : ""
|
hiddenPanels.includes(side) ? "hidePanel" : ""
|
||||||
}`}
|
}`}
|
||||||
style={getPanelStyle(side)}
|
style={getPanelStyle(side)}
|
||||||
|
@ -348,5 +325,3 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Panel;
|
export default Panel;
|
||||||
|
|
||||||
// canvasDimensions.width as percent
|
|
||||||
|
|
|
@ -67,9 +67,7 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
const { rightClickSelected, setRightClickSelected } = useRightClickSelected();
|
const { rightClickSelected, setRightClickSelected } = useRightClickSelected();
|
||||||
const [openConfirmationPopup, setOpenConfirmationPopup] = useState(false);
|
const [openConfirmationPopup, setOpenConfirmationPopup] = useState(false);
|
||||||
|
|
||||||
const [floatingWidgets, setFloatingWidgets] = useState<
|
const [floatingWidgets, setFloatingWidgets] = useState<Record<string, { zoneName: string; zoneId: string; objects: any[] }>>({});
|
||||||
Record<string, { zoneName: string; zoneId: string; objects: any[] }>
|
|
||||||
>({});
|
|
||||||
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
|
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
|
||||||
const { widgetSubOption, setWidgetSubOption } = useWidgetSubOption();
|
const { widgetSubOption, setWidgetSubOption } = useWidgetSubOption();
|
||||||
const { visualizationSocket } = useSocketStore();
|
const { visualizationSocket } = useSocketStore();
|
||||||
|
@ -81,7 +79,6 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
const organization = email?.split("@")[1]?.split(".")[0];
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
try {
|
try {
|
||||||
const response = await getZone2dData(organization);
|
const response = await getZone2dData(organization);
|
||||||
// console.log('response: ', response);
|
|
||||||
|
|
||||||
if (!Array.isArray(response)) {
|
if (!Array.isArray(response)) {
|
||||||
return;
|
return;
|
||||||
|
@ -102,7 +99,7 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
setZonesData(formattedData);
|
setZonesData(formattedData);
|
||||||
} catch (error) {}
|
} catch (error) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
GetZoneData();
|
GetZoneData();
|
||||||
|
@ -200,7 +197,7 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
} catch (error) {}
|
} catch (error) { }
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleClickOutside = (event: MouseEvent) => {
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
|
@ -267,7 +264,7 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
/>
|
/>
|
||||||
</RenderOverlay>
|
</RenderOverlay>
|
||||||
)}
|
)}
|
||||||
{/* <div
|
<div
|
||||||
className="scene-container"
|
className="scene-container"
|
||||||
style={{
|
style={{
|
||||||
height: "100%",
|
height: "100%",
|
||||||
|
@ -279,7 +276,7 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
onDragOver={(event) => event.preventDefault()}
|
onDragOver={(event) => event.preventDefault()}
|
||||||
>
|
>
|
||||||
<Scene />
|
<Scene />
|
||||||
</div> */}
|
</div>
|
||||||
{activeModule === "visualization" && selectedZone.zoneName !== "" && (
|
{activeModule === "visualization" && selectedZone.zoneName !== "" && (
|
||||||
<DroppedObjects />
|
<DroppedObjects />
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -47,80 +47,83 @@ const DropDownList: React.FC<DropDownListProps> = ({
|
||||||
const [zoneDataList, setZoneDataList] = useState<
|
const [zoneDataList, setZoneDataList] = useState<
|
||||||
{ id: string; name: string; assets: Asset[] }[]
|
{ id: string; name: string; assets: Asset[] }[]
|
||||||
>([]);
|
>([]);
|
||||||
|
const [zonePoints3D, setZonePoints3D] = useState<[]>([]);
|
||||||
|
|
||||||
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// console.log(zones);
|
// const value = (zones || []).map(
|
||||||
// setZoneDataList([
|
// (val: { zoneId: string; zoneName: string }) => ({
|
||||||
// { id: "2e996073-546c-470c-8323-55bd3700c6aa", name: "zone1" },
|
// id: val.zoneId,
|
||||||
// { id: "3f473bf0-197c-471c-a71f-943fc9ca2b47", name: "zone2" },
|
// name: val.zoneName,
|
||||||
// { id: "905e8fb6-9e18-469b-9474-e0478fb9601b", name: "zone3" },
|
// })
|
||||||
// { id: "9d9efcbe-8e96-47eb-bfad-128a9e4c532e", name: "zone4" },
|
// );
|
||||||
// { id: "884f3d29-eb5a-49a5-abe9-d11971c08e85", name: "zone5" },
|
// console.log('zones: ', zones);
|
||||||
// { id: "70fa55cd-b5c9-4f80-a8c4-6319af3bfb4e", name: "zone6" },
|
const value = (zones || []).map((val: { zoneId: string; zoneName: string }) => ({
|
||||||
// ])
|
|
||||||
|
|
||||||
const value = (zones || []).map(
|
|
||||||
(val: { zoneId: string; zoneName: string }) => ({
|
|
||||||
id: val.zoneId,
|
id: val.zoneId,
|
||||||
name: val.zoneName,
|
name: val.zoneName
|
||||||
})
|
}));
|
||||||
);
|
setZoneDataList(prev => (JSON.stringify(prev) !== JSON.stringify(value) ? value : prev));
|
||||||
setZoneDataList([
|
const allPoints = zones.flatMap((zone: any) => zone.points);
|
||||||
{
|
setZonePoints3D(allPoints);
|
||||||
id: "zone1",
|
// setZoneDataList([
|
||||||
name: "Zone 1",
|
// {
|
||||||
assets: [
|
// id: "zone1",
|
||||||
{
|
// name: "Zone 1",
|
||||||
id: "asset1",
|
// assets: [
|
||||||
name: "Asset 1",
|
// {
|
||||||
},
|
// id: "asset1",
|
||||||
{
|
// name: "Asset 1",
|
||||||
id: "asset2",
|
// },
|
||||||
name: "Asset 2",
|
// {
|
||||||
},
|
// id: "asset2",
|
||||||
{
|
// name: "Asset 2",
|
||||||
id: "asset3",
|
// },
|
||||||
name: "Asset 3",
|
// {
|
||||||
},
|
// id: "asset3",
|
||||||
],
|
// name: "Asset 3",
|
||||||
},
|
// },
|
||||||
{
|
// ],
|
||||||
id: "zone2",
|
// },
|
||||||
name: "Zone 2",
|
// {
|
||||||
assets: [
|
// id: "zone2",
|
||||||
{
|
// name: "Zone 2",
|
||||||
id: "asset4",
|
// assets: [
|
||||||
name: "Asset 4",
|
// {
|
||||||
},
|
// id: "asset4",
|
||||||
{
|
// name: "Asset 4",
|
||||||
id: "asset5",
|
// },
|
||||||
name: "Asset 5",
|
// {
|
||||||
},
|
// id: "asset5",
|
||||||
{
|
// name: "Asset 5",
|
||||||
id: "asset6",
|
// },
|
||||||
name: "Asset 6",
|
// {
|
||||||
},
|
// id: "asset6",
|
||||||
],
|
// name: "Asset 6",
|
||||||
},
|
// },
|
||||||
{
|
// ],
|
||||||
id: "zone3",
|
// },
|
||||||
name: "Zone 3",
|
// {
|
||||||
assets: [
|
// id: "zone3",
|
||||||
{
|
// name: "Zone 3",
|
||||||
id: "asset7",
|
// assets: [
|
||||||
name: "Asset 7",
|
// {
|
||||||
},
|
// id: "asset7",
|
||||||
{
|
// name: "Asset 7",
|
||||||
id: "asset8",
|
// },
|
||||||
name: "Asset 8",
|
// {
|
||||||
},
|
// id: "asset8",
|
||||||
],
|
// name: "Asset 8",
|
||||||
},
|
// },
|
||||||
]);
|
// ],
|
||||||
|
// },
|
||||||
|
// ]);
|
||||||
|
|
||||||
}, [zones]);
|
}, [zones]);
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
// console.log('zonePoints3D: ', zonePoints3D);
|
||||||
|
}, [zonePoints3D])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="dropdown-list-container">
|
<div className="dropdown-list-container">
|
||||||
|
|
|
@ -5,7 +5,7 @@ interface SimpleCardProps {
|
||||||
icon: React.ComponentType<React.SVGProps<SVGSVGElement>>; // React component for SVG icon
|
icon: React.ComponentType<React.SVGProps<SVGSVGElement>>; // React component for SVG icon
|
||||||
value: string;
|
value: string;
|
||||||
per: string; // Percentage change
|
per: string; // Percentage change
|
||||||
position?: [number, number]
|
position?: [number, number];
|
||||||
}
|
}
|
||||||
|
|
||||||
const SimpleCard: React.FC<SimpleCardProps> = ({
|
const SimpleCard: React.FC<SimpleCardProps> = ({
|
||||||
|
@ -15,7 +15,6 @@ const SimpleCard: React.FC<SimpleCardProps> = ({
|
||||||
per,
|
per,
|
||||||
position = [0, 0],
|
position = [0, 0],
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
const handleDragStart = (event: React.DragEvent<HTMLDivElement>) => {
|
const handleDragStart = (event: React.DragEvent<HTMLDivElement>) => {
|
||||||
const rect = event.currentTarget.getBoundingClientRect(); // Get position
|
const rect = event.currentTarget.getBoundingClientRect(); // Get position
|
||||||
const cardData = JSON.stringify({
|
const cardData = JSON.stringify({
|
||||||
|
|
|
@ -29,12 +29,15 @@ export default function PathNavigator({
|
||||||
const [dropPickupPath, setDropPickupPath] = useState<[number, number, number][]>([]);
|
const [dropPickupPath, setDropPickupPath] = useState<[number, number, number][]>([]);
|
||||||
const [initialPosition, setInitialPosition] = useState<THREE.Vector3 | null>(null);
|
const [initialPosition, setInitialPosition] = useState<THREE.Vector3 | null>(null);
|
||||||
const [initialRotation, setInitialRotation] = useState<THREE.Euler | null>(null);
|
const [initialRotation, setInitialRotation] = useState<THREE.Euler | null>(null);
|
||||||
|
const [targetPosition] = useState(new THREE.Vector3());
|
||||||
|
const [smoothPosition] = useState(new THREE.Vector3());
|
||||||
|
const [targetQuaternion] = useState(new THREE.Quaternion());
|
||||||
const distancesRef = useRef<number[]>([]);
|
const distancesRef = useRef<number[]>([]);
|
||||||
const totalDistanceRef = useRef(0);
|
const totalDistanceRef = useRef(0);
|
||||||
const progressRef = useRef(0);
|
const progressRef = useRef(0);
|
||||||
const isWaiting = useRef(false);
|
const isWaiting = useRef(false);
|
||||||
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||||
|
const pathTransitionProgress = useRef(0);
|
||||||
|
|
||||||
const { scene } = useThree();
|
const { scene } = useThree();
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
|
@ -44,6 +47,9 @@ export default function PathNavigator({
|
||||||
if (object) {
|
if (object) {
|
||||||
setInitialPosition(object.position.clone());
|
setInitialPosition(object.position.clone());
|
||||||
setInitialRotation(object.rotation.clone());
|
setInitialRotation(object.rotation.clone());
|
||||||
|
smoothPosition.copy(object.position.clone());
|
||||||
|
targetPosition.copy(object.position.clone());
|
||||||
|
targetQuaternion.setFromEuler(object.rotation.clone());
|
||||||
}
|
}
|
||||||
}, [scene, id]);
|
}, [scene, id]);
|
||||||
|
|
||||||
|
@ -65,22 +71,23 @@ export default function PathNavigator({
|
||||||
|
|
||||||
setPath([]);
|
setPath([]);
|
||||||
setCurrentPhase('initial');
|
setCurrentPhase('initial');
|
||||||
setPickupDropPath([]);
|
|
||||||
setDropPickupPath([]);
|
|
||||||
distancesRef.current = [];
|
distancesRef.current = [];
|
||||||
totalDistanceRef.current = 0;
|
totalDistanceRef.current = 0;
|
||||||
progressRef.current = 0;
|
progressRef.current = 0;
|
||||||
isWaiting.current = false;
|
isWaiting.current = false;
|
||||||
|
pathTransitionProgress.current = 0;
|
||||||
|
|
||||||
if (initialPosition && initialRotation) {
|
|
||||||
const object = scene.getObjectByProperty("uuid", id);
|
const object = scene.getObjectByProperty("uuid", id);
|
||||||
if (object) {
|
if (object && initialPosition && initialRotation) {
|
||||||
object.position.copy(initialPosition);
|
object.position.copy(initialPosition);
|
||||||
object.rotation.copy(initialRotation);
|
object.rotation.copy(initialRotation);
|
||||||
}
|
smoothPosition.copy(initialPosition);
|
||||||
|
targetPosition.copy(initialPosition);
|
||||||
|
targetQuaternion.setFromEuler(initialRotation);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isPlaying) {
|
if (!isPlaying) {
|
||||||
resetState();
|
resetState();
|
||||||
|
@ -171,16 +178,16 @@ export default function PathNavigator({
|
||||||
const end = new THREE.Vector3(...path[index + 1]);
|
const end = new THREE.Vector3(...path[index + 1]);
|
||||||
const dist = distancesRef.current[index];
|
const dist = distancesRef.current[index];
|
||||||
const t = THREE.MathUtils.clamp((covered - accumulated) / dist, 0, 1);
|
const t = THREE.MathUtils.clamp((covered - accumulated) / dist, 0, 1);
|
||||||
const position = start.clone().lerp(end, t);
|
|
||||||
|
|
||||||
object.position.copy(position);
|
targetPosition.copy(start).lerp(end, t);
|
||||||
|
|
||||||
|
smoothPosition.lerp(targetPosition, 0.1);
|
||||||
|
object.position.copy(smoothPosition);
|
||||||
|
|
||||||
const direction = new THREE.Vector3().subVectors(end, start).normalize();
|
const direction = new THREE.Vector3().subVectors(end, start).normalize();
|
||||||
const targetRotationY = Math.atan2(direction.x, direction.z);
|
const targetRotationY = Math.atan2(direction.x, direction.z);
|
||||||
|
targetQuaternion.setFromAxisAngle(new THREE.Vector3(0, 1, 0), targetRotationY);
|
||||||
let angleDifference = targetRotationY - object.rotation.y;
|
object.quaternion.slerp(targetQuaternion, 0.1);
|
||||||
angleDifference = ((angleDifference + Math.PI) % (Math.PI * 2)) - Math.PI;
|
|
||||||
object.rotation.y += angleDifference * 0.1;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -53,7 +53,7 @@ export default function addFloorToScene(
|
||||||
const mesh = new THREE.Mesh(geometry, material);
|
const mesh = new THREE.Mesh(geometry, material);
|
||||||
|
|
||||||
mesh.receiveShadow = true;
|
mesh.receiveShadow = true;
|
||||||
mesh.position.y = layer;
|
mesh.position.y = (layer) * CONSTANTS.wallConfig.height;
|
||||||
mesh.rotateX(Math.PI / 2);
|
mesh.rotateX(Math.PI / 2);
|
||||||
mesh.name = `Floor_Layer_${layer}`;
|
mesh.name = `Floor_Layer_${layer}`;
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@ function loadOnlyFloors(
|
||||||
mesh.castShadow = true;
|
mesh.castShadow = true;
|
||||||
mesh.receiveShadow = true;
|
mesh.receiveShadow = true;
|
||||||
|
|
||||||
mesh.position.y = (floor[0][0][2] - 1) * CONSTANTS.wallConfig.height + 0.03;
|
mesh.position.y = (floor[0][0][2] - 1) * CONSTANTS.wallConfig.height;
|
||||||
mesh.rotateX(Math.PI / 2);
|
mesh.rotateX(Math.PI / 2);
|
||||||
mesh.name = `Only_Floor_Line_${floor[0][0][2]}`;
|
mesh.name = `Only_Floor_Line_${floor[0][0][2]}`;
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,5 @@
|
||||||
import { useFrame, useThree } from "@react-three/fiber";
|
import { useFrame, useThree } from "@react-three/fiber";
|
||||||
import {
|
import { useActiveTool, useAsset3dWidget, useCamMode, useDeletableFloorItem, useDeleteModels, useFloorItems, useLoadingProgress, useRenderDistance, useselectedFloorItem, useSelectedItem, useSimulationStates, useSocketStore, useToggleView, useTransformMode, } from "../../../store/store";
|
||||||
useActiveTool,
|
|
||||||
useAsset3dWidget,
|
|
||||||
useCamMode,
|
|
||||||
useDeletableFloorItem,
|
|
||||||
useDeleteModels,
|
|
||||||
useFloorItems,
|
|
||||||
useLoadingProgress,
|
|
||||||
useRenderDistance,
|
|
||||||
useselectedFloorItem,
|
|
||||||
useSelectedItem,
|
|
||||||
useSimulationStates,
|
|
||||||
useSocketStore,
|
|
||||||
useToggleView,
|
|
||||||
useTransformMode,
|
|
||||||
} from "../../../store/store";
|
|
||||||
import assetVisibility from "../geomentries/assets/assetVisibility";
|
import assetVisibility from "../geomentries/assets/assetVisibility";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
|
@ -31,28 +16,10 @@ import addAssetModel from "../geomentries/assets/addAssetModel";
|
||||||
import { getFloorAssets } from "../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi";
|
import { getFloorAssets } from "../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi";
|
||||||
import useModuleStore from "../../../store/useModuleStore";
|
import useModuleStore from "../../../store/useModuleStore";
|
||||||
// import { retrieveGLTF } from "../../../utils/indexDB/idbUtils";
|
// import { retrieveGLTF } from "../../../utils/indexDB/idbUtils";
|
||||||
const assetManagerWorker = new Worker(
|
const assetManagerWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/assetManagerWorker.js", import.meta.url));
|
||||||
new URL(
|
const gltfLoaderWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js", import.meta.url));
|
||||||
"../../../services/factoryBuilder/webWorkers/assetManagerWorker.js",
|
|
||||||
import.meta.url
|
|
||||||
)
|
|
||||||
);
|
|
||||||
const gltfLoaderWorker = new Worker(
|
|
||||||
new URL(
|
|
||||||
"../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js",
|
|
||||||
import.meta.url
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const FloorItemsGroup = ({
|
const FloorItemsGroup = ({ itemsGroup, hoveredDeletableFloorItem, AttachedObject, floorGroup, tempLoader, isTempLoader, plane, }: any) => {
|
||||||
itemsGroup,
|
|
||||||
hoveredDeletableFloorItem,
|
|
||||||
AttachedObject,
|
|
||||||
floorGroup,
|
|
||||||
tempLoader,
|
|
||||||
isTempLoader,
|
|
||||||
plane,
|
|
||||||
}: any) => {
|
|
||||||
const state: Types.ThreeState = useThree();
|
const state: Types.ThreeState = useThree();
|
||||||
const { raycaster, controls }: any = state;
|
const { raycaster, controls }: any = state;
|
||||||
const { renderDistance } = useRenderDistance();
|
const { renderDistance } = useRenderDistance();
|
||||||
|
@ -72,9 +39,7 @@ const FloorItemsGroup = ({
|
||||||
const loader = new GLTFLoader();
|
const loader = new GLTFLoader();
|
||||||
const dracoLoader = new DRACOLoader();
|
const dracoLoader = new DRACOLoader();
|
||||||
|
|
||||||
dracoLoader.setDecoderPath(
|
dracoLoader.setDecoderPath("https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/");
|
||||||
"https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/"
|
|
||||||
);
|
|
||||||
loader.setDRACOLoader(dracoLoader);
|
loader.setDRACOLoader(dracoLoader);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -99,10 +64,7 @@ const FloorItemsGroup = ({
|
||||||
|
|
||||||
getFloorAssets(organization).then((data) => {
|
getFloorAssets(organization).then((data) => {
|
||||||
if (data.length > 0) {
|
if (data.length > 0) {
|
||||||
const uniqueItems = (data as Types.FloorItems).filter(
|
const uniqueItems = (data as Types.FloorItems).filter((item, index, self) => index === self.findIndex((t) => t.modelfileID === item.modelfileID));
|
||||||
(item, index, self) =>
|
|
||||||
index === self.findIndex((t) => t.modelfileID === item.modelfileID)
|
|
||||||
);
|
|
||||||
totalAssets = uniqueItems.length;
|
totalAssets = uniqueItems.length;
|
||||||
if (totalAssets === 0) {
|
if (totalAssets === 0) {
|
||||||
updateLoadingProgress(100);
|
updateLoadingProgress(100);
|
||||||
|
@ -149,17 +111,10 @@ const FloorItemsGroup = ({
|
||||||
if (toggleView) return;
|
if (toggleView) return;
|
||||||
|
|
||||||
const uuids: string[] = [];
|
const uuids: string[] = [];
|
||||||
itemsGroup.current?.children.forEach((child: any) => {
|
itemsGroup.current?.children.forEach((child: any) => { uuids.push(child.uuid); });
|
||||||
uuids.push(child.uuid);
|
|
||||||
});
|
|
||||||
const cameraPosition = state.camera.position;
|
const cameraPosition = state.camera.position;
|
||||||
|
|
||||||
assetManagerWorker.postMessage({
|
assetManagerWorker.postMessage({ floorItems, cameraPosition, uuids, renderDistance, });
|
||||||
floorItems,
|
|
||||||
cameraPosition,
|
|
||||||
uuids,
|
|
||||||
renderDistance,
|
|
||||||
});
|
|
||||||
}, [camMode, renderDistance]);
|
}, [camMode, renderDistance]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -173,17 +128,10 @@ const FloorItemsGroup = ({
|
||||||
if (toggleView) return;
|
if (toggleView) return;
|
||||||
|
|
||||||
const uuids: string[] = [];
|
const uuids: string[] = [];
|
||||||
itemsGroup.current?.children.forEach((child: any) => {
|
itemsGroup.current?.children.forEach((child: any) => { uuids.push(child.uuid); });
|
||||||
uuids.push(child.uuid);
|
|
||||||
});
|
|
||||||
const cameraPosition = camera.position;
|
const cameraPosition = camera.position;
|
||||||
|
|
||||||
assetManagerWorker.postMessage({
|
assetManagerWorker.postMessage({ floorItems, cameraPosition, uuids, renderDistance, });
|
||||||
floorItems,
|
|
||||||
cameraPosition,
|
|
||||||
uuids,
|
|
||||||
renderDistance,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const startInterval = () => {
|
const startInterval = () => {
|
||||||
|
@ -244,13 +192,7 @@ const FloorItemsGroup = ({
|
||||||
if (drag) return;
|
if (drag) return;
|
||||||
|
|
||||||
if (deleteModels) {
|
if (deleteModels) {
|
||||||
DeleteFloorItems(
|
DeleteFloorItems(itemsGroup, hoveredDeletableFloorItem, setFloorItems, setSimulationStates, socket);
|
||||||
itemsGroup,
|
|
||||||
hoveredDeletableFloorItem,
|
|
||||||
setFloorItems,
|
|
||||||
setSimulationStates,
|
|
||||||
socket
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
const Mode = transformMode;
|
const Mode = transformMode;
|
||||||
|
|
||||||
|
@ -260,12 +202,7 @@ const FloorItemsGroup = ({
|
||||||
itemsGroup.current.children,
|
itemsGroup.current.children,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
if (
|
if (intersects.length > 0 && intersects[0]?.object?.parent?.parent?.position && intersects[0]?.object?.parent?.parent?.scale && intersects[0]?.object?.parent?.parent?.rotation) {
|
||||||
intersects.length > 0 &&
|
|
||||||
intersects[0]?.object?.parent?.parent?.position &&
|
|
||||||
intersects[0]?.object?.parent?.parent?.scale &&
|
|
||||||
intersects[0]?.object?.parent?.parent?.rotation
|
|
||||||
) {
|
|
||||||
// let currentObject = intersects[0].object;
|
// let currentObject = intersects[0].object;
|
||||||
// while (currentObject) {
|
// while (currentObject) {
|
||||||
// if (currentObject.name === "Scene") {
|
// if (currentObject.name === "Scene") {
|
||||||
|
@ -295,16 +232,8 @@ const FloorItemsGroup = ({
|
||||||
|
|
||||||
if (Mode !== null || activeTool === "cursor") {
|
if (Mode !== null || activeTool === "cursor") {
|
||||||
if (!itemsGroup.current) return;
|
if (!itemsGroup.current) return;
|
||||||
let intersects = raycaster.intersectObjects(
|
let intersects = raycaster.intersectObjects(itemsGroup.current.children, true);
|
||||||
itemsGroup.current.children,
|
if (intersects.length > 0 && intersects[0]?.object?.parent?.parent?.position && intersects[0]?.object?.parent?.parent?.scale && intersects[0]?.object?.parent?.parent?.rotation) {
|
||||||
true
|
|
||||||
);
|
|
||||||
if (
|
|
||||||
intersects.length > 0 &&
|
|
||||||
intersects[0]?.object?.parent?.parent?.position &&
|
|
||||||
intersects[0]?.object?.parent?.parent?.scale &&
|
|
||||||
intersects[0]?.object?.parent?.parent?.rotation
|
|
||||||
) {
|
|
||||||
let currentObject = intersects[0].object;
|
let currentObject = intersects[0].object;
|
||||||
|
|
||||||
while (currentObject) {
|
while (currentObject) {
|
||||||
|
@ -317,9 +246,7 @@ const FloorItemsGroup = ({
|
||||||
AttachedObject.current = currentObject as any;
|
AttachedObject.current = currentObject as any;
|
||||||
// controls.fitToSphere(AttachedObject.current!, true);
|
// controls.fitToSphere(AttachedObject.current!, true);
|
||||||
|
|
||||||
const bbox = new THREE.Box3().setFromObject(
|
const bbox = new THREE.Box3().setFromObject(AttachedObject.current);
|
||||||
AttachedObject.current
|
|
||||||
);
|
|
||||||
const size = bbox.getSize(new THREE.Vector3());
|
const size = bbox.getSize(new THREE.Vector3());
|
||||||
const center = bbox.getCenter(new THREE.Vector3());
|
const center = bbox.getCenter(new THREE.Vector3());
|
||||||
|
|
||||||
|
@ -328,24 +255,11 @@ const FloorItemsGroup = ({
|
||||||
front.sub(AttachedObject.current.position).normalize();
|
front.sub(AttachedObject.current.position).normalize();
|
||||||
|
|
||||||
const distance = Math.max(size.x, size.y, size.z) * 2;
|
const distance = Math.max(size.x, size.y, size.z) * 2;
|
||||||
const newPosition = center
|
const newPosition = center.clone().addScaledVector(front, distance);
|
||||||
.clone()
|
|
||||||
.addScaledVector(front, distance);
|
|
||||||
|
|
||||||
controls.setPosition(
|
controls.setPosition(newPosition.x, newPosition.y, newPosition.z, true);
|
||||||
newPosition.x,
|
|
||||||
newPosition.y,
|
|
||||||
newPosition.z,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
controls.setTarget(center.x, center.y, center.z, true);
|
controls.setTarget(center.x, center.y, center.z, true);
|
||||||
controls.fitToBox(AttachedObject.current!, true, {
|
controls.fitToBox(AttachedObject.current!, true, { cover: true, paddingTop: 5, paddingLeft: 5, paddingBottom: 5, paddingRight: 5, });
|
||||||
cover: true,
|
|
||||||
paddingTop: 5,
|
|
||||||
paddingLeft: 5,
|
|
||||||
paddingBottom: 5,
|
|
||||||
paddingRight: 5,
|
|
||||||
});
|
|
||||||
|
|
||||||
setselectedFloorItem(AttachedObject.current!);
|
setselectedFloorItem(AttachedObject.current!);
|
||||||
}
|
}
|
||||||
|
@ -362,21 +276,7 @@ const FloorItemsGroup = ({
|
||||||
if (!event.dataTransfer?.files[0]) return;
|
if (!event.dataTransfer?.files[0]) return;
|
||||||
|
|
||||||
if (selectedItem.id !== "" && event.dataTransfer?.files[0]) {
|
if (selectedItem.id !== "" && event.dataTransfer?.files[0]) {
|
||||||
addAssetModel(
|
addAssetModel(raycaster, state.camera, state.pointer, floorGroup, setFloorItems, itemsGroup, isTempLoader, tempLoader, socket, selectedItem, setSelectedItem, setSimulationStates, plane);
|
||||||
raycaster,
|
|
||||||
state.camera,
|
|
||||||
state.pointer,
|
|
||||||
floorGroup,
|
|
||||||
setFloorItems,
|
|
||||||
itemsGroup,
|
|
||||||
isTempLoader,
|
|
||||||
tempLoader,
|
|
||||||
socket,
|
|
||||||
selectedItem,
|
|
||||||
setSelectedItem,
|
|
||||||
setSimulationStates,
|
|
||||||
plane
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -407,28 +307,13 @@ const FloorItemsGroup = ({
|
||||||
canvasElement.removeEventListener("drop", onDrop);
|
canvasElement.removeEventListener("drop", onDrop);
|
||||||
canvasElement.removeEventListener("dragover", onDragOver);
|
canvasElement.removeEventListener("dragover", onDragOver);
|
||||||
};
|
};
|
||||||
}, [
|
}, [deleteModels, transformMode, controls, selectedItem, state.camera, state.pointer, activeTool, activeModule,]);
|
||||||
deleteModels,
|
|
||||||
transformMode,
|
|
||||||
controls,
|
|
||||||
selectedItem,
|
|
||||||
state.camera,
|
|
||||||
state.pointer,
|
|
||||||
activeTool,
|
|
||||||
activeModule,
|
|
||||||
]);
|
|
||||||
|
|
||||||
|
|
||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
if (controls)
|
if (controls)
|
||||||
assetVisibility(itemsGroup, state.camera.position, renderDistance);
|
assetVisibility(itemsGroup, state.camera.position, renderDistance);
|
||||||
if (deleteModels) {
|
if (deleteModels && activeModule === "builder") {
|
||||||
DeletableHoveredFloorItems(
|
DeletableHoveredFloorItems(state, itemsGroup, hoveredDeletableFloorItem, setDeletableFloorItem);
|
||||||
state,
|
|
||||||
itemsGroup,
|
|
||||||
hoveredDeletableFloorItem,
|
|
||||||
setDeletableFloorItem
|
|
||||||
);
|
|
||||||
} else if (!deleteModels) {
|
} else if (!deleteModels) {
|
||||||
if (hoveredDeletableFloorItem.current) {
|
if (hoveredDeletableFloorItem.current) {
|
||||||
hoveredDeletableFloorItem.current = undefined;
|
hoveredDeletableFloorItem.current = undefined;
|
||||||
|
|
|
@ -9,9 +9,13 @@ import handleMeshMissed from "../eventFunctions/handleMeshMissed";
|
||||||
import DeleteWallItems from "../geomentries/walls/deleteWallItems";
|
import DeleteWallItems from "../geomentries/walls/deleteWallItems";
|
||||||
import loadInitialWallItems from "../../scene/IntialLoad/loadInitialWallItems";
|
import loadInitialWallItems from "../../scene/IntialLoad/loadInitialWallItems";
|
||||||
import AddWallItems from "../geomentries/walls/addWallItems";
|
import AddWallItems from "../geomentries/walls/addWallItems";
|
||||||
|
import useModuleStore from "../../../store/useModuleStore";
|
||||||
|
|
||||||
|
|
||||||
const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletableWallItem, selectedItemsIndex, setSelectedItemsIndex, CSGGroup }: any) => {
|
const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletableWallItem, selectedItemsIndex, setSelectedItemsIndex, CSGGroup }: any) => {
|
||||||
|
const state = useThree();
|
||||||
|
const { socket } = useSocketStore();
|
||||||
|
const { pointer, camera, raycaster } = state;
|
||||||
const { deleteModels, setDeleteModels } = useDeleteModels();
|
const { deleteModels, setDeleteModels } = useDeleteModels();
|
||||||
const { wallItems, setWallItems } = useWallItems();
|
const { wallItems, setWallItems } = useWallItems();
|
||||||
const { objectPosition, setObjectPosition } = useObjectPosition();
|
const { objectPosition, setObjectPosition } = useObjectPosition();
|
||||||
|
@ -19,10 +23,7 @@ const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletable
|
||||||
const { objectRotation, setObjectRotation } = useObjectRotation();
|
const { objectRotation, setObjectRotation } = useObjectRotation();
|
||||||
const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine();
|
const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine();
|
||||||
const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
|
const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
|
||||||
const { socket } = useSocketStore();
|
const { activeModule } = useModuleStore();
|
||||||
const state = useThree();
|
|
||||||
const { pointer, camera, raycaster } = state;
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Load Wall Items from the backend
|
// Load Wall Items from the backend
|
||||||
|
@ -209,7 +210,7 @@ const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletable
|
||||||
const onMouseUp = (evt: any) => {
|
const onMouseUp = (evt: any) => {
|
||||||
if (evt.button === 0) {
|
if (evt.button === 0) {
|
||||||
isLeftMouseDown = false;
|
isLeftMouseDown = false;
|
||||||
if (!drag && deleteModels) {
|
if (!drag && deleteModels && activeModule === "builder") {
|
||||||
DeleteWallItems(hoveredDeletableWallItem, setWallItems, wallItems, socket);
|
DeleteWallItems(hoveredDeletableWallItem, setWallItems, wallItems, socket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,7 +260,7 @@ const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletable
|
||||||
}, [deleteModels, wallItems])
|
}, [deleteModels, wallItems])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (deleteModels) {
|
if (deleteModels && activeModule === "builder") {
|
||||||
handleMeshMissed(currentWallItem, setSelectedWallItem, setSelectedItemsIndex);
|
handleMeshMissed(currentWallItem, setSelectedWallItem, setSelectedItemsIndex);
|
||||||
setSelectedWallItem(null);
|
setSelectedWallItem(null);
|
||||||
setSelectedItemsIndex(null);
|
setSelectedItemsIndex(null);
|
||||||
|
|
|
@ -192,7 +192,7 @@ function processLoadedModel(
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (item.eventData || item.modelfileID === '67e3db95c2e8f37134526fb2') {
|
if (item.eventData || item.modelfileID === '67e3db5ac2e8f37134526f40' || item.modelfileID === '67eb7904c2e8f37134527eae') {
|
||||||
processEventData(item, setSimulationStates);
|
processEventData(item, setSimulationStates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,10 +227,10 @@ function processEventData(item: Types.EventData, setSimulationStates: any) {
|
||||||
data as Types.VehicleEventsSchema
|
data as Types.VehicleEventsSchema
|
||||||
]);
|
]);
|
||||||
|
|
||||||
} else if (item.modelfileID === '67e3db95c2e8f37134526fb2') {
|
} else if (item.modelfileID === '67e3db5ac2e8f37134526f40') {
|
||||||
|
|
||||||
const pointUUID = THREE.MathUtils.generateUUID();
|
const pointUUID = THREE.MathUtils.generateUUID();
|
||||||
const pointPosition = new THREE.Vector3(0, 1.75, 0);
|
const pointPosition = new THREE.Vector3(0, 1.5, -0.5);
|
||||||
|
|
||||||
const staticMachine: Types.StaticMachineEventsSchema = {
|
const staticMachine: Types.StaticMachineEventsSchema = {
|
||||||
modeluuid: item.modeluuid,
|
modeluuid: item.modeluuid,
|
||||||
|
@ -243,13 +243,39 @@ function processEventData(item: Types.EventData, setSimulationStates: any) {
|
||||||
triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
|
triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
|
||||||
connections: { source: { modelUUID: item.modeluuid, pointUUID: pointUUID }, targets: [] },
|
connections: { source: { modelUUID: item.modeluuid, pointUUID: pointUUID }, targets: [] },
|
||||||
},
|
},
|
||||||
position: item.position
|
position: item.position,
|
||||||
|
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||||
};
|
};
|
||||||
|
|
||||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
|
||||||
...(prevEvents || []),
|
...(prevEvents || []),
|
||||||
staticMachine as Types.StaticMachineEventsSchema
|
staticMachine as Types.StaticMachineEventsSchema
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
} else if (item.modelfileID === '67eb7904c2e8f37134527eae') {
|
||||||
|
const pointUUID = THREE.MathUtils.generateUUID();
|
||||||
|
const pointPosition = new THREE.Vector3(0, 2.75, -0.5);
|
||||||
|
|
||||||
|
const armBot: Types.ArmBotEventsSchema = {
|
||||||
|
modeluuid: item.modeluuid,
|
||||||
|
modelName: item.modelname,
|
||||||
|
type: "ArmBot",
|
||||||
|
points: {
|
||||||
|
uuid: pointUUID,
|
||||||
|
position: [pointPosition.x, pointPosition.y, pointPosition.z],
|
||||||
|
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', speed: 1, processes: [] },
|
||||||
|
triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
|
||||||
|
connections: { source: { modelUUID: item.modeluuid, pointUUID: pointUUID }, targets: [] },
|
||||||
|
},
|
||||||
|
position: item.position,
|
||||||
|
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||||
|
}
|
||||||
|
|
||||||
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
|
||||||
|
...(prevEvents || []),
|
||||||
|
armBot as Types.ArmBotEventsSchema
|
||||||
|
]);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||||
return updatedItems;
|
return updatedItems;
|
||||||
});
|
});
|
||||||
|
|
||||||
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||||
|
|
||||||
const email = localStorage.getItem("email");
|
const email = localStorage.getItem("email");
|
||||||
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
||||||
|
@ -234,7 +234,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||||
newEventData.position = newFloorItem.position;
|
newEventData.position = newFloorItem.position;
|
||||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
|
|
||||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||||
...(prevEvents || []),
|
...(prevEvents || []),
|
||||||
newEventData as Types.ConveyorEventsSchema
|
newEventData as Types.ConveyorEventsSchema
|
||||||
]);
|
]);
|
||||||
|
@ -313,13 +313,44 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||||
newEventData.modelName = newFloorItem.modelname;
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
newEventData.position = newFloorItem.position;
|
newEventData.position = newFloorItem.position;
|
||||||
|
|
||||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||||
...(prevEvents || []),
|
...(prevEvents || []),
|
||||||
newEventData as Types.VehicleEventsSchema
|
newEventData as Types.VehicleEventsSchema
|
||||||
]);
|
]);
|
||||||
|
|
||||||
socket.emit("v2:model-asset:add", data);
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
//REST
|
||||||
|
|
||||||
|
// await setFloorItemApi(
|
||||||
|
// organization,
|
||||||
|
// obj.uuid,
|
||||||
|
// obj.userData.name,
|
||||||
|
// [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||||
|
// { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
|
||||||
|
// obj.userData.modelId,
|
||||||
|
// false,
|
||||||
|
// true,
|
||||||
|
// );
|
||||||
|
|
||||||
|
//SOCKET
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
organization,
|
||||||
|
modeluuid: newFloorItem.modeluuid,
|
||||||
|
modelname: newFloorItem.modelname,
|
||||||
|
modelfileID: newFloorItem.modelfileID,
|
||||||
|
position: newFloorItem.position,
|
||||||
|
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
|
||||||
|
isLocked: false,
|
||||||
|
isVisible: true,
|
||||||
|
socketId: socket.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||||
return updatedItems;
|
return updatedItems;
|
||||||
});
|
});
|
||||||
|
|
||||||
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||||
|
|
||||||
const email = localStorage.getItem("email");
|
const email = localStorage.getItem("email");
|
||||||
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
||||||
|
@ -216,7 +216,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||||
newEventData.position = newFloorItem.position;
|
newEventData.position = newFloorItem.position;
|
||||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
|
|
||||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||||
...(prevEvents || []),
|
...(prevEvents || []),
|
||||||
newEventData as Types.ConveyorEventsSchema
|
newEventData as Types.ConveyorEventsSchema
|
||||||
]);
|
]);
|
||||||
|
@ -295,13 +295,44 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||||
newEventData.modelName = newFloorItem.modelname;
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
newEventData.position = newFloorItem.position;
|
newEventData.position = newFloorItem.position;
|
||||||
|
|
||||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||||
...(prevEvents || []),
|
...(prevEvents || []),
|
||||||
newEventData as Types.VehicleEventsSchema
|
newEventData as Types.VehicleEventsSchema
|
||||||
]);
|
]);
|
||||||
|
|
||||||
socket.emit("v2:model-asset:add", data);
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
//REST
|
||||||
|
|
||||||
|
// await setFloorItemApi(
|
||||||
|
// organization,
|
||||||
|
// obj.uuid,
|
||||||
|
// obj.userData.name,
|
||||||
|
// [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||||
|
// { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
|
||||||
|
// obj.userData.modelId,
|
||||||
|
// false,
|
||||||
|
// true,
|
||||||
|
// );
|
||||||
|
|
||||||
|
//SOCKET
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
organization,
|
||||||
|
modeluuid: newFloorItem.modeluuid,
|
||||||
|
modelname: newFloorItem.modelname,
|
||||||
|
modelfileID: newFloorItem.modelfileID,
|
||||||
|
position: newFloorItem.position,
|
||||||
|
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
|
||||||
|
isLocked: false,
|
||||||
|
isVisible: true,
|
||||||
|
socketId: socket.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
|
@ -180,12 +180,12 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||||
return updatedItems;
|
return updatedItems;
|
||||||
});
|
});
|
||||||
|
|
||||||
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||||
|
|
||||||
const email = localStorage.getItem("email");
|
const email = localStorage.getItem("email");
|
||||||
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
||||||
|
|
||||||
if (eventData && eventData.type !== 'StaticMachine') {
|
if (eventData) {
|
||||||
if (eventData.type === 'Conveyor' && eventData) {
|
if (eventData.type === 'Conveyor' && eventData) {
|
||||||
|
|
||||||
const backendEventData = {
|
const backendEventData = {
|
||||||
|
@ -229,7 +229,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||||
newEventData.position = newFloorItem.position;
|
newEventData.position = newFloorItem.position;
|
||||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
|
|
||||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||||
const updatedEvents = (prevEvents || []).map(event =>
|
const updatedEvents = (prevEvents || []).map(event =>
|
||||||
event.modeluuid === newFloorItem.modeluuid
|
event.modeluuid === newFloorItem.modeluuid
|
||||||
? { ...event, ...newEventData }
|
? { ...event, ...newEventData }
|
||||||
|
@ -280,7 +280,113 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||||
newEventData.modelName = newFloorItem.modelname;
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
newEventData.position = newFloorItem.position;
|
newEventData.position = newFloorItem.position;
|
||||||
|
|
||||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||||
|
const updatedEvents = (prevEvents || []).map(event =>
|
||||||
|
event.modeluuid === newFloorItem.modeluuid
|
||||||
|
? { ...event, ...newEventData }
|
||||||
|
: event
|
||||||
|
);
|
||||||
|
return updatedEvents;
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
|
||||||
|
} else if (eventData.type === 'StaticMachine' && eventData) {
|
||||||
|
|
||||||
|
const backendEventData = {
|
||||||
|
type: 'StaticMachine',
|
||||||
|
points: eventData.points,
|
||||||
|
};
|
||||||
|
|
||||||
|
// REST
|
||||||
|
|
||||||
|
// await setFloorItemApi(
|
||||||
|
// organization,
|
||||||
|
// obj.uuid,
|
||||||
|
// obj.userData.name,
|
||||||
|
// obj.userData.modelId,
|
||||||
|
// [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||||
|
// { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
|
||||||
|
// false,
|
||||||
|
// true,
|
||||||
|
// { type: backendEventData.type, points: backendEventData.points }
|
||||||
|
// );
|
||||||
|
|
||||||
|
//SOCKET
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
organization,
|
||||||
|
modeluuid: newFloorItem.modeluuid,
|
||||||
|
modelname: newFloorItem.modelname,
|
||||||
|
modelfileID: newFloorItem.modelfileID,
|
||||||
|
position: newFloorItem.position,
|
||||||
|
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
|
||||||
|
isLocked: false,
|
||||||
|
isVisible: true,
|
||||||
|
// eventData: { type: backendEventData.type, points: backendEventData.points },
|
||||||
|
socketId: socket.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const newEventData: any = { type: backendEventData.type, points: backendEventData.points };
|
||||||
|
newEventData.modeluuid = newFloorItem.modeluuid;
|
||||||
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
|
newEventData.position = newFloorItem.position;
|
||||||
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
|
|
||||||
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||||
|
const updatedEvents = (prevEvents || []).map(event =>
|
||||||
|
event.modeluuid === newFloorItem.modeluuid
|
||||||
|
? { ...event, ...newEventData }
|
||||||
|
: event
|
||||||
|
);
|
||||||
|
return updatedEvents;
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
|
||||||
|
} else if (eventData.type === 'ArmBot' && eventData) {
|
||||||
|
|
||||||
|
const backendEventData = {
|
||||||
|
type: 'ArmBot',
|
||||||
|
points: eventData.points,
|
||||||
|
};
|
||||||
|
|
||||||
|
// REST
|
||||||
|
|
||||||
|
// await setFloorItemApi(
|
||||||
|
// organization,
|
||||||
|
// obj.uuid,
|
||||||
|
// obj.userData.name,
|
||||||
|
// obj.userData.modelId,
|
||||||
|
// [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||||
|
// { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
|
||||||
|
// false,
|
||||||
|
// true,
|
||||||
|
// { type: backendEventData.type, points: backendEventData.points }
|
||||||
|
// );
|
||||||
|
|
||||||
|
//SOCKET
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
organization,
|
||||||
|
modeluuid: newFloorItem.modeluuid,
|
||||||
|
modelname: newFloorItem.modelname,
|
||||||
|
modelfileID: newFloorItem.modelfileID,
|
||||||
|
position: newFloorItem.position,
|
||||||
|
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
|
||||||
|
isLocked: false,
|
||||||
|
isVisible: true,
|
||||||
|
// eventData: { type: backendEventData.type, points: backendEventData.points },
|
||||||
|
socketId: socket.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const newEventData: any = { type: backendEventData.type, points: backendEventData.points };
|
||||||
|
newEventData.modeluuid = newFloorItem.modeluuid;
|
||||||
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
|
newEventData.position = newFloorItem.position;
|
||||||
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
|
|
||||||
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||||
const updatedEvents = (prevEvents || []).map(event =>
|
const updatedEvents = (prevEvents || []).map(event =>
|
||||||
event.modeluuid === newFloorItem.modeluuid
|
event.modeluuid === newFloorItem.modeluuid
|
||||||
? { ...event, ...newEventData }
|
? { ...event, ...newEventData }
|
||||||
|
|
|
@ -184,13 +184,12 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||||
return updatedItems;
|
return updatedItems;
|
||||||
});
|
});
|
||||||
|
|
||||||
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
|
||||||
console.log('eventData: ', eventData);
|
|
||||||
|
|
||||||
const email = localStorage.getItem("email");
|
const email = localStorage.getItem("email");
|
||||||
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
||||||
|
|
||||||
if (eventData && eventData.type !== 'StaticMachine') {
|
if (eventData) {
|
||||||
if (eventData.type === 'Conveyor' && eventData) {
|
if (eventData.type === 'Conveyor' && eventData) {
|
||||||
|
|
||||||
const backendEventData = {
|
const backendEventData = {
|
||||||
|
@ -233,9 +232,8 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||||
newEventData.modelName = newFloorItem.modelname;
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
newEventData.position = newFloorItem.position;
|
newEventData.position = newFloorItem.position;
|
||||||
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
console.log('newEventData: ', newEventData);
|
|
||||||
|
|
||||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||||
const updatedEvents = (prevEvents || []).map(event =>
|
const updatedEvents = (prevEvents || []).map(event =>
|
||||||
event.modeluuid === newFloorItem.modeluuid
|
event.modeluuid === newFloorItem.modeluuid
|
||||||
? { ...event, ...newEventData }
|
? { ...event, ...newEventData }
|
||||||
|
@ -287,7 +285,113 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||||
newEventData.modelName = newFloorItem.modelname;
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
newEventData.position = newFloorItem.position;
|
newEventData.position = newFloorItem.position;
|
||||||
|
|
||||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||||
|
const updatedEvents = (prevEvents || []).map(event =>
|
||||||
|
event.modeluuid === newFloorItem.modeluuid
|
||||||
|
? { ...event, ...newEventData }
|
||||||
|
: event
|
||||||
|
);
|
||||||
|
return updatedEvents;
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
|
||||||
|
} else if (eventData.type === 'StaticMachine' && eventData) {
|
||||||
|
|
||||||
|
const backendEventData = {
|
||||||
|
type: 'StaticMachine',
|
||||||
|
points: eventData.points,
|
||||||
|
};
|
||||||
|
|
||||||
|
// REST
|
||||||
|
|
||||||
|
// await setFloorItemApi(
|
||||||
|
// organization,
|
||||||
|
// obj.uuid,
|
||||||
|
// obj.userData.name,
|
||||||
|
// obj.userData.modelId,
|
||||||
|
// [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||||
|
// { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
|
||||||
|
// false,
|
||||||
|
// true,
|
||||||
|
// { type: backendEventData.type, points: backendEventData.points }
|
||||||
|
// );
|
||||||
|
|
||||||
|
//SOCKET
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
organization,
|
||||||
|
modeluuid: newFloorItem.modeluuid,
|
||||||
|
modelname: newFloorItem.modelname,
|
||||||
|
modelfileID: newFloorItem.modelfileID,
|
||||||
|
position: newFloorItem.position,
|
||||||
|
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
|
||||||
|
isLocked: false,
|
||||||
|
isVisible: true,
|
||||||
|
// eventData: { type: backendEventData.type, points: backendEventData.points },
|
||||||
|
socketId: socket.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const newEventData: any = { type: backendEventData.type, points: backendEventData.points };
|
||||||
|
newEventData.modeluuid = newFloorItem.modeluuid;
|
||||||
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
|
newEventData.position = newFloorItem.position;
|
||||||
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
|
|
||||||
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||||
|
const updatedEvents = (prevEvents || []).map(event =>
|
||||||
|
event.modeluuid === newFloorItem.modeluuid
|
||||||
|
? { ...event, ...newEventData }
|
||||||
|
: event
|
||||||
|
);
|
||||||
|
return updatedEvents;
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.emit("v2:model-asset:add", data);
|
||||||
|
|
||||||
|
} else if (eventData.type === 'ArmBot' && eventData) {
|
||||||
|
|
||||||
|
const backendEventData = {
|
||||||
|
type: 'ArmBot',
|
||||||
|
points: eventData.points,
|
||||||
|
};
|
||||||
|
|
||||||
|
// REST
|
||||||
|
|
||||||
|
// await setFloorItemApi(
|
||||||
|
// organization,
|
||||||
|
// obj.uuid,
|
||||||
|
// obj.userData.name,
|
||||||
|
// obj.userData.modelId,
|
||||||
|
// [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||||
|
// { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
|
||||||
|
// false,
|
||||||
|
// true,
|
||||||
|
// { type: backendEventData.type, points: backendEventData.points }
|
||||||
|
// );
|
||||||
|
|
||||||
|
//SOCKET
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
organization,
|
||||||
|
modeluuid: newFloorItem.modeluuid,
|
||||||
|
modelname: newFloorItem.modelname,
|
||||||
|
modelfileID: newFloorItem.modelfileID,
|
||||||
|
position: newFloorItem.position,
|
||||||
|
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
|
||||||
|
isLocked: false,
|
||||||
|
isVisible: true,
|
||||||
|
// eventData: { type: backendEventData.type, points: backendEventData.points },
|
||||||
|
socketId: socket.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
const newEventData: any = { type: backendEventData.type, points: backendEventData.points };
|
||||||
|
newEventData.modeluuid = newFloorItem.modeluuid;
|
||||||
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
|
newEventData.position = newFloorItem.position;
|
||||||
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
|
|
||||||
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||||
const updatedEvents = (prevEvents || []).map(event =>
|
const updatedEvents = (prevEvents || []).map(event =>
|
||||||
event.modeluuid === newFloorItem.modeluuid
|
event.modeluuid === newFloorItem.modeluuid
|
||||||
? { ...event, ...newEventData }
|
? { ...event, ...newEventData }
|
||||||
|
|
|
@ -240,7 +240,7 @@ const SelectionControls: React.FC = () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||||
const updatedEvents = (prevEvents || []).filter(event => event.modeluuid !== selectedMesh.uuid);
|
const updatedEvents = (prevEvents || []).filter(event => event.modeluuid !== selectedMesh.uuid);
|
||||||
return updatedEvents;
|
return updatedEvents;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { useFrame, useThree } from '@react-three/fiber';
|
import { useFrame, useThree } from '@react-three/fiber';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import * as THREE from 'three';
|
import * as THREE from 'three';
|
||||||
import * as Types from '../../../types/world/worldTypes';
|
import * as Types from '../../../types/world/worldTypes';
|
||||||
import { QuadraticBezierLine } from '@react-three/drei';
|
import { QuadraticBezierLine } from '@react-three/drei';
|
||||||
import { useIsConnecting, useSimulationStates, useSocketStore } from '../../../store/store';
|
import { useIsConnecting, useRenderDistance, useSimulationStates, useSocketStore } from '../../../store/store';
|
||||||
import useModuleStore from '../../../store/useModuleStore';
|
import useModuleStore from '../../../store/useModuleStore';
|
||||||
import { usePlayButtonStore } from '../../../store/usePlayButtonStore';
|
import { usePlayButtonStore } from '../../../store/usePlayButtonStore';
|
||||||
import { setEventApi } from '../../../services/factoryBuilder/assest/floorAsset/setEventsApt';
|
import { setEventApi } from '../../../services/factoryBuilder/assest/floorAsset/setEventsApt';
|
||||||
|
@ -11,28 +11,21 @@ import { setEventApi } from '../../../services/factoryBuilder/assest/floorAsset/
|
||||||
function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject<THREE.Group> }) {
|
function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject<THREE.Group> }) {
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
const { gl, raycaster, scene, pointer, camera } = useThree();
|
const { gl, raycaster, scene, pointer, camera } = useThree();
|
||||||
|
const { renderDistance } = useRenderDistance();
|
||||||
const { setIsConnecting } = useIsConnecting();
|
const { setIsConnecting } = useIsConnecting();
|
||||||
const { simulationStates, setSimulationStates } = useSimulationStates();
|
const { simulationStates, setSimulationStates } = useSimulationStates();
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
const { socket } = useSocketStore();
|
const { socket } = useSocketStore();
|
||||||
|
const groupRefs = useRef<{ [key: string]: any }>({});
|
||||||
|
|
||||||
const [firstSelected, setFirstSelected] = useState<{
|
const [firstSelected, setFirstSelected] = useState<{ modelUUID: string; sphereUUID: string; position: THREE.Vector3; isCorner: boolean; } | null>(null);
|
||||||
modelUUID: string;
|
|
||||||
sphereUUID: string;
|
|
||||||
position: THREE.Vector3;
|
|
||||||
isCorner: boolean;
|
|
||||||
} | null>(null);
|
|
||||||
const [currentLine, setCurrentLine] = useState<{ start: THREE.Vector3, end: THREE.Vector3, mid: THREE.Vector3 } | null>(null);
|
const [currentLine, setCurrentLine] = useState<{ start: THREE.Vector3, end: THREE.Vector3, mid: THREE.Vector3 } | null>(null);
|
||||||
const [helperlineColor, setHelperLineColor] = useState<string>('red');
|
const [helperlineColor, setHelperLineColor] = useState<string>('red');
|
||||||
|
|
||||||
const updatePathConnections = (
|
const updatePathConnections = (fromModelUUID: string, fromPointUUID: string, toModelUUID: string, toPointUUID: string) => {
|
||||||
fromModelUUID: string,
|
|
||||||
fromPointUUID: string,
|
|
||||||
toModelUUID: string,
|
|
||||||
toPointUUID: string
|
|
||||||
) => {
|
|
||||||
const updatedPaths = simulationStates.map(path => {
|
const updatedPaths = simulationStates.map(path => {
|
||||||
if (path.type === 'Conveyor') {
|
if (path.type === 'Conveyor') {
|
||||||
|
// Handle outgoing connections from Conveyor
|
||||||
if (path.modeluuid === fromModelUUID) {
|
if (path.modeluuid === fromModelUUID) {
|
||||||
return {
|
return {
|
||||||
...path,
|
...path,
|
||||||
|
@ -61,6 +54,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// Handle incoming connections to Conveyor
|
||||||
else if (path.modeluuid === toModelUUID) {
|
else if (path.modeluuid === toModelUUID) {
|
||||||
return {
|
return {
|
||||||
...path,
|
...path,
|
||||||
|
@ -167,82 +161,170 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
// else if (path.type === 'StaticMachine') {
|
else if (path.type === 'StaticMachine') {
|
||||||
// if (path.modeluuid === fromModelUUID && path.points.uuid === fromPointUUID) {
|
// Handle outgoing connections from StaticMachine
|
||||||
// const newTarget = {
|
if (path.modeluuid === fromModelUUID && path.points.uuid === fromPointUUID) {
|
||||||
// modelUUID: toModelUUID,
|
const newTarget = {
|
||||||
// pointUUID: toPointUUID
|
modelUUID: toModelUUID,
|
||||||
// };
|
pointUUID: toPointUUID
|
||||||
// const existingTargets = path.points.connections.targets || [];
|
};
|
||||||
|
|
||||||
// // Check if target is an ArmBot
|
// Ensure target is an ArmBot
|
||||||
// const toPath = simulationStates.find(p => p.modeluuid === toModelUUID);
|
const toPath = simulationStates.find(p => p.modeluuid === toModelUUID);
|
||||||
// if (toPath?.type !== 'ArmBot') {
|
if (toPath?.type !== 'ArmBot') {
|
||||||
// console.log("StaticMachine can only connect to ArmBot");
|
console.log("StaticMachine can only connect to ArmBot");
|
||||||
// return path;
|
return path;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // Check if already has a connection
|
const existingTargets = path.points.connections.targets || [];
|
||||||
// if (existingTargets.length >= 1) {
|
|
||||||
// console.log("StaticMachine can have only one connection");
|
|
||||||
// return path;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (!existingTargets.some(target =>
|
// Allow only one connection
|
||||||
// target.modelUUID === newTarget.modelUUID &&
|
if (existingTargets.length >= 1) {
|
||||||
// target.pointUUID === newTarget.pointUUID
|
console.log("StaticMachine can only have one connection");
|
||||||
// )) {
|
return path;
|
||||||
// return {
|
}
|
||||||
// ...path,
|
|
||||||
// points: {
|
|
||||||
// ...path.points,
|
|
||||||
// connections: {
|
|
||||||
// ...path.points.connections,
|
|
||||||
// targets: [...existingTargets, newTarget]
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // Handle incoming connections to StaticMachine
|
|
||||||
// else if (path.modeluuid === toModelUUID && path.points.uuid === toPointUUID) {
|
|
||||||
// const reverseTarget = {
|
|
||||||
// modelUUID: fromModelUUID,
|
|
||||||
// pointUUID: fromPointUUID
|
|
||||||
// };
|
|
||||||
// const existingTargets = path.points.connections.targets || [];
|
|
||||||
|
|
||||||
// // Check if source is an ArmBot
|
if (!existingTargets.some(target =>
|
||||||
// const fromPath = simulationStates.find(p => p.modeluuid === fromModelUUID);
|
target.modelUUID === newTarget.modelUUID &&
|
||||||
// if (fromPath?.type !== 'ArmBot') {
|
target.pointUUID === newTarget.pointUUID
|
||||||
// console.log("StaticMachine can only connect to ArmBot");
|
)) {
|
||||||
// return path;
|
return {
|
||||||
// }
|
...path,
|
||||||
|
points: {
|
||||||
|
...path.points,
|
||||||
|
connections: {
|
||||||
|
...path.points.connections,
|
||||||
|
targets: [...existingTargets, newTarget]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// // Check if already has a connection
|
// Handle incoming connections to StaticMachine
|
||||||
// if (existingTargets.length >= 1) {
|
else if (path.modeluuid === toModelUUID && path.points.uuid === toPointUUID) {
|
||||||
// console.log("StaticMachine can have only one connection");
|
const reverseTarget = {
|
||||||
// return path;
|
modelUUID: fromModelUUID,
|
||||||
// }
|
pointUUID: fromPointUUID
|
||||||
|
};
|
||||||
|
|
||||||
|
const fromPath = simulationStates.find(p => p.modeluuid === fromModelUUID);
|
||||||
|
if (fromPath?.type !== 'ArmBot') {
|
||||||
|
console.log("StaticMachine can only be connected from ArmBot");
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
const existingTargets = path.points.connections.targets || [];
|
||||||
|
|
||||||
|
if (existingTargets.length >= 1) {
|
||||||
|
console.log("StaticMachine can only have one connection");
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!existingTargets.some(target =>
|
||||||
|
target.modelUUID === reverseTarget.modelUUID &&
|
||||||
|
target.pointUUID === reverseTarget.pointUUID
|
||||||
|
)) {
|
||||||
|
return {
|
||||||
|
...path,
|
||||||
|
points: {
|
||||||
|
...path.points,
|
||||||
|
connections: {
|
||||||
|
...path.points.connections,
|
||||||
|
targets: [...existingTargets, reverseTarget]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
else if (path.type === 'ArmBot') {
|
||||||
|
// Handle outgoing connections from ArmBot
|
||||||
|
if (path.modeluuid === fromModelUUID && path.points.uuid === fromPointUUID) {
|
||||||
|
const newTarget = {
|
||||||
|
modelUUID: toModelUUID,
|
||||||
|
pointUUID: toPointUUID
|
||||||
|
};
|
||||||
|
|
||||||
|
const toPath = simulationStates.find(p => p.modeluuid === toModelUUID);
|
||||||
|
if (!toPath) return path;
|
||||||
|
|
||||||
|
const existingTargets = path.points.connections.targets || [];
|
||||||
|
|
||||||
|
// Check if connecting to a StaticMachine and already connected to one
|
||||||
|
const alreadyConnectedToStatic = existingTargets.some(target => {
|
||||||
|
const targetPath = simulationStates.find(p => p.modeluuid === target.modelUUID);
|
||||||
|
return targetPath?.type === 'StaticMachine';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (toPath.type === 'StaticMachine') {
|
||||||
|
if (alreadyConnectedToStatic) {
|
||||||
|
console.log("ArmBot can only connect to one StaticMachine");
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!existingTargets.some(target =>
|
||||||
|
target.modelUUID === newTarget.modelUUID &&
|
||||||
|
target.pointUUID === newTarget.pointUUID
|
||||||
|
)) {
|
||||||
|
return {
|
||||||
|
...path,
|
||||||
|
points: {
|
||||||
|
...path.points,
|
||||||
|
connections: {
|
||||||
|
...path.points.connections,
|
||||||
|
targets: [...existingTargets, newTarget]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle incoming connections to ArmBot
|
||||||
|
else if (path.modeluuid === toModelUUID && path.points.uuid === toPointUUID) {
|
||||||
|
const reverseTarget = {
|
||||||
|
modelUUID: fromModelUUID,
|
||||||
|
pointUUID: fromPointUUID
|
||||||
|
};
|
||||||
|
|
||||||
|
const fromPath = simulationStates.find(p => p.modeluuid === fromModelUUID);
|
||||||
|
if (!fromPath) return path;
|
||||||
|
|
||||||
|
const existingTargets = path.points.connections.targets || [];
|
||||||
|
|
||||||
|
const alreadyConnectedFromStatic = existingTargets.some(target => {
|
||||||
|
const targetPath = simulationStates.find(p => p.modeluuid === target.modelUUID);
|
||||||
|
return targetPath?.type === 'StaticMachine';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (fromPath.type === 'StaticMachine') {
|
||||||
|
if (alreadyConnectedFromStatic) {
|
||||||
|
console.log("ArmBot can only be connected from one StaticMachine");
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!existingTargets.some(target =>
|
||||||
|
target.modelUUID === reverseTarget.modelUUID &&
|
||||||
|
target.pointUUID === reverseTarget.pointUUID
|
||||||
|
)) {
|
||||||
|
return {
|
||||||
|
...path,
|
||||||
|
points: {
|
||||||
|
...path.points,
|
||||||
|
connections: {
|
||||||
|
...path.points.connections,
|
||||||
|
targets: [...existingTargets, reverseTarget]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
// if (!existingTargets.some(target =>
|
|
||||||
// target.modelUUID === reverseTarget.modelUUID &&
|
|
||||||
// target.pointUUID === reverseTarget.pointUUID
|
|
||||||
// )) {
|
|
||||||
// return {
|
|
||||||
// ...path,
|
|
||||||
// points: {
|
|
||||||
// ...path.points,
|
|
||||||
// connections: {
|
|
||||||
// ...path.points.connections,
|
|
||||||
// targets: [...existingTargets, reverseTarget]
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return path;
|
|
||||||
// }
|
|
||||||
return path;
|
return path;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -252,10 +334,10 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
path.modeluuid === fromModelUUID || path.modeluuid === toModelUUID
|
path.modeluuid === fromModelUUID || path.modeluuid === toModelUUID
|
||||||
);
|
);
|
||||||
|
|
||||||
updateBackend(updatedPathDetails);
|
// updateBackend(updatedPathDetails);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateBackend = async (updatedPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
|
const updateBackend = async (updatedPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||||
if (updatedPaths.length === 0) return;
|
if (updatedPaths.length === 0) return;
|
||||||
const email = localStorage.getItem("email");
|
const email = localStorage.getItem("email");
|
||||||
const organization = email ? email.split("@")[1].split(".")[0] : "";
|
const organization = email ? email.split("@")[1].split(".")[0] : "";
|
||||||
|
@ -437,6 +519,69 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if StaticMachine is involved in the connection
|
||||||
|
if ((firstPath?.type === 'StaticMachine' && secondPath?.type !== 'ArmBot') ||
|
||||||
|
(secondPath?.type === 'StaticMachine' && firstPath?.type !== 'ArmBot')) {
|
||||||
|
console.log("StaticMachine can only connect to ArmBot");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if StaticMachine already has a connection
|
||||||
|
if (firstPath?.type === 'StaticMachine') {
|
||||||
|
const staticConnections = firstPath.points.connections.targets.length;
|
||||||
|
if (staticConnections >= 1) {
|
||||||
|
console.log("StaticMachine can only have one connection");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (secondPath?.type === 'StaticMachine') {
|
||||||
|
const staticConnections = secondPath.points.connections.targets.length;
|
||||||
|
if (staticConnections >= 1) {
|
||||||
|
console.log("StaticMachine can only have one connection");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if ArmBot is involved
|
||||||
|
if ((firstPath?.type === 'ArmBot' && secondPath?.type === 'StaticMachine') ||
|
||||||
|
(secondPath?.type === 'ArmBot' && firstPath?.type === 'StaticMachine')) {
|
||||||
|
|
||||||
|
const armBotPath = firstPath?.type === 'ArmBot' ? firstPath : secondPath;
|
||||||
|
const staticPath = firstPath?.type === 'StaticMachine' ? firstPath : secondPath;
|
||||||
|
|
||||||
|
const armBotConnections = armBotPath.points.connections.targets || [];
|
||||||
|
const alreadyConnectedToStatic = armBotConnections.some(target => {
|
||||||
|
const targetPath = simulationStates.find(p => p.modeluuid === target.modelUUID);
|
||||||
|
return targetPath?.type === 'StaticMachine';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (alreadyConnectedToStatic) {
|
||||||
|
console.log("ArmBot can only connect to one StaticMachine");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const staticConnections = staticPath.points.connections.targets.length;
|
||||||
|
if (staticConnections >= 1) {
|
||||||
|
console.log("StaticMachine can only have one connection");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent ArmBot ↔ ArmBot
|
||||||
|
if (firstPath?.type === 'ArmBot' && secondPath?.type === 'ArmBot') {
|
||||||
|
console.log("Cannot connect two ArmBots together");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If one is ArmBot, ensure the other is StaticMachine or Conveyor
|
||||||
|
if (firstPath?.type === 'ArmBot' || secondPath?.type === 'ArmBot') {
|
||||||
|
const otherType = firstPath?.type === 'ArmBot' ? secondPath?.type : firstPath?.type;
|
||||||
|
if (otherType !== 'StaticMachine' && otherType !== 'Conveyor') {
|
||||||
|
console.log("ArmBot can only connect to Conveyors or one StaticMachine");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// At least one must be start/end point
|
// At least one must be start/end point
|
||||||
if (!firstSelected.isCorner && !isStartOrEnd) {
|
if (!firstSelected.isCorner && !isStartOrEnd) {
|
||||||
console.log("At least one of the selected spheres must be a start or end point.");
|
console.log("At least one of the selected spheres must be a start or end point.");
|
||||||
|
@ -489,6 +634,15 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
};
|
};
|
||||||
}, [camera, scene, raycaster, firstSelected, simulationStates]);
|
}, [camera, scene, raycaster, firstSelected, simulationStates]);
|
||||||
|
|
||||||
|
useFrame(() => {
|
||||||
|
Object.values(groupRefs.current).forEach((group) => {
|
||||||
|
if (group) {
|
||||||
|
const distance = new THREE.Vector3(...group.position.toArray()).distanceTo(camera.position);
|
||||||
|
group.visible = ((distance <= renderDistance) && !isPlaying);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
if (firstSelected) {
|
if (firstSelected) {
|
||||||
raycaster.setFromCamera(pointer, camera);
|
raycaster.setFromCamera(pointer, camera);
|
||||||
|
@ -574,12 +728,50 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
(firstPath?.type === 'Vehicle' && secondPath?.type !== 'Conveyor') ||
|
(firstPath?.type === 'Vehicle' && secondPath?.type !== 'Conveyor') ||
|
||||||
(secondPath?.type === 'Vehicle' && firstPath?.type !== 'Conveyor');
|
(secondPath?.type === 'Vehicle' && firstPath?.type !== 'Conveyor');
|
||||||
|
|
||||||
|
// Check if StaticMachine is connecting to non-ArmBot
|
||||||
|
const isStaticMachineToNonArmBot =
|
||||||
|
(firstPath?.type === 'StaticMachine' && secondPath?.type !== 'ArmBot') ||
|
||||||
|
(secondPath?.type === 'StaticMachine' && firstPath?.type !== 'ArmBot');
|
||||||
|
|
||||||
|
// Check if StaticMachine already has a connection
|
||||||
|
const isStaticMachineAtMaxConnections =
|
||||||
|
(firstPath?.type === 'StaticMachine' && firstPath.points.connections.targets.length >= 1) ||
|
||||||
|
(secondPath?.type === 'StaticMachine' && secondPath.points.connections.targets.length >= 1);
|
||||||
|
|
||||||
|
// Check if ArmBot is connecting to StaticMachine
|
||||||
|
const isArmBotToStaticMachine =
|
||||||
|
(firstPath?.type === 'ArmBot' && secondPath?.type === 'StaticMachine') ||
|
||||||
|
(secondPath?.type === 'ArmBot' && firstPath?.type === 'StaticMachine');
|
||||||
|
|
||||||
|
// Prevent multiple StaticMachine connections to ArmBot
|
||||||
|
let isArmBotAlreadyConnectedToStatic = false;
|
||||||
|
if (isArmBotToStaticMachine) {
|
||||||
|
const armBotPath = firstPath?.type === 'ArmBot' ? firstPath : secondPath;
|
||||||
|
isArmBotAlreadyConnectedToStatic = armBotPath.points.connections.targets.some(target => {
|
||||||
|
const targetPath = simulationStates.find(p => p.modeluuid === target.modelUUID);
|
||||||
|
return targetPath?.type === 'StaticMachine';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent ArmBot to ArmBot
|
||||||
|
const isArmBotToArmBot = firstPath?.type === 'ArmBot' && secondPath?.type === 'ArmBot';
|
||||||
|
|
||||||
|
// If ArmBot is involved, other must be Conveyor or StaticMachine
|
||||||
|
const isArmBotToInvalidType = (firstPath?.type === 'ArmBot' || secondPath?.type === 'ArmBot') &&
|
||||||
|
!(firstPath?.type === 'Conveyor' || firstPath?.type === 'StaticMachine' ||
|
||||||
|
secondPath?.type === 'Conveyor' || secondPath?.type === 'StaticMachine');
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!isDuplicateConnection &&
|
!isDuplicateConnection &&
|
||||||
!isVehicleToVehicle &&
|
!isVehicleToVehicle &&
|
||||||
!isNonVehicleAlreadyConnected &&
|
!isNonVehicleAlreadyConnected &&
|
||||||
!isVehicleAtMaxConnections &&
|
!isVehicleAtMaxConnections &&
|
||||||
!isVehicleConnectingToNonConveyor &&
|
!isVehicleConnectingToNonConveyor &&
|
||||||
|
!isStaticMachineToNonArmBot &&
|
||||||
|
!isStaticMachineAtMaxConnections &&
|
||||||
|
!isArmBotToArmBot &&
|
||||||
|
!isArmBotToInvalidType &&
|
||||||
|
!isArmBotAlreadyConnectedToStatic &&
|
||||||
firstSelected.sphereUUID !== sphereUUID &&
|
firstSelected.sphereUUID !== sphereUUID &&
|
||||||
firstSelected.modelUUID !== modelUUID &&
|
firstSelected.modelUUID !== modelUUID &&
|
||||||
(firstSelected.isCorner || isConnectable) &&
|
(firstSelected.isCorner || isConnectable) &&
|
||||||
|
@ -596,6 +788,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
} else {
|
} else {
|
||||||
isInvalidConnection = true;
|
isInvalidConnection = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snappedSphere) {
|
if (snappedSphere) {
|
||||||
|
@ -633,7 +826,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<group name='simulationConnectionGroup' visible={!isPlaying} >
|
<group name='simulationConnectionGroup' visible={!isPlaying}>
|
||||||
{simulationStates.flatMap(path => {
|
{simulationStates.flatMap(path => {
|
||||||
if (path.type === 'Conveyor') {
|
if (path.type === 'Conveyor') {
|
||||||
return path.points.flatMap(point =>
|
return path.points.flatMap(point =>
|
||||||
|
@ -652,7 +845,6 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
|
|
||||||
const distance = fromWorldPosition.distanceTo(toWorldPosition);
|
const distance = fromWorldPosition.distanceTo(toWorldPosition);
|
||||||
const heightFactor = Math.max(0.5, distance * 0.2);
|
const heightFactor = Math.max(0.5, distance * 0.2);
|
||||||
|
|
||||||
const midPoint = new THREE.Vector3(
|
const midPoint = new THREE.Vector3(
|
||||||
(fromWorldPosition.x + toWorldPosition.x) / 2,
|
(fromWorldPosition.x + toWorldPosition.x) / 2,
|
||||||
Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor,
|
Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor,
|
||||||
|
@ -662,6 +854,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
return (
|
return (
|
||||||
<QuadraticBezierLine
|
<QuadraticBezierLine
|
||||||
key={`${point.uuid}-${target.pointUUID}-${index}`}
|
key={`${point.uuid}-${target.pointUUID}-${index}`}
|
||||||
|
ref={(el) => (groupRefs.current[`${point.uuid}-${target.pointUUID}-${index}`] = el!)}
|
||||||
start={fromWorldPosition.toArray()}
|
start={fromWorldPosition.toArray()}
|
||||||
end={toWorldPosition.toArray()}
|
end={toWorldPosition.toArray()}
|
||||||
mid={midPoint.toArray()}
|
mid={midPoint.toArray()}
|
||||||
|
@ -676,7 +869,9 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
return null;
|
return null;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else if (path.type === 'Vehicle') {
|
}
|
||||||
|
|
||||||
|
if (path.type === 'Vehicle') {
|
||||||
return path.points.connections.targets.map((target, index) => {
|
return path.points.connections.targets.map((target, index) => {
|
||||||
const fromSphere = pathsGroupRef.current?.getObjectByProperty('uuid', path.points.uuid);
|
const fromSphere = pathsGroupRef.current?.getObjectByProperty('uuid', path.points.uuid);
|
||||||
const toSphere = pathsGroupRef.current?.getObjectByProperty('uuid', target.pointUUID);
|
const toSphere = pathsGroupRef.current?.getObjectByProperty('uuid', target.pointUUID);
|
||||||
|
@ -689,7 +884,6 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
|
|
||||||
const distance = fromWorldPosition.distanceTo(toWorldPosition);
|
const distance = fromWorldPosition.distanceTo(toWorldPosition);
|
||||||
const heightFactor = Math.max(0.5, distance * 0.2);
|
const heightFactor = Math.max(0.5, distance * 0.2);
|
||||||
|
|
||||||
const midPoint = new THREE.Vector3(
|
const midPoint = new THREE.Vector3(
|
||||||
(fromWorldPosition.x + toWorldPosition.x) / 2,
|
(fromWorldPosition.x + toWorldPosition.x) / 2,
|
||||||
Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor,
|
Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor,
|
||||||
|
@ -699,6 +893,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
return (
|
return (
|
||||||
<QuadraticBezierLine
|
<QuadraticBezierLine
|
||||||
key={`${path.points.uuid}-${target.pointUUID}-${index}`}
|
key={`${path.points.uuid}-${target.pointUUID}-${index}`}
|
||||||
|
ref={(el) => (groupRefs.current[`${path.points.uuid}-${target.pointUUID}-${index}`] = el!)}
|
||||||
start={fromWorldPosition.toArray()}
|
start={fromWorldPosition.toArray()}
|
||||||
end={toWorldPosition.toArray()}
|
end={toWorldPosition.toArray()}
|
||||||
mid={midPoint.toArray()}
|
mid={midPoint.toArray()}
|
||||||
|
@ -713,6 +908,48 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (path.type === 'StaticMachine') {
|
||||||
|
return path.points.connections.targets.map((target, index) => {
|
||||||
|
const targetPath = simulationStates.find(p => p.modeluuid === target.modelUUID);
|
||||||
|
if (targetPath?.type !== 'ArmBot') return null;
|
||||||
|
|
||||||
|
const fromSphere = pathsGroupRef.current?.getObjectByProperty('uuid', path.points.uuid);
|
||||||
|
const toSphere = pathsGroupRef.current?.getObjectByProperty('uuid', target.pointUUID);
|
||||||
|
|
||||||
|
if (fromSphere && toSphere) {
|
||||||
|
const fromWorldPosition = new THREE.Vector3();
|
||||||
|
const toWorldPosition = new THREE.Vector3();
|
||||||
|
fromSphere.getWorldPosition(fromWorldPosition);
|
||||||
|
toSphere.getWorldPosition(toWorldPosition);
|
||||||
|
|
||||||
|
const distance = fromWorldPosition.distanceTo(toWorldPosition);
|
||||||
|
const heightFactor = Math.max(0.5, distance * 0.2);
|
||||||
|
const midPoint = new THREE.Vector3(
|
||||||
|
(fromWorldPosition.x + toWorldPosition.x) / 2,
|
||||||
|
Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor,
|
||||||
|
(fromWorldPosition.z + toWorldPosition.z) / 2
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<QuadraticBezierLine
|
||||||
|
key={`${path.points.uuid}-${target.pointUUID}-${index}`}
|
||||||
|
ref={(el) => (groupRefs.current[`${path.points.uuid}-${target.pointUUID}-${index}`] = el!)}
|
||||||
|
start={fromWorldPosition.toArray()}
|
||||||
|
end={toWorldPosition.toArray()}
|
||||||
|
mid={midPoint.toArray()}
|
||||||
|
color="#42a5f5"
|
||||||
|
lineWidth={4}
|
||||||
|
dashed
|
||||||
|
dashSize={0.75}
|
||||||
|
dashScale={20}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
@ -730,6 +967,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
)}
|
)}
|
||||||
</group>
|
</group>
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PathConnector;
|
export default PathConnector;
|
|
@ -206,6 +206,7 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec
|
||||||
return (
|
return (
|
||||||
<group
|
<group
|
||||||
name={`${path.modeluuid}-${path.type}-path`}
|
name={`${path.modeluuid}-${path.type}-path`}
|
||||||
|
uuid={path.modeluuid}
|
||||||
key={path.modeluuid}
|
key={path.modeluuid}
|
||||||
ref={(el) => (groupRefs.current[path.modeluuid] = el!)}
|
ref={(el) => (groupRefs.current[path.modeluuid] = el!)}
|
||||||
position={path.position}
|
position={path.position}
|
||||||
|
@ -271,10 +272,11 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec
|
||||||
})}
|
})}
|
||||||
</group>
|
</group>
|
||||||
);
|
);
|
||||||
} else if (path.type === "Vehicle" || path.type === "StaticMachine") {
|
} else if (path.type === "Vehicle") {
|
||||||
return (
|
return (
|
||||||
<group
|
<group
|
||||||
name={`${path.modeluuid}-${path.type}-path`}
|
name={`${path.modeluuid}-${path.type}-path`}
|
||||||
|
uuid={path.modeluuid}
|
||||||
key={path.modeluuid}
|
key={path.modeluuid}
|
||||||
ref={(el) => (groupRefs.current[path.modeluuid] = el!)}
|
ref={(el) => (groupRefs.current[path.modeluuid] = el!)}
|
||||||
position={path.position}
|
position={path.position}
|
||||||
|
@ -323,6 +325,114 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec
|
||||||
</Sphere>
|
</Sphere>
|
||||||
</group>
|
</group>
|
||||||
);
|
);
|
||||||
|
} else if (path.type === "StaticMachine") {
|
||||||
|
return (
|
||||||
|
<group
|
||||||
|
name={`${path.modeluuid}-${path.type}-path`}
|
||||||
|
uuid={path.modeluuid}
|
||||||
|
key={path.modeluuid}
|
||||||
|
ref={(el) => (groupRefs.current[path.modeluuid] = el!)}
|
||||||
|
position={path.position}
|
||||||
|
rotation={path.rotation}
|
||||||
|
onClick={(e) => {
|
||||||
|
if (isConnecting || eyeDropMode) return;
|
||||||
|
e.stopPropagation();
|
||||||
|
setSelectedPath({
|
||||||
|
path,
|
||||||
|
group: groupRefs.current[path.modeluuid],
|
||||||
|
});
|
||||||
|
setSelectedActionSphere(null);
|
||||||
|
setTransformMode(null);
|
||||||
|
setSubModule("mechanics");
|
||||||
|
}}
|
||||||
|
onPointerMissed={() => {
|
||||||
|
if (eyeDropMode) return;
|
||||||
|
setSelectedPath(null);
|
||||||
|
setSubModule("properties");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Sphere
|
||||||
|
key={path.points.uuid}
|
||||||
|
uuid={path.points.uuid}
|
||||||
|
position={path.points.position}
|
||||||
|
args={[0.15, 32, 32]}
|
||||||
|
name="events-sphere"
|
||||||
|
ref={(el) => (sphereRefs.current[path.points.uuid] = el!)}
|
||||||
|
onClick={(e) => {
|
||||||
|
if (isConnecting || eyeDropMode) return;
|
||||||
|
e.stopPropagation();
|
||||||
|
setSelectedActionSphere({
|
||||||
|
path,
|
||||||
|
points: sphereRefs.current[path.points.uuid],
|
||||||
|
});
|
||||||
|
setSubModule("mechanics");
|
||||||
|
setSelectedPath(null);
|
||||||
|
}}
|
||||||
|
userData={{ points: path.points, path }}
|
||||||
|
onPointerMissed={() => {
|
||||||
|
if (eyeDropMode) return;
|
||||||
|
setSubModule("properties");
|
||||||
|
setSelectedActionSphere(null);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<meshStandardMaterial color="yellow" />
|
||||||
|
</Sphere>
|
||||||
|
</group>
|
||||||
|
);
|
||||||
|
} else if (path.type === "ArmBot") {
|
||||||
|
return (
|
||||||
|
<group
|
||||||
|
name={`${path.modeluuid}-${path.type}-path`}
|
||||||
|
uuid={path.modeluuid}
|
||||||
|
key={path.modeluuid}
|
||||||
|
ref={(el) => (groupRefs.current[path.modeluuid] = el!)}
|
||||||
|
position={path.position}
|
||||||
|
rotation={path.rotation}
|
||||||
|
onClick={(e) => {
|
||||||
|
if (isConnecting || eyeDropMode) return;
|
||||||
|
e.stopPropagation();
|
||||||
|
setSelectedPath({
|
||||||
|
path,
|
||||||
|
group: groupRefs.current[path.modeluuid],
|
||||||
|
});
|
||||||
|
setSelectedActionSphere(null);
|
||||||
|
setTransformMode(null);
|
||||||
|
setSubModule("mechanics");
|
||||||
|
}}
|
||||||
|
onPointerMissed={() => {
|
||||||
|
if (eyeDropMode) return;
|
||||||
|
setSelectedPath(null);
|
||||||
|
setSubModule("properties");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Sphere
|
||||||
|
key={path.points.uuid}
|
||||||
|
uuid={path.points.uuid}
|
||||||
|
position={path.points.position}
|
||||||
|
args={[0.15, 32, 32]}
|
||||||
|
name="events-sphere"
|
||||||
|
ref={(el) => (sphereRefs.current[path.points.uuid] = el!)}
|
||||||
|
onClick={(e) => {
|
||||||
|
if (isConnecting || eyeDropMode) return;
|
||||||
|
e.stopPropagation();
|
||||||
|
setSelectedActionSphere({
|
||||||
|
path,
|
||||||
|
points: sphereRefs.current[path.points.uuid],
|
||||||
|
});
|
||||||
|
setSubModule("mechanics");
|
||||||
|
setSelectedPath(null);
|
||||||
|
}}
|
||||||
|
userData={{ points: path.points, path }}
|
||||||
|
onPointerMissed={() => {
|
||||||
|
if (eyeDropMode) return;
|
||||||
|
setSubModule("properties");
|
||||||
|
setSelectedActionSphere(null);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<meshStandardMaterial color="pink" />
|
||||||
|
</Sphere>
|
||||||
|
</group>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -65,6 +65,7 @@ export const handleSaveTemplate = async ({
|
||||||
widgets3D,
|
widgets3D,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log('newTemplate: ', newTemplate);
|
||||||
// Extract organization from email
|
// Extract organization from email
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email.includes("@")
|
const organization = email.includes("@")
|
||||||
|
|
|
@ -56,7 +56,7 @@ const Project: React.FC = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="project-main">
|
<div className="project-main">
|
||||||
{/* {loadingProgress && <LoadingPage progress={loadingProgress} />} */}
|
{loadingProgress && <LoadingPage progress={loadingProgress} />}
|
||||||
{!isPlaying && (
|
{!isPlaying && (
|
||||||
<>
|
<>
|
||||||
{toggleThreeD && <ModuleToggle />}
|
{toggleThreeD && <ModuleToggle />}
|
||||||
|
|
|
@ -15,7 +15,7 @@ export const deleteZonesApi = async (userId: string, organization: string, zoneI
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
console.log('result: ', result);
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
|
|
|
@ -2,8 +2,7 @@ let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_UR
|
||||||
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
|
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
|
||||||
|
|
||||||
export const getZoneData = async (zoneId: string, organization: string) => {
|
export const getZoneData = async (zoneId: string, organization: string) => {
|
||||||
console.log("organization: ", organization);
|
|
||||||
console.log("zoneId: ", zoneId);
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${url_Backend_dwinzo}/api/v2/A_zone/${zoneId}/${organization}`,
|
`${url_Backend_dwinzo}/api/v2/A_zone/${zoneId}/${organization}`,
|
||||||
|
|
|
@ -347,12 +347,12 @@ export const useSelectedPath = create<any>((set: any) => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
interface SimulationPathsStore {
|
interface SimulationPathsStore {
|
||||||
simulationStates: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[];
|
simulationStates: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[];
|
||||||
setSimulationStates: (
|
setSimulationStates: (
|
||||||
paths:
|
paths:
|
||||||
| (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]
|
| (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]
|
||||||
| ((prev: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]
|
| ((prev: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]
|
||||||
) => (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[])
|
) => (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[])
|
||||||
) => void;
|
) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,67 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
|
.template-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 1rem;
|
||||||
|
min-height: 50vh;
|
||||||
|
max-height: 60vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-item {
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 1rem;
|
||||||
|
transition: box-shadow 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-image-container {
|
||||||
|
position: relative;
|
||||||
|
padding-bottom: 56.25%; // 16:9 aspect ratio
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-image {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-details {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-name {
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-button {
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
background: #ff4444;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-templates {
|
||||||
|
text-align: center;
|
||||||
|
color: #666;
|
||||||
|
padding: 2rem;
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.widget-left-sideBar {
|
.widget-left-sideBar {
|
||||||
min-height: 50vh;
|
min-height: 50vh;
|
||||||
max-height: 60vh;
|
max-height: 60vh;
|
||||||
|
|
|
@ -24,9 +24,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.floating {
|
.floating {
|
||||||
width: 100%;
|
|
||||||
max-width: 250px;
|
|
||||||
min-height: 83px;
|
width: calc(var(--realTimeViz-container-width) * 0.2);
|
||||||
|
height: calc(var(--realTimeViz-container-width) * 0.05);
|
||||||
|
|
||||||
|
min-width: 250px;
|
||||||
|
max-width: 300px;
|
||||||
|
|
||||||
|
min-height: 83px !important;
|
||||||
|
// max-height: 100px !important;
|
||||||
|
|
||||||
background: var(--background-color);
|
background: var(--background-color);
|
||||||
border: 1.23px solid var(--border-color);
|
border: 1.23px solid var(--border-color);
|
||||||
box-shadow: 0px 4.91px 4.91px 0px #0000001c;
|
box-shadow: 0px 4.91px 4.91px 0px #0000001c;
|
||||||
|
@ -60,9 +68,8 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 10px;
|
// bottom: 10px;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, 0);
|
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
@ -70,6 +77,7 @@
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
max-width: calc(100% - 500px);
|
max-width: calc(100% - 500px);
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
|
transform: translate(-50%, -100%);
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -116,8 +124,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.zone-wrapper.bottom {
|
.zone-wrapper.bottom {
|
||||||
bottom: calc(var(--realTimeViz-container-height) * 0.27);
|
top: var(--bottomWidth);
|
||||||
bottom: 200px;
|
// bottom: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-container {
|
.content-container {
|
||||||
|
@ -138,7 +146,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
background-color: rgba(224, 223, 255, 0.5);
|
background-color: rgba(224, 223, 255, 0.5);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 10px;
|
// bottom: 10px;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, 0);
|
transform: translate(-50%, 0);
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
|
@ -203,9 +211,9 @@
|
||||||
|
|
||||||
.chart-container {
|
.chart-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 150px;
|
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
// border: 1px dashed var(--background-color-gray);
|
border: 1px dashed var(--background-color-gray);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: var(--box-shadow-medium);
|
box-shadow: var(--box-shadow-medium);
|
||||||
padding: 6px 0;
|
padding: 6px 0;
|
||||||
|
@ -306,7 +314,6 @@
|
||||||
min-height: 150px;
|
min-height: 150px;
|
||||||
|
|
||||||
.chart-container {
|
.chart-container {
|
||||||
|
|
||||||
min-width: 160px;
|
min-width: 160px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,14 +331,12 @@
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.right-panel {
|
&.right-panel {
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.left-panel,
|
&.left-panel,
|
||||||
|
@ -342,12 +347,11 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
|
|
||||||
.chart-container {
|
.chart-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 160px;
|
min-height: 150px;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: var(--box-shadow-medium);
|
box-shadow: var(--box-shadow-medium);
|
||||||
|
@ -355,8 +359,6 @@
|
||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -368,8 +370,8 @@
|
||||||
|
|
||||||
.playingFlase {
|
.playingFlase {
|
||||||
.zone-wrapper.bottom {
|
.zone-wrapper.bottom {
|
||||||
bottom: calc(var(--realTimeViz-container-height) * 0.3);
|
top: var(--bottomWidth);
|
||||||
bottom: 210px;
|
// bottom: 210px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,9 +660,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -756,14 +755,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.connectionSuccess {
|
.connectionSuccess {
|
||||||
outline-color: #43C06D;
|
outline-color: #43c06d;
|
||||||
}
|
}
|
||||||
|
|
||||||
.connectionFails {
|
.connectionFails {
|
||||||
outline-color: #ffe3e0;
|
outline-color: #ffe3e0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.editWidgetOptions {
|
.editWidgetOptions {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
// top: 50%;
|
// top: 50%;
|
||||||
|
|
|
@ -329,6 +329,7 @@ interface StaticMachineEventsSchema {
|
||||||
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
||||||
};
|
};
|
||||||
position: [number, number, number];
|
position: [number, number, number];
|
||||||
|
rotation: [number, number, number];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ArmBotEventsSchema {
|
interface ArmBotEventsSchema {
|
||||||
|
@ -343,6 +344,7 @@ interface ArmBotEventsSchema {
|
||||||
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
||||||
};
|
};
|
||||||
position: [number, number, number];
|
position: [number, number, number];
|
||||||
|
rotation: [number, number, number];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type EventData = {
|
export type EventData = {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
interface OuterClickProps {
|
interface OuterClickProps {
|
||||||
contextClassName: string;
|
contextClassName: string[]; // Make sure this is an array of strings
|
||||||
setMenuVisible: React.Dispatch<React.SetStateAction<boolean>>;
|
setMenuVisible: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,8 +11,12 @@ export default function OuterClick({
|
||||||
}: OuterClickProps) {
|
}: OuterClickProps) {
|
||||||
const handleClick = (event: MouseEvent) => {
|
const handleClick = (event: MouseEvent) => {
|
||||||
const targets = event.target as HTMLElement;
|
const targets = event.target as HTMLElement;
|
||||||
// Check if the click is outside the selectable-dropdown-wrapper
|
// Check if the click is outside of any of the provided class names
|
||||||
if (!targets.closest(`.${contextClassName}`)) {
|
const isOutside = contextClassName.every(
|
||||||
|
(className) => !targets.closest(`.${className}`)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isOutside) {
|
||||||
setMenuVisible(false); // Close the menu by updating the state
|
setMenuVisible(false); // Close the menu by updating the state
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -23,7 +27,7 @@ export default function OuterClick({
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener("click", handleClick);
|
document.removeEventListener("click", handleClick);
|
||||||
};
|
};
|
||||||
}, []);
|
}, [contextClassName]); // Add contextClassName to dependency array to handle any changes
|
||||||
|
|
||||||
return null; // This component doesn't render anything
|
return null; // This component doesn't render anything
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue