Merge remote-tracking branch 'origin/main-dev' into feature/agv-edit
This commit is contained in:
@@ -6,146 +6,128 @@ import PositionInput from "../customInput/PositionInputs";
|
||||
import RotationInput from "../customInput/RotationInput";
|
||||
import { useSelectedFloorItem, useObjectPosition, useObjectRotation } from "../../../../store/builder/store";
|
||||
import { useSceneContext } from "../../../../modules/scene/sceneContext";
|
||||
import { useBuilderStore } from "../../../../store/builder/useBuilderStore";
|
||||
|
||||
interface UserData {
|
||||
id: number; // Unique identifier for the user data
|
||||
label: string; // Label of the user data field
|
||||
value: string; // Value of the user data field
|
||||
id: number;
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
const AssetProperties: React.FC = () => {
|
||||
const [userData, setUserData] = useState<UserData[]>([]); // State to track user data
|
||||
const [nextId, setNextId] = useState(1); // Unique ID for new entries
|
||||
const { selectedFloorItem } = useSelectedFloorItem();
|
||||
const { objectPosition } = useObjectPosition();
|
||||
const { objectRotation } = useObjectRotation();
|
||||
const { assetStore } = useSceneContext();
|
||||
const { assets, setCurrentAnimation } = assetStore()
|
||||
const [hoveredIndex, setHoveredIndex] = useState<any>(null);
|
||||
const [isPlaying, setIsplaying] = useState(false);
|
||||
// Function to handle adding new user data
|
||||
const handleAddUserData = () => {
|
||||
const newUserData: UserData = {
|
||||
id: nextId,
|
||||
label: `Property ${nextId}`,
|
||||
value: "",
|
||||
const [userData, setUserData] = useState<UserData[]>([]);
|
||||
const { selectedFloorItem } = useSelectedFloorItem();
|
||||
const { objectPosition } = useObjectPosition();
|
||||
const { objectRotation } = useObjectRotation();
|
||||
const { assetStore } = useSceneContext();
|
||||
const { assets, setCurrentAnimation } = assetStore();
|
||||
const { loopAnimation } = useBuilderStore();
|
||||
const [hoveredIndex, setHoveredIndex] = useState<any>(null);
|
||||
|
||||
const handleAddUserData = () => {
|
||||
};
|
||||
setUserData([...userData, newUserData]);
|
||||
setNextId(nextId + 1); // Increment the ID for the next entry
|
||||
};
|
||||
|
||||
// Function to update the value of a user data entry
|
||||
const handleUserDataChange = (id: number, newValue: string) => {
|
||||
setUserData((prevUserData) =>
|
||||
prevUserData.map((data) =>
|
||||
data.id === id ? { ...data, value: newValue } : data
|
||||
)
|
||||
);
|
||||
};
|
||||
const handleUserDataChange = (id: number, newValue: string) => {
|
||||
};
|
||||
|
||||
// Remove user data
|
||||
const handleRemoveUserData = (id: number) => {
|
||||
setUserData((prevUserData) =>
|
||||
prevUserData.filter((data) => data.id !== id)
|
||||
);
|
||||
};
|
||||
const handleRemoveUserData = (id: number) => {
|
||||
};
|
||||
|
||||
const handleAnimationClick = (animation: string) => {
|
||||
if (selectedFloorItem && selectedFloorItem.animationState) {
|
||||
const isPlaying = selectedFloorItem.animationState?.playing || false;
|
||||
setCurrentAnimation(selectedFloorItem.uuid, animation, !isPlaying);
|
||||
const handleAnimationClick = (animation: string) => {
|
||||
if (selectedFloorItem) {
|
||||
setCurrentAnimation(selectedFloorItem.uuid, animation, true, loopAnimation, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!selectedFloorItem) return null;
|
||||
if (!selectedFloorItem) return null;
|
||||
|
||||
return (
|
||||
<div className="asset-properties-container">
|
||||
{/* Name */}
|
||||
<div className="header">{selectedFloorItem.userData.modelName}</div>
|
||||
<section>
|
||||
{objectPosition.x && objectPosition.z &&
|
||||
<PositionInput
|
||||
onChange={() => { }}
|
||||
value1={parseFloat(objectPosition.x.toFixed(5))}
|
||||
value2={parseFloat(objectPosition.z.toFixed(5))}
|
||||
/>
|
||||
}
|
||||
{objectRotation.y &&
|
||||
<RotationInput
|
||||
onChange={() => { }}
|
||||
value={parseFloat(objectRotation.y.toFixed(5))}
|
||||
/>
|
||||
}
|
||||
</section>
|
||||
return (
|
||||
<div className="asset-properties-container">
|
||||
{/* Name */}
|
||||
<div className="header">{selectedFloorItem.userData.modelName}</div>
|
||||
<section>
|
||||
{objectPosition &&
|
||||
<PositionInput
|
||||
onChange={() => { }}
|
||||
value1={parseFloat(objectPosition.x.toFixed(5))}
|
||||
value2={parseFloat(objectPosition.z.toFixed(5))}
|
||||
/>
|
||||
}
|
||||
{objectRotation &&
|
||||
<RotationInput
|
||||
onChange={() => { }}
|
||||
value={parseFloat(objectRotation.y.toFixed(5))}
|
||||
/>
|
||||
}
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div className="header">Render settings</div>
|
||||
<InputToggle inputKey="visible" label="Visible" />
|
||||
<InputToggle inputKey="frustumCull" label="Frustum cull" />
|
||||
</section>
|
||||
<section>
|
||||
<div className="header">Render settings</div>
|
||||
<InputToggle inputKey="visible" label="Visible" />
|
||||
<InputToggle inputKey="frustumCull" label="Frustum cull" />
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div className="header">User Data</div>
|
||||
{userData.map((data) => (
|
||||
<div className="input-container">
|
||||
<InputWithDropDown
|
||||
key={data.id}
|
||||
label={data.label}
|
||||
value={data.value}
|
||||
editableLabel
|
||||
onChange={(newValue) => handleUserDataChange(data.id, newValue)} // Pass the change handler
|
||||
/>
|
||||
<div
|
||||
className="remove-button"
|
||||
onClick={() => handleRemoveUserData(data.id)}
|
||||
>
|
||||
<RemoveIcon />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<section>
|
||||
<div className="header">User Data</div>
|
||||
{userData.map((data) => (
|
||||
<div className="input-container">
|
||||
<InputWithDropDown
|
||||
key={data.id}
|
||||
label={data.label}
|
||||
value={data.value}
|
||||
editableLabel
|
||||
onChange={(newValue) => handleUserDataChange(data.id, newValue)}
|
||||
/>
|
||||
<div
|
||||
className="remove-button"
|
||||
onClick={() => handleRemoveUserData(data.id)}
|
||||
>
|
||||
<RemoveIcon />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* Add new user data */}
|
||||
<div className="optimize-button" onClick={handleAddUserData}>
|
||||
+ Add
|
||||
</div>
|
||||
</section>
|
||||
<div style={{ display: "flex", flexDirection: "column", outline: "1px solid var(--border-color)" }}>
|
||||
{selectedFloorItem.uuid && <div style={{ display: "flex", alignItems: "center", justifyContent: "center" }}>Animations</div>}
|
||||
{assets.map((asset) => (
|
||||
<div key={asset.modelUuid} className="asset-item">
|
||||
{asset.modelUuid === selectedFloorItem.uuid &&
|
||||
asset.animations &&
|
||||
asset.animations.length > 0 &&
|
||||
asset.animations.map((animation, index) => (
|
||||
<div
|
||||
key={index}
|
||||
style={{ gap: "15px", cursor: "pointer", padding: "5px" }}
|
||||
>
|
||||
<div
|
||||
onClick={() => handleAnimationClick(animation)}
|
||||
onMouseEnter={() => setHoveredIndex(index)}
|
||||
onMouseLeave={() => setHoveredIndex(null)}
|
||||
style={{
|
||||
height: "20px",
|
||||
width: "100%",
|
||||
borderRadius: "5px",
|
||||
background:
|
||||
hoveredIndex === index
|
||||
? "#7b4cd3"
|
||||
: "transparent",
|
||||
}}
|
||||
>
|
||||
{animation.charAt(0).toUpperCase() +
|
||||
animation.slice(1).toLowerCase()}
|
||||
</div>
|
||||
{/* Add new user data */}
|
||||
<div className="optimize-button" onClick={handleAddUserData}>
|
||||
+ Add
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
</section>
|
||||
<div style={{ display: "flex", flexDirection: "column", outline: "1px solid var(--border-color)" }}>
|
||||
{selectedFloorItem.uuid && <div style={{ display: "flex", alignItems: "center", justifyContent: "center" }}>Animations</div>}
|
||||
{assets.map((asset) => (
|
||||
<div key={asset.modelUuid} className="asset-item">
|
||||
{asset.modelUuid === selectedFloorItem.uuid &&
|
||||
asset.animations &&
|
||||
asset.animations.length > 0 &&
|
||||
asset.animations.map((animation, index) => (
|
||||
<div
|
||||
key={index}
|
||||
style={{ gap: "15px", cursor: "pointer", padding: "5px" }}
|
||||
>
|
||||
<div
|
||||
onClick={() => handleAnimationClick(animation)}
|
||||
onMouseEnter={() => setHoveredIndex(index)}
|
||||
onMouseLeave={() => setHoveredIndex(null)}
|
||||
style={{
|
||||
height: "20px",
|
||||
width: "100%",
|
||||
borderRadius: "5px",
|
||||
background:
|
||||
hoveredIndex === index
|
||||
? "#7b4cd3"
|
||||
: "transparent",
|
||||
}}
|
||||
>
|
||||
{animation.charAt(0).toUpperCase() +
|
||||
animation.slice(1).toLowerCase()}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AssetProperties;
|
||||
|
||||
@@ -12,13 +12,17 @@ import { zoneCameraUpdate } from "../../../../services/visulization/zone/zoneCam
|
||||
import { useParams } from "react-router-dom";
|
||||
import { getUserData } from "../../../../functions/getUserData";
|
||||
import { useVersionContext } from "../../../../modules/builder/version/versionContext";
|
||||
import { useSceneContext } from "../../../../modules/scene/sceneContext";
|
||||
|
||||
const ZoneProperties: React.FC = () => {
|
||||
const { Edit, setEdit } = useEditPosition();
|
||||
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||
const { zonePosition, setZonePosition } = usezonePosition();
|
||||
const { zoneTarget, setZoneTarget } = usezoneTarget();
|
||||
const { zones, setZones } = useZones();
|
||||
// const { zones, setZones } = useZones();
|
||||
const { assetStore, zoneStore } = useSceneContext();
|
||||
const { zones, setZoneName } = zoneStore()
|
||||
|
||||
const { projectId } = useParams();
|
||||
const { userName, userId, organization, email } = getUserData();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
@@ -34,10 +38,11 @@ const ZoneProperties: React.FC = () => {
|
||||
|
||||
let zonesdata = {
|
||||
zoneUuid: selectedZone.zoneUuid,
|
||||
viewPortposition: zonePosition,
|
||||
viewPortCenter: zoneTarget,
|
||||
viewPortPosition: zonePosition,
|
||||
viewPortTarget: zoneTarget,
|
||||
};
|
||||
|
||||
|
||||
let response = await zoneCameraUpdate(zonesdata, organization, projectId, selectedVersion?.versionId || "");
|
||||
// console.log('response: ', response);
|
||||
if (response.message === "zone updated") {
|
||||
@@ -63,13 +68,14 @@ const ZoneProperties: React.FC = () => {
|
||||
let response = await zoneCameraUpdate(zonesdata, organization, projectId, selectedVersion?.versionId || "");
|
||||
if (response.message === "zone updated") {
|
||||
setSelectedZone((prev) => ({ ...prev, zoneName: newName }));
|
||||
setZones((prevZones: any[]) =>
|
||||
prevZones.map((zone) =>
|
||||
zone.zoneUuid === selectedZone.zoneUuid
|
||||
? { ...zone, zoneName: newName }
|
||||
: zone
|
||||
)
|
||||
);
|
||||
setZoneName(selectedZone.zoneUuid, newName)
|
||||
// setZones((prevZones: any[]) =>
|
||||
// prevZones.map((zone) =>
|
||||
// zone.zoneUuid === selectedZone.zoneUuid
|
||||
// ? { ...zone, zoneName: newName }
|
||||
// : zone
|
||||
// )
|
||||
// );
|
||||
} else {
|
||||
// console.log(response?.message);
|
||||
}
|
||||
@@ -81,6 +87,7 @@ const ZoneProperties: React.FC = () => {
|
||||
setSelectedZone((prev) => ({ ...prev, [key]: newValue }));
|
||||
}
|
||||
const checkZoneNameDuplicate = (name: string) => {
|
||||
console.log('zones: ', zones);
|
||||
return zones.some(
|
||||
(zone: any) =>
|
||||
zone.zoneName?.trim().toLowerCase() === name?.trim().toLowerCase() &&
|
||||
|
||||
@@ -8,6 +8,7 @@ import VehicleMechanics from "./mechanics/vehicleMechanics";
|
||||
import RoboticArmMechanics from "./mechanics/roboticArmMechanics";
|
||||
import MachineMechanics from "./mechanics/machineMechanics";
|
||||
import StorageMechanics from "./mechanics/storageMechanics";
|
||||
import HumanMechanics from "./mechanics/humanMechanics";
|
||||
import { AddIcon } from "../../../../icons/ExportCommonIcons";
|
||||
import { handleAddEventToProduct } from "../../../../../modules/simulation/events/points/functions/handleAddEventToProduct";
|
||||
import { useProductContext } from "../../../../../modules/simulation/products/productContext";
|
||||
@@ -60,6 +61,8 @@ const EventProperties: React.FC = () => {
|
||||
return "machine";
|
||||
case "storageUnit":
|
||||
return "storageUnit";
|
||||
case "human":
|
||||
return "human";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -79,6 +82,7 @@ const EventProperties: React.FC = () => {
|
||||
{assetType === "roboticArm" && <RoboticArmMechanics />}
|
||||
{assetType === "machine" && <MachineMechanics />}
|
||||
{assetType === "storageUnit" && <StorageMechanics />}
|
||||
{assetType === "human" && <HumanMechanics />}
|
||||
</>
|
||||
)}
|
||||
{!currentEventData && selectedEventSphere && (
|
||||
|
||||
@@ -1,95 +1,70 @@
|
||||
import React from "react";
|
||||
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
|
||||
import EyeDropInput from "../../../../../ui/inputs/EyeDropInput";
|
||||
|
||||
interface TravelActionProps {
|
||||
loadCapacity: {
|
||||
value: string;
|
||||
min: number;
|
||||
max: number;
|
||||
defaultValue: string;
|
||||
onChange: (value: string) => void;
|
||||
};
|
||||
unloadDuration: {
|
||||
value: string;
|
||||
min: number;
|
||||
max: number;
|
||||
defaultValue: string;
|
||||
onChange: (value: string) => void;
|
||||
};
|
||||
pickPoint?: {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
};
|
||||
unloadPoint?: {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
};
|
||||
clearPoints: () => void;
|
||||
loadCapacity: {
|
||||
value: string;
|
||||
min: number;
|
||||
max: number;
|
||||
defaultValue: string;
|
||||
onChange: (value: string) => void;
|
||||
};
|
||||
unloadDuration: {
|
||||
value: string;
|
||||
min: number;
|
||||
max: number;
|
||||
defaultValue: string;
|
||||
onChange: (value: string) => void;
|
||||
};
|
||||
clearPoints: () => void;
|
||||
}
|
||||
|
||||
const TravelAction: React.FC<TravelActionProps> = ({
|
||||
loadCapacity,
|
||||
unloadDuration,
|
||||
pickPoint,
|
||||
unloadPoint,
|
||||
clearPoints,
|
||||
loadCapacity,
|
||||
unloadDuration,
|
||||
clearPoints,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<InputWithDropDown
|
||||
label="Load Capacity"
|
||||
value={loadCapacity.value}
|
||||
min={loadCapacity.min}
|
||||
max={loadCapacity.max}
|
||||
defaultValue={loadCapacity.defaultValue}
|
||||
step={1}
|
||||
activeOption="s"
|
||||
onClick={() => {}}
|
||||
onChange={loadCapacity.onChange}
|
||||
/>
|
||||
<InputWithDropDown
|
||||
label="Unload Duration"
|
||||
value={unloadDuration.value}
|
||||
min={unloadDuration.min}
|
||||
max={unloadDuration.max}
|
||||
defaultValue={unloadDuration.defaultValue}
|
||||
step={0.1}
|
||||
activeOption="s"
|
||||
onClick={() => {}}
|
||||
onChange={unloadDuration.onChange}
|
||||
/>
|
||||
<div className="selected-actions-list">
|
||||
<div className="value-field-container">
|
||||
<div className="label">Reset</div>
|
||||
<button
|
||||
id="rest-button"
|
||||
type="button"
|
||||
className="regularDropdown-container"
|
||||
onClick={() => {
|
||||
clearPoints();
|
||||
}}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{pickPoint && (
|
||||
<EyeDropInput
|
||||
label="Pick Point"
|
||||
value={pickPoint.value}
|
||||
onChange={pickPoint.onChange}
|
||||
/>
|
||||
)}
|
||||
{unloadPoint && (
|
||||
<EyeDropInput
|
||||
label="Unload Point"
|
||||
value={unloadPoint.value}
|
||||
onChange={unloadPoint.onChange}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<InputWithDropDown
|
||||
label="Load Capacity"
|
||||
value={loadCapacity.value}
|
||||
min={loadCapacity.min}
|
||||
max={loadCapacity.max}
|
||||
defaultValue={loadCapacity.defaultValue}
|
||||
step={1}
|
||||
activeOption="unit"
|
||||
onClick={() => { }}
|
||||
onChange={loadCapacity.onChange}
|
||||
/>
|
||||
<InputWithDropDown
|
||||
label="Unload Duration"
|
||||
value={unloadDuration.value}
|
||||
min={unloadDuration.min}
|
||||
max={unloadDuration.max}
|
||||
defaultValue={unloadDuration.defaultValue}
|
||||
step={0.1}
|
||||
activeOption="s"
|
||||
onClick={() => { }}
|
||||
onChange={unloadDuration.onChange}
|
||||
/>
|
||||
<div className="selected-actions-list">
|
||||
<div className="value-field-container">
|
||||
<div className="label">Reset</div>
|
||||
<button
|
||||
id="rest-button"
|
||||
type="button"
|
||||
className="regularDropdown-container"
|
||||
onClick={() => {
|
||||
clearPoints();
|
||||
}}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default TravelAction;
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import React from "react";
|
||||
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
|
||||
|
||||
interface WorkerActionProps {
|
||||
loadCapacity: {
|
||||
value: string;
|
||||
min: number;
|
||||
max: number;
|
||||
step: number;
|
||||
defaultValue: string;
|
||||
disabled?: boolean,
|
||||
onChange: (value: string) => void;
|
||||
};
|
||||
clearPoints: () => void;
|
||||
}
|
||||
|
||||
const WorkerAction: React.FC<WorkerActionProps> = ({
|
||||
loadCapacity,
|
||||
clearPoints,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<InputWithDropDown
|
||||
label="Load Capacity"
|
||||
value={loadCapacity.value}
|
||||
min={loadCapacity.min}
|
||||
max={loadCapacity.max}
|
||||
disabled={loadCapacity.disabled}
|
||||
defaultValue={loadCapacity.defaultValue}
|
||||
step={loadCapacity.step}
|
||||
activeOption="unit"
|
||||
onClick={() => { }}
|
||||
onChange={loadCapacity.onChange}
|
||||
/>
|
||||
<div className="selected-actions-list">
|
||||
<div className="value-field-container">
|
||||
<div className="label">Reset</div>
|
||||
<button
|
||||
id="rest-button"
|
||||
type="button"
|
||||
className="regularDropdown-container"
|
||||
onClick={() => {
|
||||
clearPoints();
|
||||
}}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default WorkerAction;
|
||||
@@ -0,0 +1,292 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { MathUtils } from "three";
|
||||
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
|
||||
import RenameInput from "../../../../../ui/inputs/RenameInput";
|
||||
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
|
||||
import Trigger from "../trigger/Trigger";
|
||||
import ActionsList from "../components/ActionsList";
|
||||
import { useSelectedEventData, useSelectedAction, useSelectedAnimation } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
|
||||
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
|
||||
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import WorkerAction from "../actions/workerAction";
|
||||
|
||||
function HumanMechanics() {
|
||||
const [activeOption, setActiveOption] = useState<"worker">("worker");
|
||||
const [speed, setSpeed] = useState("0.5");
|
||||
const [loadCapacity, setLoadCapacity] = useState("1");
|
||||
const [currentAction, setCurrentAction] = useState<HumanAction | undefined>();
|
||||
const [selectedPointData, setSelectedPointData] = useState<HumanPointSchema | undefined>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { productStore } = useSceneContext();
|
||||
const { getPointByUuid, updateEvent, updateAction, addAction, removeAction, getEventByModelUuid } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData && selectedEventData.data.type === "human") {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint
|
||||
) as HumanPointSchema | undefined;
|
||||
|
||||
if (point?.action) {
|
||||
setSelectedPointData(point);
|
||||
setCurrentAction(point.action);
|
||||
setSelectedAction(point.action.actionUuid, point.action.actionName);
|
||||
setSpeed((
|
||||
getEventByModelUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData?.data.modelUuid || ""
|
||||
) as HumanEventSchema | undefined
|
||||
)?.speed?.toString() || "1");
|
||||
setLoadCapacity(point.action.loadCapacity.toString());
|
||||
}
|
||||
} else {
|
||||
clearSelectedAction();
|
||||
}
|
||||
}, [selectedEventData, selectedProduct]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData && selectedProduct.productUuid) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint
|
||||
) as HumanPointSchema | undefined;
|
||||
|
||||
if (point?.action) {
|
||||
setSelectedPointData(point);
|
||||
setCurrentAction(point.action);
|
||||
setActiveOption(point.action.actionType);
|
||||
setSelectedAction(point.action.actionUuid, point.action.actionName);
|
||||
}
|
||||
} else {
|
||||
clearSelectedAction();
|
||||
setCurrentAction(undefined);
|
||||
setSpeed("0.5");
|
||||
setLoadCapacity("1");
|
||||
}
|
||||
}, [selectedEventData, selectedProduct, selectedAction]);
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
projectId: string,
|
||||
eventData: EventsSchema
|
||||
) => {
|
||||
upsertProductOrEventApi({
|
||||
productName,
|
||||
productUuid,
|
||||
projectId,
|
||||
eventDatas: eventData,
|
||||
versionId: selectedVersion?.versionId || "",
|
||||
});
|
||||
};
|
||||
|
||||
const handleSelectActionType = (actionType: string) => {
|
||||
if (!selectedAction.actionId || !currentAction || !selectedPointData) return;
|
||||
|
||||
const updatedAction = { ...currentAction, actionType: actionType as "worker" };
|
||||
const updatedPoint = { ...selectedPointData, action: updatedAction };
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
updatedAction
|
||||
);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
}
|
||||
|
||||
setCurrentAction(updatedAction);
|
||||
setSelectedPointData(updatedPoint);
|
||||
};
|
||||
|
||||
const handleSpeedChange = (value: string) => {
|
||||
if (!selectedEventData) return;
|
||||
|
||||
const numericValue = parseFloat(value);
|
||||
if (isNaN(numericValue)) return;
|
||||
|
||||
const updatedEvent = {
|
||||
...selectedEventData.data,
|
||||
speed: numericValue
|
||||
} as HumanEventSchema;
|
||||
|
||||
const event = updateEvent(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
updatedEvent
|
||||
);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
}
|
||||
|
||||
setSpeed(value);
|
||||
};
|
||||
|
||||
const handleLoadCapacityChange = (value: string) => {
|
||||
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
|
||||
|
||||
const updatedAction = { ...currentAction };
|
||||
updatedAction.loadCapacity = parseInt(value)
|
||||
|
||||
const updatedPoint = { ...selectedPointData, action: updatedAction };
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
updatedAction
|
||||
);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
}
|
||||
|
||||
setCurrentAction(updatedAction);
|
||||
setSelectedPointData(updatedPoint);
|
||||
setLoadCapacity(value);
|
||||
};
|
||||
|
||||
const handleClearPoints = () => {
|
||||
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
|
||||
|
||||
const updatedAction = { ...currentAction };
|
||||
delete updatedAction.pickUpPoint;
|
||||
delete updatedAction.dropPoint;
|
||||
|
||||
const updatedPoint = { ...selectedPointData, action: updatedAction };
|
||||
|
||||
const event = updateAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedAction.actionId,
|
||||
updatedAction
|
||||
);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
}
|
||||
|
||||
setCurrentAction(updatedAction);
|
||||
setSelectedPointData(updatedPoint);
|
||||
};
|
||||
|
||||
const handleAddAction = () => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
|
||||
const newAction: HumanAction = {
|
||||
actionUuid: MathUtils.generateUUID(),
|
||||
actionName: `Action`,
|
||||
actionType: "worker",
|
||||
loadCapacity: 1,
|
||||
triggers: [],
|
||||
};
|
||||
|
||||
const event = addAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint,
|
||||
newAction
|
||||
);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
}
|
||||
|
||||
const updatedPoint = { ...selectedPointData, action: newAction };
|
||||
setSelectedPointData(updatedPoint);
|
||||
setSelectedAction(newAction.actionUuid, newAction.actionName);
|
||||
};
|
||||
|
||||
const handleDeleteAction = () => {
|
||||
if (!selectedPointData) return;
|
||||
|
||||
const event = removeAction(
|
||||
selectedProduct.productUuid,
|
||||
selectedPointData.action.actionUuid
|
||||
);
|
||||
|
||||
if (event) {
|
||||
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||
}
|
||||
|
||||
const updatedPoint = { ...selectedPointData, action: undefined as any };
|
||||
setSelectedPointData(updatedPoint);
|
||||
clearSelectedAction();
|
||||
setCurrentAction(undefined);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="global-props section">
|
||||
<div className="property-list-container">
|
||||
<div className="property-item">
|
||||
<InputWithDropDown
|
||||
label="Speed"
|
||||
value={speed}
|
||||
min={0}
|
||||
step={0.1}
|
||||
defaultValue="0.5"
|
||||
max={10}
|
||||
activeOption="m/s"
|
||||
onClick={() => { }}
|
||||
onChange={handleSpeedChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<section>
|
||||
<ActionsList
|
||||
selectedPointData={selectedPointData}
|
||||
multipleAction={false}
|
||||
handleAddAction={handleAddAction}
|
||||
handleDeleteAction={handleDeleteAction}
|
||||
/>
|
||||
|
||||
{selectedAction.actionId && currentAction && (
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput value={selectedAction.actionName || ""} canEdit={false} />
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
label="Action Type"
|
||||
defaultOption={activeOption}
|
||||
options={["worker"]}
|
||||
onSelect={handleSelectActionType}
|
||||
disabled={true}
|
||||
/>
|
||||
</div>
|
||||
<WorkerAction
|
||||
loadCapacity={{
|
||||
value: loadCapacity,
|
||||
min: 1,
|
||||
max: 5,
|
||||
step: 1,
|
||||
defaultValue: "1",
|
||||
disabled: true,
|
||||
onChange: handleLoadCapacityChange,
|
||||
}}
|
||||
clearPoints={handleClearPoints}
|
||||
/>
|
||||
<div className="tirgger">
|
||||
<Trigger selectedPointData={selectedPointData as any} type="Human" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default HumanMechanics;
|
||||
@@ -274,14 +274,6 @@ function VehicleMechanics() {
|
||||
onChange: handleUnloadDurationChange,
|
||||
}}
|
||||
clearPoints={handleClearPoints}
|
||||
// pickPoint={{
|
||||
// value: currentPickPoint,
|
||||
// onChange: handlePickPointChange,
|
||||
// }}
|
||||
// unloadPoint={{
|
||||
// value: currentUnloadPoint,
|
||||
// onChange: handleUnloadPointChange,
|
||||
// }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@ import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||
|
||||
type TriggerProps = {
|
||||
selectedPointData?: PointsScheme | undefined;
|
||||
type?: "Conveyor" | "Vehicle" | "RoboticArm" | "Machine" | "StorageUnit";
|
||||
type?: "Conveyor" | "Vehicle" | "RoboticArm" | "Machine" | "StorageUnit" | "Human";
|
||||
};
|
||||
|
||||
const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
@@ -38,7 +38,7 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
|
||||
if (type === "Conveyor" || type === "Vehicle" || type === "Machine" || type === "StorageUnit") {
|
||||
actionUuid = (selectedPointData as | ConveyorPointSchema | VehiclePointSchema | MachinePointSchema | StoragePointSchema).action?.actionUuid;
|
||||
} else if (type === "RoboticArm" && selectedAction.actionId) {
|
||||
} else if ((type === "RoboticArm" || type === "Human") && selectedAction.actionId) {
|
||||
actionUuid = selectedAction.actionId;
|
||||
}
|
||||
|
||||
@@ -365,18 +365,16 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||
}
|
||||
/>
|
||||
</button>
|
||||
{triggers.length > 1 && (
|
||||
<button
|
||||
id="remove-trigger-button"
|
||||
className="remove-button"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleRemoveTrigger(trigger.triggerUuid);
|
||||
}}
|
||||
>
|
||||
<RemoveIcon />
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
id="remove-trigger-button"
|
||||
className="remove-button"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleRemoveTrigger(trigger.triggerUuid);
|
||||
}}
|
||||
>
|
||||
<RemoveIcon />
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -28,9 +28,9 @@ const VersionHistory = () => {
|
||||
const handleSelectVersion = (version: Version) => {
|
||||
if (!projectId) return;
|
||||
|
||||
getVersionDataApi(projectId, version.versionId).then((verdionData) => {
|
||||
getVersionDataApi(projectId, version.versionId).then((versionData) => {
|
||||
setSelectedVersion(version);
|
||||
// console.log(verdionData);
|
||||
// console.log(versionData);
|
||||
}).catch((err) => {
|
||||
// console.log(err);
|
||||
})
|
||||
|
||||
@@ -8,6 +8,7 @@ type InputWithDropDownProps = {
|
||||
max?: number;
|
||||
step?: number;
|
||||
defaultValue?: string;
|
||||
disabled?: boolean;
|
||||
options?: string[]; // Array of dropdown options
|
||||
activeOption?: string; // The currently active dropdown option
|
||||
onClick?: () => void;
|
||||
@@ -23,6 +24,7 @@ const InputWithDropDown: React.FC<InputWithDropDownProps> = ({
|
||||
max,
|
||||
step,
|
||||
defaultValue,
|
||||
disabled = false,
|
||||
options,
|
||||
activeOption,
|
||||
onClick,
|
||||
@@ -54,6 +56,7 @@ const InputWithDropDown: React.FC<InputWithDropDownProps> = ({
|
||||
type="number"
|
||||
defaultValue={value}
|
||||
// value={value}
|
||||
disabled={disabled}
|
||||
onChange={(e) => {
|
||||
onChange(e.target.value);
|
||||
}}
|
||||
|
||||
@@ -9,9 +9,10 @@ interface RenameInputProps {
|
||||
value: string;
|
||||
onRename?: (newText: string) => void;
|
||||
checkDuplicate?: (name: string) => boolean;
|
||||
canEdit?: boolean;
|
||||
}
|
||||
|
||||
const RenameInput: React.FC<RenameInputProps> = ({ value, onRename, checkDuplicate }) => {
|
||||
const RenameInput: React.FC<RenameInputProps> = ({ value, onRename, checkDuplicate, canEdit = true }) => {
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
const [text, setText] = useState(value);
|
||||
const [isDuplicate, setIsDuplicate] = useState(false);
|
||||
@@ -28,13 +29,15 @@ const RenameInput: React.FC<RenameInputProps> = ({ value, onRename, checkDuplica
|
||||
}, [text, checkDuplicate]);
|
||||
|
||||
const handleDoubleClick = () => {
|
||||
setIsEditing(true);
|
||||
setTimeout(() => inputRef.current?.focus(), 0);
|
||||
if (canEdit) {
|
||||
setIsEditing(true);
|
||||
setTimeout(() => inputRef.current?.focus(), 0);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBlur = () => {
|
||||
|
||||
if(isDuplicate) return
|
||||
|
||||
if (isDuplicate) return
|
||||
setIsEditing(false);
|
||||
if (onRename && !isDuplicate) {
|
||||
onRename(text);
|
||||
|
||||
@@ -44,16 +44,19 @@ const DropDownList: React.FC<DropDownListProps> = ({
|
||||
remove,
|
||||
}) => {
|
||||
const [isOpen, setIsOpen] = useState<boolean>(defaultOpen);
|
||||
const { zones } = useZones();
|
||||
// const { zones } = useZones();
|
||||
|
||||
const handleToggle = () => {
|
||||
setIsOpen((prev) => !prev); // Toggle the state
|
||||
};
|
||||
|
||||
const [zoneDataList, setZoneDataList] = useState<ZoneData[]>([]);
|
||||
const { assetStore } = useSceneContext();
|
||||
// const { assetStore } = useSceneContext();
|
||||
const { assetStore, zoneStore } = useSceneContext();
|
||||
const { assets } = assetStore();
|
||||
|
||||
const { zones } = zoneStore()
|
||||
|
||||
|
||||
const isPointInsidePolygon = (
|
||||
point: [number, number],
|
||||
polygon: [number, number][]
|
||||
@@ -76,7 +79,7 @@ const DropDownList: React.FC<DropDownListProps> = ({
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const updatedZoneList: ZoneData[] = zones?.map((zone: Zone) => {
|
||||
const updatedZoneList: ZoneData[] = zones?.map((zone: any) => {
|
||||
const polygon2D = zone.points.map((p: [number, number, number]) => [
|
||||
p[0],
|
||||
p[2],
|
||||
|
||||
@@ -46,7 +46,7 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
||||
const { activeModule } = useModuleStore();
|
||||
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||
const { zoneAssetId, setZoneAssetId } = useZoneAssetId();
|
||||
const { zones, setZones } = useZones();
|
||||
|
||||
const { setSubModule } = useSubModuleStore();
|
||||
const [expandedZones, setExpandedZones] = useState<Record<string, boolean>>({});
|
||||
const { projectId } = useParams();
|
||||
@@ -55,6 +55,8 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
||||
const { organization } = getUserData();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { zoneStore } = useSceneContext();
|
||||
const { zones, setZoneName } = zoneStore()
|
||||
|
||||
useEffect(() => {
|
||||
useSelectedZoneStore.getState().setSelectedZone({
|
||||
@@ -92,8 +94,8 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
||||
lockedPanels: response?.lockedPanels ?? [],
|
||||
widgets: response?.widgets ?? [],
|
||||
zoneUuid: response?.zoneUuid,
|
||||
zoneViewPortTarget: response?.viewPortCenter ?? [],
|
||||
zoneViewPortPosition: response?.viewPortposition ?? [],
|
||||
zoneViewPortTarget: response?.viewPortTarget ?? [],
|
||||
zoneViewPortPosition: response?.viewPortPosition ?? [],
|
||||
});
|
||||
} catch (error) {
|
||||
echo.error("Failed to select zone");
|
||||
@@ -123,13 +125,14 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
||||
const response = await zoneCameraUpdate(zonesdata, organization, projectId, selectedVersion?.versionId || "");
|
||||
if (response.message === "zone updated") {
|
||||
setSelectedZone((prev) => ({ ...prev, zoneName: newName }));
|
||||
setZones((prevZones: any[]) =>
|
||||
prevZones.map((zone) =>
|
||||
zone.zoneUuid === selectedZone.zoneUuid
|
||||
? { ...zone, zoneName: newName }
|
||||
: zone
|
||||
)
|
||||
);
|
||||
setZoneName(selectedZone.zoneUuid, newName)
|
||||
// setZones((prevZones: any[]) =>
|
||||
// prevZones.map((zone) =>
|
||||
// zone.zoneUuid === selectedZone.zoneUuid
|
||||
// ? { ...zone, zoneName: newName }
|
||||
// : zone
|
||||
// )
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user