Merge branch 'main' into simulation-agv
This commit is contained in:
@@ -1,14 +1,18 @@
|
||||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { AppDockIcon } from "../../icons/HeaderIcons";
|
||||
import orgImg from "../../../assets/orgTemp.png"
|
||||
import orgImg from "../../../assets/orgTemp.png";
|
||||
import { useActiveUsers } from "../../../store/store";
|
||||
import { getAvatarColor } from "../../../modules/collaboration/users/functions/getAvatarColor";
|
||||
import { ActiveUser } from "../../../types/users";
|
||||
|
||||
const Header: React.FC = () => {
|
||||
const guestUsers = [
|
||||
{ value: "Nazria", color: "#43C06D" },
|
||||
{ value: "Name1", color: "#0050EB" },
|
||||
{ value: "Abigail", color: "#FF6600" },
|
||||
{ value: "Jack", color: "#488EF6" },
|
||||
]; // Example guest users array
|
||||
const { activeUsers } = useActiveUsers();
|
||||
const userName = localStorage.getItem("userName") || "Anonymous";
|
||||
|
||||
const guestUsers: ActiveUser[] = activeUsers.filter(
|
||||
(user: ActiveUser) => user.userName !== userName
|
||||
);
|
||||
console.log('guestUsers: ', guestUsers);
|
||||
|
||||
return (
|
||||
<div className="header-container">
|
||||
@@ -25,18 +29,23 @@ const Header: React.FC = () => {
|
||||
<div className="other-guest">+{guestUsers.length - 3}</div>
|
||||
)}
|
||||
{guestUsers.slice(0, 3).map((user, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="user-profile"
|
||||
style={{ background: user.color }}
|
||||
>
|
||||
{user.value[0]}
|
||||
</div>
|
||||
<>
|
||||
<div
|
||||
key={index}
|
||||
className="user-profile"
|
||||
style={{ background: getAvatarColor(index) }}
|
||||
>
|
||||
{user.userName[0]}
|
||||
</div>
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
<div className="user-profile-container">
|
||||
<div className="user-profile" style={{ background: "#48AC2A" }}>
|
||||
V
|
||||
<div
|
||||
className="user-profile"
|
||||
style={{ background: "var(--accent-color)" }}
|
||||
>
|
||||
{userName[0]}
|
||||
</div>
|
||||
<div className="user-organization">
|
||||
<img src={orgImg} alt="" />
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
SimulationIcon,
|
||||
} from "../../icons/SimulationIcons";
|
||||
import useToggleStore from "../../../store/useUIToggleStore";
|
||||
import MachineMechanics from "./mechanics/MachineMechanics";
|
||||
import ConveyorMechanics from "./mechanics/ConveyorMechanics";
|
||||
import Visualization from "./visualization/Visualization";
|
||||
import Analysis from "./analysis/Analysis";
|
||||
import Simulations from "./simulation/Simulations";
|
||||
@@ -18,6 +18,7 @@ import { useSelectedActionSphere } from "../../../store/store";
|
||||
import GlobalProperties from "./properties/GlobalProperties";
|
||||
import AsstePropertiies from "./properties/AssetProperties";
|
||||
import ZoneProperties from "./properties/ZoneProperties";
|
||||
import VehicleMechanics from "./mechanics/VehicleMechanics";
|
||||
|
||||
const SideBarRight: React.FC = () => {
|
||||
const { activeModule } = useModuleStore();
|
||||
@@ -98,17 +99,24 @@ const SideBarRight: React.FC = () => {
|
||||
|
||||
{toggleUI && activeModule === "simulation" && (
|
||||
<>
|
||||
{subModule === "mechanics" && selectedActionSphere && (
|
||||
{subModule === "mechanics" && selectedActionSphere && selectedActionSphere.path.type === "Conveyor" && (
|
||||
<div className="sidebar-right-container">
|
||||
<div className="sidebar-right-content-container">
|
||||
<MachineMechanics />
|
||||
<ConveyorMechanics />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{subModule === "mechanics" && selectedActionSphere && selectedActionSphere.path.type === "Vehicle" && (
|
||||
<div className="sidebar-right-container">
|
||||
<div className="sidebar-right-content-container">
|
||||
{/* <VehicleMechanics /> */}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{subModule === "mechanics" && !selectedActionSphere && (
|
||||
<div className="sidebar-right-container">
|
||||
<div className="sidebar-right-content-container">
|
||||
{/* <MachineMechanics /> */}
|
||||
<ConveyorMechanics />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -0,0 +1,586 @@
|
||||
import React, { useRef, useState, useMemo, useEffect } from "react";
|
||||
import {
|
||||
AddIcon,
|
||||
InfoIcon,
|
||||
RemoveIcon,
|
||||
ResizeHeightIcon,
|
||||
} from "../../../icons/ExportCommonIcons";
|
||||
import RenameInput from "../../../ui/inputs/RenameInput";
|
||||
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
|
||||
import RegularDropDown from "../../../ui/inputs/RegularDropDown";
|
||||
import { handleResize } from "../../../../functions/handleResizePannel";
|
||||
import EyeDropInput from "../../../ui/inputs/EyeDropInput";
|
||||
import { useSelectedActionSphere, useSelectedPath, useSimulationPaths } from "../../../../store/store";
|
||||
import * as THREE from 'three';
|
||||
import * as Types from '../../../../types/world/worldTypes';
|
||||
import InputToggle from "../../../ui/inputs/InputToggle";
|
||||
|
||||
const ConveyorMechanics: React.FC = () => {
|
||||
const { selectedActionSphere } = useSelectedActionSphere();
|
||||
const { selectedPath, setSelectedPath } = useSelectedPath();
|
||||
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
|
||||
|
||||
const actionsContainerRef = useRef<HTMLDivElement>(null);
|
||||
const triggersContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const selectedPoint = useMemo(() => {
|
||||
if (!selectedActionSphere) return null;
|
||||
return simulationPaths
|
||||
.filter((path): path is Types.ConveyorEventsSchema => path.type === "Conveyor")
|
||||
.flatMap((path) => path.points)
|
||||
.find((point) => point.uuid === selectedActionSphere.point.uuid);
|
||||
}, [selectedActionSphere, simulationPaths]);
|
||||
|
||||
const handleAddAction = () => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) => {
|
||||
if (path.type === "Conveyor") {
|
||||
return {
|
||||
...path,
|
||||
points: path.points.map((point) => {
|
||||
if (point.uuid === selectedActionSphere.point.uuid) {
|
||||
const actionIndex = point.actions.length;
|
||||
const newAction = {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
name: `Action ${actionIndex + 1}`,
|
||||
type: 'Inherit',
|
||||
material: 'Inherit',
|
||||
delay: 'Inherit',
|
||||
spawnInterval: 'Inherit',
|
||||
isUsed: false
|
||||
};
|
||||
|
||||
return { ...point, actions: [...point.actions, newAction] };
|
||||
}
|
||||
return point;
|
||||
}),
|
||||
};
|
||||
}
|
||||
return path;
|
||||
});
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleDeleteAction = (uuid: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? { ...point, actions: point.actions.filter(action => action.uuid !== uuid) }
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleActionSelect = (uuid: string, actionType: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
actions: point.actions.map((action) =>
|
||||
action.uuid === uuid
|
||||
? {
|
||||
...action,
|
||||
type: actionType,
|
||||
material: actionType === 'Spawn' || actionType === 'Swap' ? 'Inherit' : action.material,
|
||||
delay: actionType === 'Delay' ? 'Inherit' : action.delay,
|
||||
spawnInterval: actionType === 'Spawn' ? 'Inherit' : action.spawnInterval
|
||||
}
|
||||
: action
|
||||
),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
|
||||
// Update the selected item to reflect changes
|
||||
if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
|
||||
const updatedAction = updatedPaths
|
||||
.filter((path): path is Types.ConveyorEventsSchema => path.type === "Conveyor")
|
||||
.flatMap(path => path.points)
|
||||
.find(p => p.uuid === selectedActionSphere.point.uuid)
|
||||
?.actions.find(a => a.uuid === uuid);
|
||||
|
||||
if (updatedAction) {
|
||||
setSelectedItem({
|
||||
type: "action",
|
||||
item: updatedAction
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Modified handleMaterialSelect to ensure it only applies to relevant action types
|
||||
const handleMaterialSelect = (uuid: string, material: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
actions: point.actions.map((action) =>
|
||||
action.uuid === uuid &&
|
||||
(action.type === 'Spawn' || action.type === 'Swap')
|
||||
? { ...action, material }
|
||||
: action
|
||||
),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
|
||||
// Update selected item if it's the current action
|
||||
if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
|
||||
setSelectedItem({
|
||||
...selectedItem,
|
||||
item: {
|
||||
...selectedItem.item,
|
||||
material
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelayChange = (uuid: string, delay: number | string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
actions: point.actions.map((action) =>
|
||||
action.uuid === uuid ? { ...action, delay } : action
|
||||
),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleSpawnIntervalChange = (uuid: string, spawnInterval: number | string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
actions: point.actions.map((action) =>
|
||||
action.uuid === uuid ? { ...action, spawnInterval } : action
|
||||
),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleSpeedChange = (speed: number) => {
|
||||
if (!selectedPath) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.modeluuid === selectedPath.path.modeluuid ? { ...path, speed } : path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
setSelectedPath({ ...selectedPath, path: { ...selectedPath.path, speed } });
|
||||
};
|
||||
|
||||
const handleAddTrigger = () => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) => {
|
||||
if (point.uuid === selectedActionSphere.point.uuid) {
|
||||
const triggerIndex = point.triggers.length;
|
||||
const newTrigger = {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
name: `Trigger ${triggerIndex + 1}`,
|
||||
type: '',
|
||||
isUsed: false
|
||||
};
|
||||
|
||||
return { ...point, triggers: [...point.triggers, newTrigger] };
|
||||
}
|
||||
return point;
|
||||
}),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleDeleteTrigger = (uuid: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? { ...point, triggers: point.triggers.filter(trigger => trigger.uuid !== uuid) }
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleTriggerSelect = (uuid: string, triggerType: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
triggers: point.triggers.map((trigger) =>
|
||||
trigger.uuid === uuid ? { ...trigger, type: triggerType } : trigger
|
||||
),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
// Update the toggle handlers to immediately update the selected item
|
||||
const handleActionToggle = (uuid: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
actions: point.actions.map((action) => ({
|
||||
...action,
|
||||
isUsed: action.uuid === uuid ? !action.isUsed : false,
|
||||
})),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
|
||||
// Immediately update the selected item if it's the one being toggled
|
||||
if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
|
||||
setSelectedItem({
|
||||
...selectedItem,
|
||||
item: {
|
||||
...selectedItem.item,
|
||||
isUsed: !selectedItem.item.isUsed
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Do the same for trigger toggle
|
||||
const handleTriggerToggle = (uuid: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
triggers: point.triggers.map((trigger) => ({
|
||||
...trigger,
|
||||
isUsed: trigger.uuid === uuid ? !trigger.isUsed : false,
|
||||
})),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
|
||||
// Immediately update the selected item if it's the one being toggled
|
||||
if (selectedItem?.type === "trigger" && selectedItem.item.uuid === uuid) {
|
||||
setSelectedItem({
|
||||
...selectedItem,
|
||||
item: {
|
||||
...selectedItem.item,
|
||||
isUsed: !selectedItem.item.isUsed
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const [selectedItem, setSelectedItem] = useState<{ type: "action" | "trigger"; item: any; } | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedItem(null); // Reset selectedItem when selectedActionSphere changes
|
||||
}, [selectedActionSphere]);
|
||||
|
||||
return (
|
||||
<div className="machine-mechanics-container">
|
||||
<div className="machine-mechanics-header">
|
||||
{selectedActionSphere?.path?.modelName || "point name not found"}
|
||||
</div>
|
||||
|
||||
<div className="machine-mechanics-content-container">
|
||||
{!selectedPath &&
|
||||
<>
|
||||
<div className="actions">
|
||||
<div className="header">
|
||||
<div className="header-value">Actions</div>
|
||||
<div className="add-button" onClick={handleAddAction}>
|
||||
<AddIcon /> Add
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="lists-main-container"
|
||||
ref={actionsContainerRef}
|
||||
style={{ height: "120px" }}
|
||||
>
|
||||
<div className="list-container">
|
||||
{selectedPoint?.actions.map((action) => (
|
||||
<div
|
||||
key={action.uuid}
|
||||
className={`list-item ${selectedItem?.type === "action" &&
|
||||
selectedItem.item?.uuid === action.uuid
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className="value"
|
||||
onClick={() => setSelectedItem({ type: "action", item: action })}
|
||||
>
|
||||
<RenameInput value={action.name} />
|
||||
</div>
|
||||
<div
|
||||
className="remove-button"
|
||||
onClick={() => handleDeleteAction(action.uuid)}
|
||||
>
|
||||
<RemoveIcon />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div
|
||||
className="resize-icon"
|
||||
id="action-resize"
|
||||
onMouseDown={(e) => handleResize(e, actionsContainerRef)}
|
||||
>
|
||||
<ResizeHeightIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="triggers">
|
||||
<div className="header">
|
||||
<div className="header-value">Triggers</div>
|
||||
<div className="add-button" onClick={handleAddTrigger}>
|
||||
<AddIcon /> Add
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="lists-main-container"
|
||||
ref={triggersContainerRef}
|
||||
style={{ height: "120px" }}
|
||||
>
|
||||
<div className="list-container">
|
||||
{selectedPoint?.triggers.map((trigger) => (
|
||||
<div
|
||||
key={trigger.uuid}
|
||||
className={`list-item ${selectedItem?.type === "trigger" &&
|
||||
selectedItem.item?.uuid === trigger.uuid
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className="value"
|
||||
onClick={() => setSelectedItem({ type: "trigger", item: trigger })}
|
||||
>
|
||||
<RenameInput value={trigger.name} />
|
||||
</div>
|
||||
<div
|
||||
className="remove-button"
|
||||
onClick={() => handleDeleteTrigger(trigger.uuid)}
|
||||
>
|
||||
<RemoveIcon />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div
|
||||
className="resize-icon"
|
||||
id="trigger-resize"
|
||||
onMouseDown={(e) => handleResize(e, triggersContainerRef)}
|
||||
>
|
||||
<ResizeHeightIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
|
||||
<div className="selected-properties-container">
|
||||
{selectedItem && (
|
||||
<>
|
||||
<div className="properties-header">{selectedItem.item.name}</div>
|
||||
|
||||
{selectedItem.type === "action" && (
|
||||
<>
|
||||
<InputToggle
|
||||
inputKey="enableTrigger"
|
||||
label="Enable Trigger"
|
||||
value={selectedItem.item.isUsed}
|
||||
onClick={() => handleActionToggle(selectedItem.item.uuid)}
|
||||
/>
|
||||
<LabledDropdown
|
||||
defaultOption={selectedItem.item.type}
|
||||
options={["Inherit", "Spawn", "Swap", "Despawn", "Delay"]}
|
||||
onSelect={(option) => handleActionSelect(selectedItem.item.uuid, option)}
|
||||
/>
|
||||
|
||||
{/* Only show material dropdown for Spawn/Swap actions */}
|
||||
{(selectedItem.item.type === 'Spawn' || selectedItem.item.type === 'Swap') && (
|
||||
<LabledDropdown
|
||||
label={selectedItem.item.type === 'Spawn' ? 'Spawn Material' : 'Swap Material'}
|
||||
defaultOption={selectedItem.item.material}
|
||||
options={["Inherit", "Crate", "Box"]}
|
||||
onSelect={(option) => handleMaterialSelect(selectedItem.item.uuid, option)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Only show delay input for Delay actions */}
|
||||
{selectedItem.item.type === 'Delay' && (
|
||||
<InputWithDropDown
|
||||
label="Delay Time"
|
||||
value={selectedItem.item.delay === 'Inherit'
|
||||
? undefined
|
||||
: selectedItem.item.delay}
|
||||
onChange={(value) => {
|
||||
const numValue = parseInt(value);
|
||||
handleDelayChange(
|
||||
selectedItem.item.uuid,
|
||||
!value ? 'Inherit' : numValue
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Only show spawn interval for Spawn actions */}
|
||||
{selectedItem.item.type === 'Spawn' && (
|
||||
<InputWithDropDown
|
||||
label="Spawn Interval"
|
||||
min={0}
|
||||
defaultValue={selectedItem.item.spawnInterval === "Inherit" ? "" : selectedItem.item.spawnInterval.toString()}
|
||||
value={selectedItem.item.spawnInterval === "Inherit" ? "" : selectedItem.item.spawnInterval.toString()}
|
||||
onChange={(value) => {
|
||||
handleSpawnIntervalChange(selectedItem.item.uuid, (value === "") ? "Inherit" : parseInt(value));
|
||||
}}
|
||||
/>
|
||||
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{selectedItem.type === "trigger" && (
|
||||
<>
|
||||
<InputToggle
|
||||
inputKey="enableTrigger"
|
||||
label="Enable Trigger"
|
||||
value={selectedItem.item.isUsed}
|
||||
onClick={() => handleTriggerToggle(selectedItem.item.uuid)}
|
||||
/>
|
||||
|
||||
<LabledDropdown
|
||||
defaultOption={selectedItem.item.type || "Select Trigger Type"}
|
||||
options={["On-Hit", "Buffer"]}
|
||||
onSelect={(option) => handleTriggerSelect(selectedItem.item.uuid, option)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{selectedPath && !selectedItem && (
|
||||
<div className="speed-control">
|
||||
<InputWithDropDown
|
||||
label="Conveyor Speed"
|
||||
value={selectedPath.path.speed.toString()}
|
||||
onChange={(value) => handleSpeedChange(parseFloat(value))}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="footer">
|
||||
<InfoIcon />
|
||||
By selecting points, you can create events and triggers.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConveyorMechanics;
|
||||
@@ -1,533 +0,0 @@
|
||||
import React, { useRef, useState, useMemo, useEffect } from "react";
|
||||
import {
|
||||
AddIcon,
|
||||
InfoIcon,
|
||||
RemoveIcon,
|
||||
ResizeHeightIcon,
|
||||
} from "../../../icons/ExportCommonIcons";
|
||||
import RenameInput from "../../../ui/inputs/RenameInput";
|
||||
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
|
||||
import RegularDropDown from "../../../ui/inputs/RegularDropDown";
|
||||
import { handleResize } from "../../../../functions/handleResizePannel";
|
||||
import EyeDropInput from "../../../ui/inputs/EyeDropInput";
|
||||
import { useSelectedActionSphere, useSelectedPath, useSimulationPaths } from "../../../../store/store";
|
||||
import * as THREE from 'three';
|
||||
import InputToggle from "../../../ui/inputs/InputToggle";
|
||||
|
||||
const MachineMechanics: React.FC = () => {
|
||||
const { selectedActionSphere } = useSelectedActionSphere();
|
||||
const { selectedPath, setSelectedPath } = useSelectedPath();
|
||||
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
|
||||
|
||||
const actionsContainerRef = useRef<HTMLDivElement>(null);
|
||||
const triggersContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const selectedPoint = useMemo(() => {
|
||||
if (!selectedActionSphere) return null;
|
||||
return simulationPaths.flatMap((path) => path.points).find((point) => point.uuid === selectedActionSphere.point.uuid);
|
||||
}, [selectedActionSphere, simulationPaths]);
|
||||
|
||||
const handleAddAction = () => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) => ({
|
||||
...path,
|
||||
points: path.points.map((point) => {
|
||||
if (point.uuid === selectedActionSphere.point.uuid) {
|
||||
const actionIndex = point.actions.length;
|
||||
const newAction = {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
name: `Action ${actionIndex + 1}`,
|
||||
type: 'Inherit',
|
||||
material: 'Inherit',
|
||||
delay: 'Inherit',
|
||||
spawnInterval: 'Inherit',
|
||||
isUsed: false
|
||||
};
|
||||
|
||||
return { ...point, actions: [...point.actions, newAction] };
|
||||
}
|
||||
return point;
|
||||
}),
|
||||
}));
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleDeleteAction = (uuid: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) => ({
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? { ...point, actions: point.actions.filter(action => action.uuid !== uuid) }
|
||||
: point
|
||||
),
|
||||
}));
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleActionSelect = (uuid: string, actionType: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) => ({
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
actions: point.actions.map((action) =>
|
||||
action.uuid === uuid
|
||||
? {
|
||||
...action,
|
||||
type: actionType,
|
||||
// Reset dependent fields when type changes
|
||||
material: actionType === 'Spawn' || actionType === 'Swap' ? 'Inherit' : action.material,
|
||||
delay: actionType === 'Delay' ? 'Inherit' : action.delay,
|
||||
spawnInterval: actionType === 'Spawn' ? 'Inherit' : action.spawnInterval
|
||||
}
|
||||
: action
|
||||
),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}));
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
|
||||
// Update the selected item to reflect changes
|
||||
if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
|
||||
const updatedAction = updatedPaths
|
||||
.flatMap(path => path.points)
|
||||
.find(p => p.uuid === selectedActionSphere.point.uuid)
|
||||
?.actions.find(a => a.uuid === uuid);
|
||||
|
||||
if (updatedAction) {
|
||||
setSelectedItem({
|
||||
type: "action",
|
||||
item: updatedAction
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Modified handleMaterialSelect to ensure it only applies to relevant action types
|
||||
const handleMaterialSelect = (uuid: string, material: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) => ({
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
actions: point.actions.map((action) =>
|
||||
action.uuid === uuid &&
|
||||
(action.type === 'Spawn' || action.type === 'Swap')
|
||||
? { ...action, material }
|
||||
: action
|
||||
),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}));
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
|
||||
// Update selected item if it's the current action
|
||||
if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
|
||||
setSelectedItem({
|
||||
...selectedItem,
|
||||
item: {
|
||||
...selectedItem.item,
|
||||
material
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelayChange = (uuid: string, delay: number | string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) => ({
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
actions: point.actions.map((action) =>
|
||||
action.uuid === uuid ? { ...action, delay } : action
|
||||
),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}));
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleSpawnIntervalChange = (uuid: string, spawnInterval: number | string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) => ({
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
actions: point.actions.map((action) =>
|
||||
action.uuid === uuid ? { ...action, spawnInterval } : action
|
||||
),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}));
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleSpeedChange = (speed: number) => {
|
||||
if (!selectedPath) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.modeluuid === selectedPath.path.modeluuid ? { ...path, speed } : path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
setSelectedPath({ ...selectedPath, path: { ...selectedPath.path, speed } });
|
||||
};
|
||||
|
||||
const handleAddTrigger = () => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) => ({
|
||||
...path,
|
||||
points: path.points.map((point) => {
|
||||
if (point.uuid === selectedActionSphere.point.uuid) {
|
||||
const triggerIndex = point.triggers.length;
|
||||
const newTrigger = {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
name: `Trigger ${triggerIndex + 1}`,
|
||||
type: '',
|
||||
isUsed: false
|
||||
};
|
||||
|
||||
return { ...point, triggers: [...point.triggers, newTrigger] };
|
||||
}
|
||||
return point;
|
||||
}),
|
||||
}));
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleDeleteTrigger = (uuid: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) => ({
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? { ...point, triggers: point.triggers.filter(trigger => trigger.uuid !== uuid) }
|
||||
: point
|
||||
),
|
||||
}));
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleTriggerSelect = (uuid: string, triggerType: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) => ({
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
triggers: point.triggers.map((trigger) =>
|
||||
trigger.uuid === uuid ? { ...trigger, type: triggerType } : trigger
|
||||
),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}));
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
// Update the toggle handlers to immediately update the selected item
|
||||
const handleActionToggle = (uuid: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) => ({
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
actions: point.actions.map((action) => ({
|
||||
...action,
|
||||
isUsed: action.uuid === uuid ? !action.isUsed : false,
|
||||
})),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}));
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
|
||||
// Immediately update the selected item if it's the one being toggled
|
||||
if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
|
||||
setSelectedItem({
|
||||
...selectedItem,
|
||||
item: {
|
||||
...selectedItem.item,
|
||||
isUsed: !selectedItem.item.isUsed
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Do the same for trigger toggle
|
||||
const handleTriggerToggle = (uuid: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) => ({
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
triggers: point.triggers.map((trigger) => ({
|
||||
...trigger,
|
||||
isUsed: trigger.uuid === uuid ? !trigger.isUsed : false,
|
||||
})),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}));
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
|
||||
// Immediately update the selected item if it's the one being toggled
|
||||
if (selectedItem?.type === "trigger" && selectedItem.item.uuid === uuid) {
|
||||
setSelectedItem({
|
||||
...selectedItem,
|
||||
item: {
|
||||
...selectedItem.item,
|
||||
isUsed: !selectedItem.item.isUsed
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const [selectedItem, setSelectedItem] = useState<{ type: "action" | "trigger"; item: any; } | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedItem(null); // Reset selectedItem when selectedActionSphere changes
|
||||
}, [selectedActionSphere]);
|
||||
|
||||
return (
|
||||
<div className="machine-mechanics-container">
|
||||
<div className="machine-mechanics-header">
|
||||
{selectedActionSphere?.path?.modelName || "point name not found"}
|
||||
</div>
|
||||
|
||||
<div className="machine-mechanics-content-container">
|
||||
<div className="actions">
|
||||
<div className="header">
|
||||
<div className="header-value">Actions</div>
|
||||
<div className="add-button" onClick={handleAddAction}>
|
||||
<AddIcon /> Add
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="lists-main-container"
|
||||
ref={actionsContainerRef}
|
||||
style={{ height: "120px" }}
|
||||
>
|
||||
<div className="list-container">
|
||||
{selectedPoint?.actions.map((action) => (
|
||||
<div
|
||||
key={action.uuid}
|
||||
className={`list-item ${selectedItem?.type === "action" &&
|
||||
selectedItem.item?.uuid === action.uuid
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className="value"
|
||||
onClick={() => setSelectedItem({ type: "action", item: action })}
|
||||
>
|
||||
<RenameInput value={action.name} />
|
||||
</div>
|
||||
<div
|
||||
className="remove-button"
|
||||
onClick={() => handleDeleteAction(action.uuid)}
|
||||
>
|
||||
<RemoveIcon />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div
|
||||
className="resize-icon"
|
||||
id="action-resize"
|
||||
onMouseDown={(e) => handleResize(e, actionsContainerRef)}
|
||||
>
|
||||
<ResizeHeightIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="triggers">
|
||||
<div className="header">
|
||||
<div className="header-value">Triggers</div>
|
||||
<div className="add-button" onClick={handleAddTrigger}>
|
||||
<AddIcon /> Add
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="lists-main-container"
|
||||
ref={triggersContainerRef}
|
||||
style={{ height: "120px" }}
|
||||
>
|
||||
<div className="list-container">
|
||||
{selectedPoint?.triggers.map((trigger) => (
|
||||
<div
|
||||
key={trigger.uuid}
|
||||
className={`list-item ${selectedItem?.type === "trigger" &&
|
||||
selectedItem.item?.uuid === trigger.uuid
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className="value"
|
||||
onClick={() => setSelectedItem({ type: "trigger", item: trigger })}
|
||||
>
|
||||
<RenameInput value={trigger.name} />
|
||||
</div>
|
||||
<div
|
||||
className="remove-button"
|
||||
onClick={() => handleDeleteTrigger(trigger.uuid)}
|
||||
>
|
||||
<RemoveIcon />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div
|
||||
className="resize-icon"
|
||||
id="trigger-resize"
|
||||
onMouseDown={(e) => handleResize(e, triggersContainerRef)}
|
||||
>
|
||||
<ResizeHeightIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="selected-properties-container">
|
||||
{selectedItem && (
|
||||
<>
|
||||
<div className="properties-header">{selectedItem.item.name}</div>
|
||||
|
||||
{selectedItem.type === "action" && (
|
||||
<>
|
||||
<InputToggle
|
||||
inputKey="enableTrigger"
|
||||
label="Enable Trigger"
|
||||
value={selectedItem.item.isUsed}
|
||||
onClick={() => handleActionToggle(selectedItem.item.uuid)}
|
||||
/>
|
||||
<LabledDropdown
|
||||
defaultOption={selectedItem.item.type}
|
||||
options={["Inherit", "Spawn", "Swap", "Despawn", "Delay"]}
|
||||
onSelect={(option) => handleActionSelect(selectedItem.item.uuid, option)}
|
||||
/>
|
||||
|
||||
{/* Only show material dropdown for Spawn/Swap actions */}
|
||||
{(selectedItem.item.type === 'Spawn' || selectedItem.item.type === 'Swap') && (
|
||||
<LabledDropdown
|
||||
label={selectedItem.item.type === 'Spawn' ? 'Spawn Material' : 'Swap Material'}
|
||||
defaultOption={selectedItem.item.material}
|
||||
options={["Inherit", "Crate", "Box"]}
|
||||
onSelect={(option) => handleMaterialSelect(selectedItem.item.uuid, option)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Only show delay input for Delay actions */}
|
||||
{selectedItem.item.type === 'Delay' && (
|
||||
<InputWithDropDown
|
||||
label="Delay Time"
|
||||
value={selectedItem.item.delay === 'Inherit'
|
||||
? undefined
|
||||
: selectedItem.item.delay}
|
||||
onChange={(value) => {
|
||||
const numValue = parseInt(value);
|
||||
handleDelayChange(
|
||||
selectedItem.item.uuid,
|
||||
!value ? 'Inherit' : numValue
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Only show spawn interval for Spawn actions */}
|
||||
{selectedItem.item.type === 'Spawn' && (
|
||||
<InputWithDropDown
|
||||
label="Spawn Interval"
|
||||
min={0}
|
||||
defaultValue={selectedItem.item.spawnInterval === "Inherit" ? "" : selectedItem.item.spawnInterval.toString()}
|
||||
value={selectedItem.item.spawnInterval === "Inherit" ? "" : selectedItem.item.spawnInterval.toString()}
|
||||
onChange={(value) => {
|
||||
handleSpawnIntervalChange(selectedItem.item.uuid, (value === "") ? "Inherit" : parseInt(value));
|
||||
}}
|
||||
/>
|
||||
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{selectedItem.type === "trigger" && (
|
||||
<>
|
||||
<InputToggle
|
||||
inputKey="enableTrigger"
|
||||
label="Enable Trigger"
|
||||
value={selectedItem.item.isUsed}
|
||||
onClick={() => handleTriggerToggle(selectedItem.item.uuid)}
|
||||
/>
|
||||
|
||||
<LabledDropdown
|
||||
defaultOption={selectedItem.item.type || "Select Trigger Type"}
|
||||
options={["On-Hit", "Buffer"]}
|
||||
onSelect={(option) => handleTriggerSelect(selectedItem.item.uuid, option)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{selectedPath && !selectedItem && (
|
||||
<div className="speed-control">
|
||||
<InputWithDropDown
|
||||
label="Path Speed"
|
||||
value={selectedPath.path.speed.toString()}
|
||||
onChange={(value) => handleSpeedChange(parseFloat(value))}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="footer">
|
||||
<InfoIcon />
|
||||
By selecting points, you can create events and triggers.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MachineMechanics;
|
||||
@@ -0,0 +1,561 @@
|
||||
import React, { useRef, useState, useMemo, useEffect } from "react";
|
||||
import {
|
||||
AddIcon,
|
||||
InfoIcon,
|
||||
RemoveIcon,
|
||||
ResizeHeightIcon,
|
||||
} from "../../../icons/ExportCommonIcons";
|
||||
import RenameInput from "../../../ui/inputs/RenameInput";
|
||||
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
|
||||
import RegularDropDown from "../../../ui/inputs/RegularDropDown";
|
||||
import { handleResize } from "../../../../functions/handleResizePannel";
|
||||
import EyeDropInput from "../../../ui/inputs/EyeDropInput";
|
||||
import { useSelectedActionSphere, useSelectedPath, useSimulationPaths } from "../../../../store/store";
|
||||
import * as THREE from 'three';
|
||||
import * as Types from '../../../../types/world/worldTypes';
|
||||
import InputToggle from "../../../ui/inputs/InputToggle";
|
||||
|
||||
const VehicleMechanics: React.FC = () => {
|
||||
const { selectedActionSphere } = useSelectedActionSphere();
|
||||
const { selectedPath, setSelectedPath } = useSelectedPath();
|
||||
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
|
||||
|
||||
const actionsContainerRef = useRef<HTMLDivElement>(null);
|
||||
const triggersContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const selectedPoint = useMemo(() => {
|
||||
if (!selectedActionSphere) return null;
|
||||
return simulationPaths
|
||||
.filter((path): path is Types.ConveyorEventsSchema => path.type === "Conveyor")
|
||||
.flatMap((path) => path.points)
|
||||
.find((point) => point.uuid === selectedActionSphere.point.uuid);
|
||||
}, [selectedActionSphere, simulationPaths]);
|
||||
|
||||
const handleAddAction = () => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) => {
|
||||
if (path.type === "Conveyor") {
|
||||
return {
|
||||
...path,
|
||||
points: path.points.map((point) => {
|
||||
if (point.uuid === selectedActionSphere.point.uuid) {
|
||||
const actionIndex = point.actions.length;
|
||||
const newAction = {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
name: `Action ${actionIndex + 1}`,
|
||||
type: 'Inherit',
|
||||
material: 'Inherit',
|
||||
delay: 'Inherit',
|
||||
spawnInterval: 'Inherit',
|
||||
isUsed: false
|
||||
};
|
||||
|
||||
return { ...point, actions: [...point.actions, newAction] };
|
||||
}
|
||||
return point;
|
||||
}),
|
||||
};
|
||||
}
|
||||
return path;
|
||||
});
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleDeleteAction = (uuid: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? { ...point, actions: point.actions.filter(action => action.uuid !== uuid) }
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleActionSelect = (uuid: string, actionType: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
actions: point.actions.map((action) =>
|
||||
action.uuid === uuid
|
||||
? {
|
||||
...action,
|
||||
type: actionType,
|
||||
material: actionType === 'Spawn' || actionType === 'Swap' ? 'Inherit' : action.material,
|
||||
delay: actionType === 'Delay' ? 'Inherit' : action.delay,
|
||||
spawnInterval: actionType === 'Spawn' ? 'Inherit' : action.spawnInterval
|
||||
}
|
||||
: action
|
||||
),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
|
||||
// Update the selected item to reflect changes
|
||||
if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
|
||||
const updatedAction = updatedPaths
|
||||
.filter((path): path is Types.ConveyorEventsSchema => path.type === "Conveyor")
|
||||
.flatMap(path => path.points)
|
||||
.find(p => p.uuid === selectedActionSphere.point.uuid)
|
||||
?.actions.find(a => a.uuid === uuid);
|
||||
|
||||
if (updatedAction) {
|
||||
setSelectedItem({
|
||||
type: "action",
|
||||
item: updatedAction
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Modified handleMaterialSelect to ensure it only applies to relevant action types
|
||||
const handleMaterialSelect = (uuid: string, material: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
actions: point.actions.map((action) =>
|
||||
action.uuid === uuid &&
|
||||
(action.type === 'Spawn' || action.type === 'Swap')
|
||||
? { ...action, material }
|
||||
: action
|
||||
),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
|
||||
// Update selected item if it's the current action
|
||||
if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
|
||||
setSelectedItem({
|
||||
...selectedItem,
|
||||
item: {
|
||||
...selectedItem.item,
|
||||
material
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelayChange = (uuid: string, delay: number | string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
actions: point.actions.map((action) =>
|
||||
action.uuid === uuid ? { ...action, delay } : action
|
||||
),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleSpawnIntervalChange = (uuid: string, spawnInterval: number | string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
actions: point.actions.map((action) =>
|
||||
action.uuid === uuid ? { ...action, spawnInterval } : action
|
||||
),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleSpeedChange = (speed: number) => {
|
||||
if (!selectedPath) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.modeluuid === selectedPath.path.modeluuid ? { ...path, speed } : path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
setSelectedPath({ ...selectedPath, path: { ...selectedPath.path, speed } });
|
||||
};
|
||||
|
||||
const handleAddTrigger = () => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) => {
|
||||
if (point.uuid === selectedActionSphere.point.uuid) {
|
||||
const triggerIndex = point.triggers.length;
|
||||
const newTrigger = {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
name: `Trigger ${triggerIndex + 1}`,
|
||||
type: '',
|
||||
isUsed: false
|
||||
};
|
||||
|
||||
return { ...point, triggers: [...point.triggers, newTrigger] };
|
||||
}
|
||||
return point;
|
||||
}),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleDeleteTrigger = (uuid: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? { ...point, triggers: point.triggers.filter(trigger => trigger.uuid !== uuid) }
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
const handleTriggerSelect = (uuid: string, triggerType: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
triggers: point.triggers.map((trigger) =>
|
||||
trigger.uuid === uuid ? { ...trigger, type: triggerType } : trigger
|
||||
),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
};
|
||||
|
||||
// Update the toggle handlers to immediately update the selected item
|
||||
const handleActionToggle = (uuid: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
actions: point.actions.map((action) => ({
|
||||
...action,
|
||||
isUsed: action.uuid === uuid ? !action.isUsed : false,
|
||||
})),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
|
||||
// Immediately update the selected item if it's the one being toggled
|
||||
if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
|
||||
setSelectedItem({
|
||||
...selectedItem,
|
||||
item: {
|
||||
...selectedItem.item,
|
||||
isUsed: !selectedItem.item.isUsed
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Do the same for trigger toggle
|
||||
const handleTriggerToggle = (uuid: string) => {
|
||||
if (!selectedActionSphere) return;
|
||||
|
||||
const updatedPaths = simulationPaths.map((path) =>
|
||||
path.type === "Conveyor"
|
||||
? {
|
||||
...path,
|
||||
points: path.points.map((point) =>
|
||||
point.uuid === selectedActionSphere.point.uuid
|
||||
? {
|
||||
...point,
|
||||
triggers: point.triggers.map((trigger) => ({
|
||||
...trigger,
|
||||
isUsed: trigger.uuid === uuid ? !trigger.isUsed : false,
|
||||
})),
|
||||
}
|
||||
: point
|
||||
),
|
||||
}
|
||||
: path
|
||||
);
|
||||
|
||||
setSimulationPaths(updatedPaths);
|
||||
|
||||
// Immediately update the selected item if it's the one being toggled
|
||||
if (selectedItem?.type === "trigger" && selectedItem.item.uuid === uuid) {
|
||||
setSelectedItem({
|
||||
...selectedItem,
|
||||
item: {
|
||||
...selectedItem.item,
|
||||
isUsed: !selectedItem.item.isUsed
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const [selectedItem, setSelectedItem] = useState<{ type: "action" | "trigger"; item: any; } | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedItem(null); // Reset selectedItem when selectedActionSphere changes
|
||||
}, [selectedActionSphere]);
|
||||
|
||||
return (
|
||||
<div className="machine-mechanics-container">
|
||||
<div className="machine-mechanics-header">
|
||||
{selectedActionSphere?.path?.modelName || "point name not found"}
|
||||
</div>
|
||||
|
||||
<div className="machine-mechanics-content-container">
|
||||
<div className="actions">
|
||||
<div className="header">
|
||||
<div className="header-value">Actions</div>
|
||||
<div className="add-button" onClick={handleAddAction}>
|
||||
<AddIcon /> Add
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="lists-main-container"
|
||||
ref={actionsContainerRef}
|
||||
style={{ height: "120px" }}
|
||||
>
|
||||
<div className="list-container">
|
||||
<>
|
||||
{console.log(selectedPoint)}
|
||||
</>
|
||||
</div>
|
||||
<div
|
||||
className="resize-icon"
|
||||
id="action-resize"
|
||||
onMouseDown={(e) => handleResize(e, actionsContainerRef)}
|
||||
>
|
||||
<ResizeHeightIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="triggers">
|
||||
<div className="header">
|
||||
<div className="header-value">Triggers</div>
|
||||
<div className="add-button" onClick={handleAddTrigger}>
|
||||
<AddIcon /> Add
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="lists-main-container"
|
||||
ref={triggersContainerRef}
|
||||
style={{ height: "120px" }}
|
||||
>
|
||||
<div className="list-container">
|
||||
{selectedPoint?.triggers.map((trigger) => (
|
||||
<div
|
||||
key={trigger.uuid}
|
||||
className={`list-item ${selectedItem?.type === "trigger" &&
|
||||
selectedItem.item?.uuid === trigger.uuid
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className="value"
|
||||
onClick={() => setSelectedItem({ type: "trigger", item: trigger })}
|
||||
>
|
||||
<RenameInput value={trigger.name} />
|
||||
</div>
|
||||
<div
|
||||
className="remove-button"
|
||||
onClick={() => handleDeleteTrigger(trigger.uuid)}
|
||||
>
|
||||
<RemoveIcon />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div
|
||||
className="resize-icon"
|
||||
id="trigger-resize"
|
||||
onMouseDown={(e) => handleResize(e, triggersContainerRef)}
|
||||
>
|
||||
<ResizeHeightIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="selected-properties-container">
|
||||
{selectedItem && (
|
||||
<>
|
||||
<div className="properties-header">{selectedItem.item.name}</div>
|
||||
|
||||
{selectedItem.type === "action" && (
|
||||
<>
|
||||
<InputToggle
|
||||
inputKey="enableTrigger"
|
||||
label="Enable Trigger"
|
||||
value={selectedItem.item.isUsed}
|
||||
onClick={() => handleActionToggle(selectedItem.item.uuid)}
|
||||
/>
|
||||
<LabledDropdown
|
||||
defaultOption={selectedItem.item.type}
|
||||
options={["Inherit", "Spawn", "Swap", "Despawn", "Delay"]}
|
||||
onSelect={(option) => handleActionSelect(selectedItem.item.uuid, option)}
|
||||
/>
|
||||
|
||||
{/* Only show material dropdown for Spawn/Swap actions */}
|
||||
{(selectedItem.item.type === 'Spawn' || selectedItem.item.type === 'Swap') && (
|
||||
<LabledDropdown
|
||||
label={selectedItem.item.type === 'Spawn' ? 'Spawn Material' : 'Swap Material'}
|
||||
defaultOption={selectedItem.item.material}
|
||||
options={["Inherit", "Crate", "Box"]}
|
||||
onSelect={(option) => handleMaterialSelect(selectedItem.item.uuid, option)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Only show delay input for Delay actions */}
|
||||
{selectedItem.item.type === 'Delay' && (
|
||||
<InputWithDropDown
|
||||
label="Delay Time"
|
||||
value={selectedItem.item.delay === 'Inherit'
|
||||
? undefined
|
||||
: selectedItem.item.delay}
|
||||
onChange={(value) => {
|
||||
const numValue = parseInt(value);
|
||||
handleDelayChange(
|
||||
selectedItem.item.uuid,
|
||||
!value ? 'Inherit' : numValue
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Only show spawn interval for Spawn actions */}
|
||||
{selectedItem.item.type === 'Spawn' && (
|
||||
<InputWithDropDown
|
||||
label="Spawn Interval"
|
||||
min={0}
|
||||
defaultValue={selectedItem.item.spawnInterval === "Inherit" ? "" : selectedItem.item.spawnInterval.toString()}
|
||||
value={selectedItem.item.spawnInterval === "Inherit" ? "" : selectedItem.item.spawnInterval.toString()}
|
||||
onChange={(value) => {
|
||||
handleSpawnIntervalChange(selectedItem.item.uuid, (value === "") ? "Inherit" : parseInt(value));
|
||||
}}
|
||||
/>
|
||||
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{selectedItem.type === "trigger" && (
|
||||
<>
|
||||
<InputToggle
|
||||
inputKey="enableTrigger"
|
||||
label="Enable Trigger"
|
||||
value={selectedItem.item.isUsed}
|
||||
onClick={() => handleTriggerToggle(selectedItem.item.uuid)}
|
||||
/>
|
||||
|
||||
<LabledDropdown
|
||||
defaultOption={selectedItem.item.type || "Select Trigger Type"}
|
||||
options={["On-Hit", "Buffer"]}
|
||||
onSelect={(option) => handleTriggerSelect(selectedItem.item.uuid, option)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{selectedPath && !selectedItem && (
|
||||
<div className="speed-control">
|
||||
<InputWithDropDown
|
||||
label="ConveyorEventsSchema Speed"
|
||||
value={selectedPath.path.speed.toString()}
|
||||
onChange={(value) => handleSpeedChange(parseFloat(value))}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="footer">
|
||||
<InfoIcon />
|
||||
By selecting points, you can create events and triggers.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default VehicleMechanics;
|
||||
@@ -1,115 +1,215 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import MultiLevelDropdown from '../../../../ui/inputs/MultiLevelDropDown'
|
||||
import { AddIcon } from '../../../../icons/ExportCommonIcons'
|
||||
import RegularDropDown from '../../../../ui/inputs/RegularDropDown'
|
||||
import useChartStore from '../../../../../store/useChartStore'
|
||||
import axios from 'axios'
|
||||
// import React, { useEffect, useState } from 'react'
|
||||
// import MultiLevelDropdown from '../../../../ui/inputs/MultiLevelDropDown'
|
||||
// import { AddIcon } from '../../../../icons/ExportCommonIcons'
|
||||
// import RegularDropDown from '../../../../ui/inputs/RegularDropDown'
|
||||
// import useChartStore from '../../../../../store/useChartStore'
|
||||
// import axios from 'axios'
|
||||
|
||||
type Props = {}
|
||||
// type Props = {}
|
||||
|
||||
const LineGrapInput = (props: Props) => {
|
||||
const [dropDowndata, setDropDownData] = useState({})
|
||||
const [selections, setSelections] = useState<Record<string, { name: string, fields: string }>>({})
|
||||
const [selectedOption, setSelectedOption] = useState('1h')
|
||||
const { measurements, setMeasurements, updateDuration, duration } = useChartStore();
|
||||
// const LineGrapInput = (props: Props) => {
|
||||
// const [dropDowndata, setDropDownData] = useState({})
|
||||
// const [selections, setSelections] = useState<Record<string, { name: string, fields: string }>>({})
|
||||
// const [selectedOption, setSelectedOption] = useState('1h')
|
||||
// const { measurements, setMeasurements, updateDuration, duration } = useChartStore();
|
||||
// const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
|
||||
const handleSelectDuration = (option: string) => {
|
||||
updateDuration(option); // Normalize for key matching
|
||||
};
|
||||
// const handleSelectDuration = (option: string) => {
|
||||
// updateDuration(option); // Normalize for key matching
|
||||
// };
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
const response = await axios.get('http://192.168.0.192:5010/getinput');
|
||||
if (response.status === 200) {
|
||||
console.log('dropdown data:', response.data);
|
||||
setDropDownData(response.data)
|
||||
} else {
|
||||
console.log('Unexpected response:', response);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('There was an error!', error);
|
||||
}
|
||||
};
|
||||
fetchZoneData();
|
||||
}, []);
|
||||
// useEffect(() => {
|
||||
// const fetchZoneData = async () => {
|
||||
// try {
|
||||
// const response = await axios.get(`http://${iotApiUrl}/getinput`);
|
||||
// if (response.status === 200) {
|
||||
// console.log('dropdown data:', response.data);
|
||||
// setDropDownData(response.data)
|
||||
// } else {
|
||||
// console.log('Unexpected response:', response);
|
||||
// }
|
||||
// } catch (error) {
|
||||
// console.error('There was an error!', error);
|
||||
// }
|
||||
// };
|
||||
// fetchZoneData();
|
||||
// }, []);
|
||||
|
||||
useEffect(() => {
|
||||
console.log(selections);
|
||||
}, [selections])
|
||||
// useEffect(() => {
|
||||
// console.log(selections);
|
||||
// }, [selections])
|
||||
|
||||
const handleSelect = (inputKey: string, selectedData: { name: string, fields: string } | null) => {
|
||||
setSelections(prev => {
|
||||
if (selectedData === null) {
|
||||
const newSelections = { ...prev };
|
||||
delete newSelections[inputKey];
|
||||
return newSelections;
|
||||
} else {
|
||||
return {
|
||||
...prev,
|
||||
[inputKey]: selectedData
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
// const handleSelect = (inputKey: string, selectedData: { name: string, fields: string } | null) => {
|
||||
// setSelections(prev => {
|
||||
// if (selectedData === null) {
|
||||
// const newSelections = { ...prev };
|
||||
// delete newSelections[inputKey];
|
||||
// return newSelections;
|
||||
// } else {
|
||||
// return {
|
||||
// ...prev,
|
||||
// [inputKey]: selectedData
|
||||
// };
|
||||
// }
|
||||
// });
|
||||
// };
|
||||
|
||||
interface Measurement {
|
||||
name: string;
|
||||
fields: string;
|
||||
}
|
||||
// interface Measurement {
|
||||
// name: string;
|
||||
// fields: string;
|
||||
// }
|
||||
|
||||
interface InputData {
|
||||
[key: string]: Measurement;
|
||||
}
|
||||
// interface InputData {
|
||||
// [key: string]: Measurement;
|
||||
// }
|
||||
|
||||
const extractMeasurements = (input: InputData): Measurement[] => {
|
||||
return Object.values(input);
|
||||
};
|
||||
// const extractMeasurements = (input: InputData): Measurement[] => {
|
||||
// return Object.values(input);
|
||||
// };
|
||||
|
||||
useEffect(() => {
|
||||
const measurementsData = extractMeasurements(selections);
|
||||
setMeasurements(measurementsData);
|
||||
}, [selections]);
|
||||
// useEffect(() => {
|
||||
// const measurementsData = extractMeasurements(selections);
|
||||
// setMeasurements(measurementsData);
|
||||
// }, [selections]);
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="inputs-wrapper">
|
||||
{[...Array(6)].map((_, index) => {
|
||||
const inputKey = `input${index + 1}`;
|
||||
return (
|
||||
<div key={index} className="datas">
|
||||
<div className="datas__label">Input {index + 1}</div>
|
||||
<div className="datas__class">
|
||||
<MultiLevelDropdown
|
||||
data={dropDowndata}
|
||||
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
onUnselect={() => handleSelect(inputKey, null)}
|
||||
selectedValue={selections[inputKey]}
|
||||
/>
|
||||
<div className="icon">
|
||||
<AddIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div>
|
||||
<div className="datas">
|
||||
<div className="datas__label">duration</div>
|
||||
<div className="datas__class">
|
||||
<RegularDropDown
|
||||
header={duration}
|
||||
options={["1h", "2h", "12h"]}
|
||||
onSelect={handleSelectDuration}
|
||||
search={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
// return (
|
||||
// <>
|
||||
// <div className="inputs-wrapper">
|
||||
// {[...Array(6)].map((_, index) => {
|
||||
// const inputKey = `input${index + 1}`;
|
||||
// return (
|
||||
// <div key={index} className="datas">
|
||||
// <div className="datas__label">Input {index + 1}</div>
|
||||
// <div className="datas__class">
|
||||
// <MultiLevelDropdown
|
||||
// data={dropDowndata}
|
||||
// onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
// onUnselect={() => handleSelect(inputKey, null)}
|
||||
// selectedValue={selections[inputKey]}
|
||||
// />
|
||||
// <div className="icon">
|
||||
// <AddIcon />
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// );
|
||||
// })}
|
||||
// </div>
|
||||
// <div>
|
||||
// <div className="datas">
|
||||
// <div className="datas__label">duration</div>
|
||||
// <div className="datas__class">
|
||||
// <RegularDropDown
|
||||
// header={duration}
|
||||
// options={["1h", "2h", "12h"]}
|
||||
// onSelect={handleSelectDuration}
|
||||
// search={false}
|
||||
// />
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
||||
export default LineGrapInput
|
||||
// export default LineGrapInput
|
||||
|
||||
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import MultiLevelDropdown from "../../../../ui/inputs/MultiLevelDropDown";
|
||||
import { AddIcon } from "../../../../icons/ExportCommonIcons";
|
||||
import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
|
||||
import useChartStore from "../../../../../store/useChartStore";
|
||||
import axios from "axios";
|
||||
|
||||
type Props = {};
|
||||
|
||||
const LineGrapInput = (props: Props) => {
|
||||
const { measurements, setMeasurements, updateDuration, duration } = useChartStore();
|
||||
|
||||
const [dropDowndata, setDropDownData] = useState({});
|
||||
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>(measurements);
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
const response = await axios.get(`http://${iotApiUrl}/getinput`);
|
||||
if (response.status === 200) {
|
||||
console.log("dropdown data:", response.data);
|
||||
setDropDownData(response.data);
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("There was an error!", error);
|
||||
}
|
||||
};
|
||||
fetchZoneData();
|
||||
}, []);
|
||||
|
||||
// Sync Zustand state when component mounts
|
||||
useEffect(() => {
|
||||
setSelections(measurements);
|
||||
}, [measurements]);
|
||||
|
||||
const handleSelect = (inputKey: string, selectedData: { name: string; fields: string } | null) => {
|
||||
setSelections((prev) => {
|
||||
const newSelections = { ...prev };
|
||||
if (selectedData === null) {
|
||||
delete newSelections[inputKey];
|
||||
} else {
|
||||
newSelections[inputKey] = selectedData;
|
||||
}
|
||||
setMeasurements(newSelections); // Update Zustand store
|
||||
return newSelections;
|
||||
});
|
||||
};
|
||||
|
||||
const handleSelectDuration = (option: string) => {
|
||||
updateDuration(option);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="inputs-wrapper">
|
||||
{[...Array(6)].map((_, index) => {
|
||||
const inputKey = `input${index + 1}`;
|
||||
return (
|
||||
<div key={index} className="datas">
|
||||
<div className="datas__label">Input {index + 1}</div>
|
||||
<div className="datas__class">
|
||||
<MultiLevelDropdown
|
||||
data={dropDowndata}
|
||||
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
onUnselect={() => handleSelect(inputKey, null)}
|
||||
selectedValue={selections[inputKey]} // Load from Zustand
|
||||
/>
|
||||
<div className="icon">
|
||||
<AddIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div>
|
||||
<div className="datas">
|
||||
<div className="datas__label">Duration</div>
|
||||
<div className="datas__class">
|
||||
<RegularDropDown
|
||||
header={duration}
|
||||
options={["1h", "2h", "12h"]}
|
||||
onSelect={handleSelectDuration}
|
||||
search={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default LineGrapInput;
|
||||
|
||||
@@ -8,11 +8,12 @@ type Props = {}
|
||||
const PieChartInput = (props: Props) => {
|
||||
const [dropDowndata, setDropDownData] = useState({})
|
||||
const [selections, setSelections] = useState<Record<string, {name: string, fields: string}>>({})
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
const response = await axios.get('http://192.168.0.192:5010/getinput');
|
||||
const response = await axios.get(`http://${iotApiUrl}/getinput`);
|
||||
if (response.status === 200) {
|
||||
console.log('dropdown data:', response.data);
|
||||
setDropDownData(response.data)
|
||||
|
||||
Reference in New Issue
Block a user