Merge remote-tracking branch 'origin/v2-ui' into v2

This commit is contained in:
Jerald-Golden-B 2025-05-10 16:27:15 +05:30
commit e16a0a6d8b
10 changed files with 704 additions and 601 deletions
app/src
components
layout/sidebarRight/properties/eventProperties
ui
modules/simulation
spatialUI
storageUnit/instances/animator
styles/layout

View File

@ -1,25 +1,28 @@
import React from "react"; import React from "react";
import EyeDropInput from "../../../../../ui/inputs/EyeDropInput";
interface PickAndPlaceActionProps { interface PickAndPlaceActionProps {
pickPointValue: string; clearPoints: () => void;
pickPointOnChange: (value: string) => void;
placePointValue: string;
placePointOnChange: (value: string) => void;
} }
const PickAndPlaceAction: React.FC<PickAndPlaceActionProps> = ({ const PickAndPlaceAction: React.FC<PickAndPlaceActionProps> = ({
pickPointValue, clearPoints,
pickPointOnChange,
placePointValue,
placePointOnChange,
}) => { }) => {
return ( return (
<> <div className="selected-actions-list">
<EyeDropInput label="Pick Point" value={pickPointValue} onChange={pickPointOnChange} /> <div className="value-field-container">
<EyeDropInput label="Unload Point" value={placePointValue} onChange={placePointOnChange} /> <div className="label">Reset</div>
</> <button
); type="button"
className="regularDropdown-container"
onClick={() => {
clearPoints();
}}
>
Clear
</button>
</div>
</div>
);
}; };
export default PickAndPlaceAction; export default PickAndPlaceAction;

View File

@ -3,76 +3,92 @@ import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
import EyeDropInput from "../../../../../ui/inputs/EyeDropInput"; import EyeDropInput from "../../../../../ui/inputs/EyeDropInput";
interface TravelActionProps { interface TravelActionProps {
loadCapacity: { loadCapacity: {
value: string; value: string;
min: number; min: number;
max: number; max: number;
defaultValue: string; defaultValue: string;
onChange: (value: string) => void; onChange: (value: string) => void;
}; };
unloadDuration: { unloadDuration: {
value: string; value: string;
min: number; min: number;
max: number; max: number;
defaultValue: string; defaultValue: string;
onChange: (value: string) => void; onChange: (value: string) => void;
}; };
pickPoint?: { pickPoint?: {
value: string; value: string;
onChange: (value: string) => void; onChange: (value: string) => void;
}; };
unloadPoint?: { unloadPoint?: {
value: string; value: string;
onChange: (value: string) => void; onChange: (value: string) => void;
}; };
clearPoints: () => void;
} }
const TravelAction: React.FC<TravelActionProps> = ({ const TravelAction: React.FC<TravelActionProps> = ({
loadCapacity, loadCapacity,
unloadDuration, unloadDuration,
pickPoint, pickPoint,
unloadPoint, unloadPoint,
clearPoints,
}) => { }) => {
return ( return (
<> <>
<InputWithDropDown <InputWithDropDown
label="Load Capacity" label="Load Capacity"
value={loadCapacity.value} value={loadCapacity.value}
min={loadCapacity.min} min={loadCapacity.min}
max={loadCapacity.max} max={loadCapacity.max}
defaultValue={loadCapacity.defaultValue} defaultValue={loadCapacity.defaultValue}
step={0.1} step={1}
activeOption="s" activeOption="s"
onClick={() => { }} onClick={() => {}}
onChange={loadCapacity.onChange} onChange={loadCapacity.onChange}
/> />
<InputWithDropDown <InputWithDropDown
label="Unload Duration" label="Unload Duration"
value={unloadDuration.value} value={unloadDuration.value}
min={unloadDuration.min} min={unloadDuration.min}
max={unloadDuration.max} max={unloadDuration.max}
defaultValue={unloadDuration.defaultValue} defaultValue={unloadDuration.defaultValue}
step={0.1} step={0.1}
activeOption="s" activeOption="s"
onClick={() => { }} onClick={() => {}}
onChange={unloadDuration.onChange} onChange={unloadDuration.onChange}
/> />
{pickPoint && ( <div className="selected-actions-list">
<EyeDropInput <div className="value-field-container">
label="Pick Point" <div className="label">Reset</div>
value={pickPoint.value} <button
onChange={pickPoint.onChange} type="button"
/> className="regularDropdown-container"
)} onClick={() => {
{unloadPoint && ( clearPoints();
<EyeDropInput }}
label="Unload Point" >
value={unloadPoint.value} Clear
onChange={unloadPoint.onChange} </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}
/>
)}
</>
);
}; };
export default TravelAction; export default TravelAction;

View File

@ -4,286 +4,304 @@ import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
import RenameInput from "../../../../../ui/inputs/RenameInput"; import RenameInput from "../../../../../ui/inputs/RenameInput";
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown"; import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import Trigger from "../trigger/Trigger"; import Trigger from "../trigger/Trigger";
import { useSelectedEventData, useSelectedProduct, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore"; import {
useSelectedEventData,
useSelectedProduct,
useSelectedAction,
} from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import PickAndPlaceAction from "../actions/PickAndPlaceAction"; import PickAndPlaceAction from "../actions/PickAndPlaceAction";
import ActionsList from "../components/ActionsList"; import ActionsList from "../components/ActionsList";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/UpsertProductOrEventApi"; import { upsertProductOrEventApi } from "../../../../../../services/simulation/UpsertProductOrEventApi";
function RoboticArmMechanics() { function RoboticArmMechanics() {
const [activeOption, setActiveOption] = useState<"default" | "pickAndPlace">("default"); const [activeOption, setActiveOption] = useState<"default" | "pickAndPlace">(
const [selectedPointData, setSelectedPointData] = useState<RoboticArmPointSchema | undefined>(); "default"
const { selectedEventData } = useSelectedEventData(); );
const { getPointByUuid, getEventByModelUuid, getActionByUuid, updateEvent, updateAction, addAction, removeAction } = useProductStore(); const [selectedPointData, setSelectedPointData] = useState<
const { selectedProduct } = useSelectedProduct(); RoboticArmPointSchema | undefined
const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction(); >();
const { selectedEventData } = useSelectedEventData();
const {
getPointByUuid,
getEventByModelUuid,
updateEvent,
updateAction,
addAction,
removeAction,
} = useProductStore();
const { selectedProduct } = useSelectedProduct();
const { selectedAction, setSelectedAction, clearSelectedAction } =
useSelectedAction();
const email = localStorage.getItem('email') const email = localStorage.getItem("email");
const organization = (email!.split("@")[1]).split(".")[0]; const organization = email!.split("@")[1].split(".")[0];
useEffect(() => { useEffect(() => {
if (selectedEventData) { if (selectedEventData) {
const point = getPointByUuid( const point = getPointByUuid(
selectedProduct.productId, selectedProduct.productId,
selectedEventData.data.modelUuid, selectedEventData.data.modelUuid,
selectedEventData.selectedPoint selectedEventData.selectedPoint
) as RoboticArmPointSchema | undefined; ) as RoboticArmPointSchema | undefined;
if (point?.actions) { if (point?.actions) {
setSelectedPointData(point); setSelectedPointData(point);
if (point.actions.length > 0) { if (point.actions.length > 0) {
setActiveOption(point.actions[0].actionType as "default" | "pickAndPlace"); setActiveOption(
setSelectedAction(point.actions[0].actionUuid, point.actions[0].actionName); point.actions[0].actionType as "default" | "pickAndPlace"
} );
} setSelectedAction(
} else { point.actions[0].actionUuid,
clearSelectedAction(); point.actions[0].actionName
);
} }
}, [selectedEventData, selectedProduct]); }
} else {
clearSelectedAction();
}
}, [selectedEventData, selectedProduct]);
const updateBackend = ( const updateBackend = (
productName: string, productName: string,
productId: string, productId: string,
organization: string, organization: string,
eventData: EventsSchema eventData: EventsSchema
) => { ) => {
upsertProductOrEventApi({ upsertProductOrEventApi({
productName: productName, productName: productName,
productId: productId, productId: productId,
organization: organization, organization: organization,
eventDatas: eventData eventDatas: eventData,
}) });
};
const handleRenameAction = (newName: string) => {
if (!selectedAction.actionId) return;
const event = updateAction(
selectedProduct.productId,
selectedAction.actionId,
{ actionName: newName }
);
if (selectedPointData) {
const updatedActions = selectedPointData.actions.map((action) =>
action.actionUuid === selectedAction.actionId
? { ...action, actionName: newName }
: action
);
setSelectedPointData({
...selectedPointData,
actions: updatedActions,
});
} }
const handleRenameAction = (newName: string) => { if (event) {
if (!selectedAction.actionId) return; updateBackend(
const event = updateAction(selectedProduct.productId, selectedAction.actionId, { actionName: newName }); selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
if (selectedPointData) { const handleSpeedChange = (value: string) => {
const updatedActions = selectedPointData.actions.map((action) => if (!selectedEventData) return;
action.actionUuid === selectedAction.actionId ? { ...action, actionName: newName } : action const event = updateEvent(
); selectedProduct.productId,
setSelectedPointData({ selectedEventData.data.modelUuid,
...selectedPointData, {
actions: updatedActions, speed: parseFloat(value),
}); }
}
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handleSpeedChange = (value: string) => {
if (!selectedEventData) return;
const event = updateEvent(selectedProduct.productId, selectedEventData.data.modelUuid, {
speed: parseFloat(value),
});
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handlePickPointChange = (value: string) => {
if (!selectedAction.actionId || !selectedPointData) return;
const [x, y, z] = value.split(",").map(Number);
const event = updateAction(selectedProduct.productId, selectedAction.actionId, {
process: {
startPoint: [x, y, z] as [number, number, number],
endPoint: selectedPointData.actions.find((a) => a.actionUuid === selectedAction.actionId)?.process.endPoint || null,
},
});
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handlePlacePointChange = (value: string) => {
if (!selectedAction.actionId || !selectedPointData) return;
const [x, y, z] = value.split(",").map(Number);
const event = updateAction(selectedProduct.productId, selectedAction.actionId, {
process: {
startPoint: selectedPointData.actions.find((a) => a.actionUuid === selectedAction.actionId)?.process.startPoint || null,
endPoint: [x, y, z] as [number, number, number],
},
});
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handleAddAction = () => {
if (!selectedEventData || !selectedPointData) return;
const newAction = {
actionUuid: MathUtils.generateUUID(),
actionName: `Action ${selectedPointData.actions.length + 1}`,
actionType: "pickAndPlace" as const,
process: {
startPoint: null,
endPoint: null,
},
triggers: [] as TriggerSchema[],
};
const event = addAction(
selectedProduct.productId,
selectedEventData.data.modelUuid,
selectedEventData.selectedPoint,
newAction
);
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
const updatedPoint = {
...selectedPointData,
actions: [...selectedPointData.actions, newAction],
};
setSelectedPointData(updatedPoint);
setSelectedAction(newAction.actionUuid, newAction.actionName);
};
const handleDeleteAction = (actionUuid: string) => {
if (!selectedPointData) return;
const event = removeAction(selectedProduct.productId, actionUuid);
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
const index = selectedPointData.actions.findIndex(a => a.actionUuid === actionUuid);
const newActions = selectedPointData.actions.filter(a => a.actionUuid !== actionUuid);
const updatedPoint = {
...selectedPointData,
actions: newActions,
};
setSelectedPointData(updatedPoint);
if (selectedAction.actionId === actionUuid) {
const nextAction = newActions[index] || newActions[index - 1];
if (nextAction) {
setSelectedAction(nextAction.actionUuid, nextAction.actionName);
} else {
clearSelectedAction();
}
}
};
const availableActions = {
defaultOption: "pickAndPlace",
options: ["pickAndPlace"],
};
const currentSpeed = (getEventByModelUuid(
selectedProduct.productId, selectedEventData?.data.modelUuid || ""
) as RoboticArmEventSchema | undefined)?.speed?.toString() || "0.5";
const currentAction = selectedPointData?.actions.find((a) => a.actionUuid === selectedAction.actionId);
const currentPickPoint = currentAction?.process.startPoint
? `${currentAction.process.startPoint[0]},${currentAction.process.startPoint[1]},${currentAction.process.startPoint[2]}`
: "";
const currentPlacePoint = currentAction?.process.endPoint
? `${currentAction.process.endPoint[0]},${currentAction.process.endPoint[1]},${currentAction.process.endPoint[2]}`
: "";
return (
<>
<div className="global-props section">
<div className="property-list-container">
<div className="property-item">
<InputWithDropDown
label="Speed"
value={currentSpeed}
min={0}
step={0.1}
defaultValue={"0.5"}
max={10}
activeOption="m/s"
onClick={() => { }}
onChange={handleSpeedChange}
/>
</div>
</div>
</div>
<section>
<ActionsList
selectedPointData={selectedPointData}
multipleAction
handleAddAction={handleAddAction}
handleDeleteAction={handleDeleteAction}
/>
{selectedAction.actionId && currentAction && (
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput
value={selectedAction.actionName || ''}
onRename={handleRenameAction}
/>
</div>
<div className="selected-actions-list">
<LabledDropdown
defaultOption={activeOption}
options={availableActions.options}
onSelect={() => { }}
disabled={true}
/>
<PickAndPlaceAction
pickPointValue={currentPickPoint}
pickPointOnChange={handlePickPointChange}
placePointValue={currentPlacePoint}
placePointOnChange={handlePlacePointChange}
/>
</div>
<div className="tirgger">
<Trigger selectedPointData={selectedPointData as any} type={'RoboticArm'} />
</div>
</div>
)}
</section>
</>
); );
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handleClearPoints = () => {
if (!selectedAction.actionId || !selectedPointData) return;
const event = updateAction(
selectedProduct.productId,
selectedAction.actionId,
{
process: {
startPoint: null,
endPoint: null,
},
}
);
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handleAddAction = () => {
if (!selectedEventData || !selectedPointData) return;
const newAction = {
actionUuid: MathUtils.generateUUID(),
actionName: `Action ${selectedPointData.actions.length + 1}`,
actionType: "pickAndPlace" as const,
process: {
startPoint: null,
endPoint: null,
},
triggers: [] as TriggerSchema[],
};
const event = addAction(
selectedProduct.productId,
selectedEventData.data.modelUuid,
selectedEventData.selectedPoint,
newAction
);
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
const updatedPoint = {
...selectedPointData,
actions: [...selectedPointData.actions, newAction],
};
setSelectedPointData(updatedPoint);
setSelectedAction(newAction.actionUuid, newAction.actionName);
};
const handleDeleteAction = (actionUuid: string) => {
if (!selectedPointData) return;
const event = removeAction(selectedProduct.productId, actionUuid);
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
const index = selectedPointData.actions.findIndex(
(a) => a.actionUuid === actionUuid
);
const newActions = selectedPointData.actions.filter(
(a) => a.actionUuid !== actionUuid
);
const updatedPoint = {
...selectedPointData,
actions: newActions,
};
setSelectedPointData(updatedPoint);
if (selectedAction.actionId === actionUuid) {
const nextAction = newActions[index] || newActions[index - 1];
if (nextAction) {
setSelectedAction(nextAction.actionUuid, nextAction.actionName);
} else {
clearSelectedAction();
}
}
};
const availableActions = {
defaultOption: "pickAndPlace",
options: ["pickAndPlace"],
};
const currentSpeed =
(
getEventByModelUuid(
selectedProduct.productId,
selectedEventData?.data.modelUuid || ""
) as RoboticArmEventSchema | undefined
)?.speed?.toString() || "0.5";
const currentAction = selectedPointData?.actions.find(
(a) => a.actionUuid === selectedAction.actionId
);
const currentPickPoint = currentAction?.process.startPoint
? `${currentAction.process.startPoint[0]},${currentAction.process.startPoint[1]},${currentAction.process.startPoint[2]}`
: "";
const currentPlacePoint = currentAction?.process.endPoint
? `${currentAction.process.endPoint[0]},${currentAction.process.endPoint[1]},${currentAction.process.endPoint[2]}`
: "";
return (
<>
<div className="global-props section">
<div className="property-list-container">
<div className="property-item">
<InputWithDropDown
label="Speed"
value={currentSpeed}
min={0}
step={0.1}
defaultValue={"0.5"}
max={10}
activeOption="m/s"
onClick={() => {}}
onChange={handleSpeedChange}
/>
</div>
</div>
</div>
<section>
<ActionsList
selectedPointData={selectedPointData}
multipleAction
handleAddAction={handleAddAction}
handleDeleteAction={handleDeleteAction}
/>
{selectedAction.actionId && currentAction && (
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput
value={selectedAction.actionName || ""}
onRename={handleRenameAction}
/>
</div>
<div className="selected-actions-list">
<LabledDropdown
defaultOption={activeOption}
options={availableActions.options}
onSelect={() => {}}
disabled={true}
/>
<PickAndPlaceAction clearPoints={handleClearPoints} />
</div>
<div className="tirgger">
<Trigger
selectedPointData={selectedPointData as any}
type={"RoboticArm"}
/>
</div>
</div>
)}
</section>
</>
);
} }
export default RoboticArmMechanics; export default RoboticArmMechanics;

View File

@ -4,249 +4,319 @@ import RenameInput from "../../../../../ui/inputs/RenameInput";
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown"; import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import Trigger from "../trigger/Trigger"; import Trigger from "../trigger/Trigger";
import { import {
useSelectedAction, useSelectedAction,
useSelectedEventData, useSelectedEventData,
useSelectedProduct, useSelectedEventSphere,
useSelectedProduct,
} from "../../../../../../store/simulation/useSimulationStore"; } from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import TravelAction from "../actions/TravelAction"; import TravelAction from "../actions/TravelAction";
import ActionsList from "../components/ActionsList"; import ActionsList from "../components/ActionsList";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/UpsertProductOrEventApi"; import { upsertProductOrEventApi } from "../../../../../../services/simulation/UpsertProductOrEventApi";
import { useVehicleStore } from "../../../../../../store/simulation/useVehicleStore";
function VehicleMechanics() { function VehicleMechanics() {
const [activeOption, setActiveOption] = useState<"default" | "travel">("default"); const [activeOption, setActiveOption] = useState<"default" | "travel">(
const [selectedPointData, setSelectedPointData] = useState<VehiclePointSchema | undefined>(); "default"
const { selectedEventData } = useSelectedEventData(); );
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction } = useProductStore(); const [selectedPointData, setSelectedPointData] = useState<
const { selectedProduct } = useSelectedProduct(); VehiclePointSchema | undefined
const { setSelectedAction, clearSelectedAction } = useSelectedAction(); >();
const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction } =
useProductStore();
const { selectedProduct } = useSelectedProduct();
const { setSelectedAction, clearSelectedAction } = useSelectedAction();
const { getVehicleById } = useVehicleStore();
const email = localStorage.getItem('email') const email = localStorage.getItem("email");
const organization = (email!.split("@")[1]).split(".")[0]; const organization = email!.split("@")[1].split(".")[0];
useEffect(() => { useEffect(() => {
if (selectedEventData && selectedEventData.data.type === 'vehicle') { if (selectedEventData && selectedEventData.data.type === "vehicle") {
const point = getPointByUuid( const point = getPointByUuid(
selectedProduct.productId, selectedProduct.productId,
selectedEventData.data.modelUuid, selectedEventData.data.modelUuid,
selectedEventData.selectedPoint selectedEventData.selectedPoint
) as VehiclePointSchema | undefined; ) as VehiclePointSchema | undefined;
if (point) { if (point) {
setSelectedPointData(point); setSelectedPointData(point);
setActiveOption(point.action.actionType as "travel"); setActiveOption(point.action.actionType as "travel");
setSelectedAction(point.action.actionUuid, point.action.actionName); setSelectedAction(point.action.actionUuid, point.action.actionName);
} }
} else { } else {
clearSelectedAction(); clearSelectedAction();
}
}, [selectedProduct, selectedEventData]);
const updateBackend = (
productName: string,
productId: string,
organization: string,
eventData: EventsSchema
) => {
upsertProductOrEventApi({
productName: productName,
productId: productId,
organization: organization,
eventDatas: eventData
})
} }
}, [selectedProduct, selectedEventData]);
const handleSpeedChange = (value: string) => { const updateBackend = (
if (!selectedEventData) return; productName: string,
const event = updateEvent(selectedProduct.productId, selectedEventData.data.modelUuid, { productId: string,
speed: parseFloat(value), organization: string,
}); eventData: EventsSchema
) => {
upsertProductOrEventApi({
productName: productName,
productId: productId,
organization: organization,
eventDatas: eventData,
});
};
if (event) { const handleSpeedChange = (value: string) => {
updateBackend( if (!selectedEventData) return;
selectedProduct.productName, const event = updateEvent(
selectedProduct.productId, selectedProduct.productId,
organization, selectedEventData.data.modelUuid,
event {
); speed: parseFloat(value),
} }
};
const handleActionTypeChange = (option: string) => {
if (!selectedEventData || !selectedPointData) return;
const validOption = option as "travel";
setActiveOption(validOption);
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
actionType: validOption,
});
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handleRenameAction = (newName: string) => {
if (!selectedPointData) return;
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, { actionName: newName });
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handleLoadCapacityChange = (value: string) => {
if (!selectedPointData) return;
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
loadCapacity: parseFloat(value),
});
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handleUnloadDurationChange = (value: string) => {
if (!selectedPointData) return;
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
unLoadDuration: parseFloat(value),
});
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handlePickPointChange = (value: string) => {
if (!selectedPointData) return;
};
const handleUnloadPointChange = (value: string) => {
if (!selectedPointData) return;
};
// Get current values from store
const currentSpeed = (getEventByModelUuid(
selectedProduct.productId, selectedEventData?.data.modelUuid || ""
) as VehicleEventSchema | undefined)?.speed?.toString() || "0.5";
const currentActionName = selectedPointData
? selectedPointData.action.actionName
: "Action Name";
const currentLoadCapacity = selectedPointData
? selectedPointData.action.loadCapacity.toString()
: "1";
const currentUnloadDuration = selectedPointData
? selectedPointData.action.unLoadDuration.toString()
: "1";
const currentPickPoint = selectedPointData?.action.pickUpPoint;
const currentUnloadPoint = selectedPointData?.action.unLoadPoint;
const availableActions = {
defaultOption: "travel",
options: ["travel"],
};
return (
<>
{selectedEventData && (
<>
<div className="global-props section">
<div className="property-list-container">
<div className="property-item">
<InputWithDropDown
label="Speed"
value={currentSpeed}
min={0}
step={0.1}
defaultValue={"0.5"}
max={10}
activeOption="m/s"
onClick={() => { }}
onChange={handleSpeedChange}
/>
</div>
</div>
</div>
<section>
<ActionsList
selectedPointData={selectedPointData}
/>
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput
value={currentActionName}
onRename={handleRenameAction}
/>
</div>
<div className="selected-actions-list">
<LabledDropdown
defaultOption="travel"
options={availableActions.options}
onSelect={handleActionTypeChange}
/>
{activeOption === "travel" && (
<TravelAction
loadCapacity={{
value: currentLoadCapacity,
min: 1,
max: 100,
defaultValue: "1",
onChange: handleLoadCapacityChange,
}}
unloadDuration={{
value: currentUnloadDuration,
min: 1,
max: 60,
defaultValue: "1",
onChange: handleUnloadDurationChange,
}}
// pickPoint={{
// value: currentPickPoint,
// onChange: handlePickPointChange,
// }}
// unloadPoint={{
// value: currentUnloadPoint,
// onChange: handleUnloadPointChange,
// }}
/>
)}
</div>
</div>
<div className="tirgger">
<Trigger selectedPointData={selectedPointData as any} type={'Vehicle'} />
</div>
</section>
</>
)}
</>
); );
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handleActionTypeChange = (option: string) => {
if (!selectedEventData || !selectedPointData) return;
const validOption = option as "travel";
setActiveOption(validOption);
const event = updateAction(
selectedProduct.productId,
selectedPointData.action.actionUuid,
{
actionType: validOption,
}
);
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handleRenameAction = (newName: string) => {
if (!selectedPointData) return;
const event = updateAction(
selectedProduct.productId,
selectedPointData.action.actionUuid,
{ actionName: newName }
);
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handleLoadCapacityChange = (value: string) => {
if (!selectedPointData) return;
const event = updateAction(
selectedProduct.productId,
selectedPointData.action.actionUuid,
{
loadCapacity: parseFloat(value),
}
);
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handleUnloadDurationChange = (value: string) => {
if (!selectedPointData) return;
const event = updateAction(
selectedProduct.productId,
selectedPointData.action.actionUuid,
{
unLoadDuration: parseFloat(value),
}
);
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handlePickPointChange = (value: string) => {
if (!selectedPointData) return;
};
const handleUnloadPointChange = (value: string) => {
if (!selectedPointData) return;
};
// Get current values from store
const currentSpeed =
(
getEventByModelUuid(
selectedProduct.productId,
selectedEventData?.data.modelUuid || ""
) as VehicleEventSchema | undefined
)?.speed?.toString() || "0.5";
const currentActionName = selectedPointData
? selectedPointData.action.actionName
: "Action Name";
const currentLoadCapacity = selectedPointData
? selectedPointData.action.loadCapacity.toString()
: "1";
const currentUnloadDuration = selectedPointData
? selectedPointData.action.unLoadDuration.toString()
: "1";
const { selectedEventSphere } = useSelectedEventSphere();
function handleClearPoints() {
const updatedVehicle = getVehicleById(
selectedEventSphere?.userData.modelUuid
);
if (
!selectedProduct?.productId ||
!selectedEventSphere?.userData?.modelUuid ||
!updatedVehicle?.point
)
return;
const event = updateEvent(
selectedProduct.productId,
selectedEventSphere.userData.modelUuid,
{
point: {
...updatedVehicle.point,
action: {
...updatedVehicle.point?.action,
pickUpPoint: null,
unLoadPoint: null,
steeringAngle: 0,
},
},
}
);
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
}
const availableActions = {
defaultOption: "travel",
options: ["travel"],
};
return (
<>
{selectedEventData && (
<>
<div className="global-props section">
<div className="property-list-container">
<div className="property-item">
<InputWithDropDown
label="Speed"
value={currentSpeed}
min={0}
step={0.1}
defaultValue={"0.5"}
max={10}
activeOption="m/s"
onClick={() => {}}
onChange={handleSpeedChange}
/>
</div>
</div>
</div>
<section>
<ActionsList selectedPointData={selectedPointData} />
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput
value={currentActionName}
onRename={handleRenameAction}
/>
</div>
<div className="selected-actions-list">
<LabledDropdown
defaultOption="travel"
options={availableActions.options}
onSelect={handleActionTypeChange}
/>
{activeOption === "travel" && (
<TravelAction
loadCapacity={{
value: currentLoadCapacity,
min: 1,
max: 100,
defaultValue: "1",
onChange: handleLoadCapacityChange,
}}
unloadDuration={{
value: currentUnloadDuration,
min: 1,
max: 60,
defaultValue: "1",
onChange: handleUnloadDurationChange,
}}
clearPoints={handleClearPoints}
// pickPoint={{
// value: currentPickPoint,
// onChange: handlePickPointChange,
// }}
// unloadPoint={{
// value: currentUnloadPoint,
// onChange: handleUnloadPointChange,
// }}
/>
)}
</div>
</div>
<div className="tirgger">
<Trigger
selectedPointData={selectedPointData as any}
type={"Vehicle"}
/>
</div>
</section>
</>
)}
</>
);
} }
export default VehicleMechanics; export default VehicleMechanics;

View File

@ -1,21 +1,18 @@
import React from "react"; import React from "react";
import { EyeDroperIcon } from "../../icons/ExportCommonIcons"; import { EyeDroperIcon } from "../../icons/ExportCommonIcons";
import RegularDropDown from "./RegularDropDown";
interface EyeDropInputProps { interface EyeDropInputProps {
label: string; label: string;
value: string; value: string;
onChange: (value: string) => void; onChange: (value: string) => void;
options?: string[];
} }
const EyeDropInput: React.FC<EyeDropInputProps> = ({ const EyeDropInput: React.FC<EyeDropInputProps> = ({
label = "Object", label = "Object",
value,
onChange, onChange,
}) => { }) => {
const handleEyeDropClick = () => { const handleEyeDropClick = () => {
// Here you would typically implement the eye dropper functionality
// For now, we'll just simulate selecting a value
const simulatedValue = "picked_value"; // Replace with actual eye dropper logic const simulatedValue = "picked_value"; // Replace with actual eye dropper logic
onChange(simulatedValue); onChange(simulatedValue);
}; };
@ -24,18 +21,15 @@ const EyeDropInput: React.FC<EyeDropInputProps> = ({
<div className="eye-dropper-input-container"> <div className="eye-dropper-input-container">
<div className="label">{label}</div> <div className="label">{label}</div>
<div className="input-container"> <div className="input-container">
{/* <input disabled type="text" /> */} <input disabled type="text" value={value}/>
<RegularDropDown {/* <input type="text" value={activeValue ?? "null"} disabled /> */}
header="select object" {/* <input type="button" value="Clear" onClick={handleEyeDropClick}/> */}
options={[]} <button className="eye-picker-button" onClick={handleEyeDropClick}>
onSelect={() => { }}
/>
<div className="eye-picker-button" onClick={handleEyeDropClick}>
<EyeDroperIcon isActive={false} /> <EyeDroperIcon isActive={false} />
</div> </button>
</div> </div>
</div> </div>
); );
}; };
export default EyeDropInput; export default EyeDropInput;

View File

@ -1,6 +1,5 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { import {
CartBagIcon,
ExpandIcon, ExpandIcon,
IndicationArrow, IndicationArrow,
SimulationStatusIcon, SimulationStatusIcon,
@ -107,7 +106,7 @@ const AssetDetailsCard: React.FC<AssetDetailsCardInterface> = ({
<div className="value-container"> <div className="value-container">
<div className="progress-bar"> <div className="progress-bar">
{[...Array(5)].map((_, i) => { {[...Array(5)].map((_, i) => {
const percentage = (count ?? 0 / totalCapacity) * 100; const percentage = (count! / totalCapacity) * 100;
const start = i * 20; const start = i * 20;
const end = (i + 1) * 20; const end = (i + 1) * 20;
// fill amount: 0 to 100 // fill amount: 0 to 100
@ -120,7 +119,7 @@ const AssetDetailsCard: React.FC<AssetDetailsCardInterface> = ({
fillPercent = ((percentage - start) / 20) * 100; fillPercent = ((percentage - start) / 20) * 100;
} }
return ( return (
<div key={i} className="block"> <div key={`block-${i}-${start}-${end}`} className="block">
<div <div
className="fill" className="fill"
style={ style={
@ -134,7 +133,7 @@ const AssetDetailsCard: React.FC<AssetDetailsCardInterface> = ({
})} })}
</div> </div>
<div className="value"> <div className="value">
{Math.round((count ?? 0 / totalCapacity) * 100).toString()}% {Math.round((count! / totalCapacity) * 100).toString()}%
</div> </div>
</div> </div>
</div> </div>

View File

@ -3,6 +3,7 @@ import { useSelectedAction, useSelectedEventSphere, useSelectedProduct } from '.
import { useGLTF } from '@react-three/drei'; import { useGLTF } from '@react-three/drei';
import { useThree } from '@react-three/fiber'; import { useThree } from '@react-three/fiber';
import { useProductStore } from '../../../../store/simulation/useProductStore'; import { useProductStore } from '../../../../store/simulation/useProductStore';
import { useArmBotStore } from '../../../../store/simulation/useArmBotStore';
import PickDropPoints from './PickDropPoints'; import PickDropPoints from './PickDropPoints';
import useDraggableGLTF from './useDraggableGLTF'; import useDraggableGLTF from './useDraggableGLTF';
import * as THREE from 'three'; import * as THREE from 'three';
@ -23,6 +24,7 @@ const ArmBotUI = () => {
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = useSelectedProduct();
const { scene } = useThree(); const { scene } = useThree();
const { selectedAction } = useSelectedAction(); const { selectedAction } = useSelectedAction();
const { armBots } = useArmBotStore();
const armUiPick = useGLTF(armPick) as any; const armUiPick = useGLTF(armPick) as any;
const armUiDrop = useGLTF(armDrop) as any; const armUiDrop = useGLTF(armDrop) as any;
@ -73,7 +75,7 @@ const ArmBotUI = () => {
} }
} }
} }
}, [selectedEventSphere, selectedProduct, getEventByModelUuid, selectedAction]); }, [armBots, selectedEventSphere, selectedProduct, getEventByModelUuid, selectedAction]);
function getDefaultPositions(modelUuid: string): Positions { function getDefaultPositions(modelUuid: string): Positions {
const modelData = getEventByModelUuid(selectedProduct.productId, modelUuid); const modelData = getEventByModelUuid(selectedProduct.productId, modelUuid);

View File

@ -23,7 +23,7 @@ const VehicleUI = () => {
const prevMousePos = useRef({ x: 0, y: 0 }); const prevMousePos = useRef({ x: 0, y: 0 });
const { selectedEventSphere } = useSelectedEventSphere(); const { selectedEventSphere } = useSelectedEventSphere();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = useSelectedProduct();
const { getVehicleById } = useVehicleStore(); const { vehicles, getVehicleById } = useVehicleStore();
const { updateEvent } = useProductStore(); const { updateEvent } = useProductStore();
const [startPosition, setStartPosition] = useState<[number, number, number]>([ const [startPosition, setStartPosition] = useState<[number, number, number]>([
0, 1, 0, 0, 1, 0,
@ -144,7 +144,7 @@ const VehicleUI = () => {
setSteeringRotation([0, steeringAngle, 0]); setSteeringRotation([0, steeringAngle, 0]);
} }
}, 10); }, 10);
}, [selectedEventSphere, outerGroup.current]); }, [selectedEventSphere, outerGroup.current, vehicles]);
const handlePointerDown = ( const handlePointerDown = (
e: any, e: any,

View File

@ -58,7 +58,7 @@ const MaterialAnimator = ({
}, [storageModel, storage.currentMaterials]); }, [storageModel, storage.currentMaterials]);
return ( return (
<group position={[0, -padding, 0]}> <group {...{ position: [0, -padding, 0] }}>
{hasLoad && {hasLoad &&
storage.currentMaterials.map((mat, index) => ( storage.currentMaterials.map((mat, index) => (
<MaterialModel <MaterialModel

View File

@ -271,6 +271,7 @@
height: calc(100% - 16px); height: calc(100% - 16px);
max-height: 46vh; max-height: 46vh;
overflow: auto; overflow: auto;
margin: 0;
} }
} }
} }
@ -454,7 +455,6 @@
height: calc(100% - 36px); height: calc(100% - 36px);
position: relative; position: relative;
width: 304px; width: 304px;
padding-bottom: 10px;
.no-event-selected { .no-event-selected {
color: #666; color: #666;
@ -780,8 +780,9 @@
.simulations-container, .simulations-container,
.event-proprties-wrapper { .event-proprties-wrapper {
position: relative; position: relative;
max-height: calc(60vh - (47px - 35px)); max-height: calc(62vh - (47px - 35px));
width: 304px; width: 304px;
border-radius: #{$border-radius-large};
overflow-x: hidden; overflow-x: hidden;
.header { .header {
@ -1175,8 +1176,8 @@
} }
.analysis-content-container { .analysis-content-container {
min-height: 50vh; min-height: 48vh;
max-height: 60vh; max-height: 56vh;
overflow-y: auto; overflow-y: auto;
.dropdown-header-container, .dropdown-header-container,