added arm ui
This commit is contained in:
@@ -37,7 +37,7 @@ const SideBarRight: React.FC = () => {
|
||||
useEffect(() => {
|
||||
if (activeModule !== "mechanics" && selectedEventData && selectedEventSphere) {
|
||||
setSubModule("mechanics");
|
||||
} else {
|
||||
} else if (!selectedEventData && !selectedEventSphere) {
|
||||
if (activeModule === 'simulation') {
|
||||
setSubModule("simulations");
|
||||
}
|
||||
@@ -123,7 +123,7 @@ const SideBarRight: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{subModule === "mechanics" && selectedEventData && selectedEventSphere && (
|
||||
{subModule === "mechanics" && (
|
||||
<div className="sidebar-right-container">
|
||||
<div className="sidebar-right-content-container">
|
||||
<EventProperties />
|
||||
|
||||
@@ -1,52 +1,34 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import InputWithDropDown from "../../../../ui/inputs/InputWithDropDown";
|
||||
import LabledDropdown from "../../../../ui/inputs/LabledDropdown";
|
||||
import {
|
||||
AddIcon,
|
||||
RemoveIcon,
|
||||
ResizeHeightIcon,
|
||||
} from "../../../../icons/ExportCommonIcons";
|
||||
import RenameInput from "../../../../ui/inputs/RenameInput";
|
||||
import { handleResize } from "../../../../../functions/handleResizePannel";
|
||||
import { handleActionToggle } from "./functions/handleActionToggle";
|
||||
import { handleDeleteAction } from "./functions/handleDeleteAction";
|
||||
import DefaultAction from "./actions/DefaultAction";
|
||||
import SpawnAction from "./actions/SpawnAction";
|
||||
import SwapAction from "./actions/SwapAction";
|
||||
import DespawnAction from "./actions/DespawnAction";
|
||||
import TravelAction from "./actions/TravelAction";
|
||||
import PickAndPlaceAction from "./actions/PickAndPlaceAction";
|
||||
import ProcessAction from "./actions/ProcessAction";
|
||||
import StorageAction from "./actions/StorageAction";
|
||||
import Trigger from "./trigger/Trigger";
|
||||
|
||||
import { useSelectedEventData, useSelectedProduct } from "../../../../../store/simulation/useSimulationStore";
|
||||
import { useProductStore } from "../../../../../store/simulation/useProductStore";
|
||||
import ConveyorMechanics from "./mechanics/conveyorMechanics";
|
||||
import VehicleMechanics from "./mechanics/vehicleMechanics";
|
||||
import RoboticArmMechanics from "./mechanics/roboticArmMechanics";
|
||||
import MachineMechanics from "./mechanics/machineMechanics";
|
||||
import StorageMechanics from "./mechanics/storageMechanics";
|
||||
|
||||
const EventProperties: React.FC = () => {
|
||||
const actionsContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const [activeOption, setActiveOption] = useState("default");
|
||||
const [selectedItem, setSelectedItem] = useState<{ item: { uuid: string; name: string } | null; }>({ item: null });
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getEventByModelUuid } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
const [currentEventData, setCurrentEventData] = useState<EventsSchema | null>(null);
|
||||
const [assetType, setAssetType] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const actions = getActions();
|
||||
if (actions.length > 0 && !selectedItem.item) {
|
||||
setSelectedItem({ item: actions[0] });
|
||||
}
|
||||
}, [selectedEventData]);
|
||||
const event = getCurrentEventData();
|
||||
setCurrentEventData(event);
|
||||
|
||||
const type = determineAssetType(event);
|
||||
setAssetType(type);
|
||||
|
||||
}, [selectedEventData, selectedProduct]);
|
||||
|
||||
const getCurrentEventData = () => {
|
||||
if (!selectedEventData?.data || !selectedProduct) return null;
|
||||
const event = getEventByModelUuid(selectedProduct.productId, selectedEventData.data.modelUuid);
|
||||
return event || null;
|
||||
return getEventByModelUuid(selectedProduct.productId, selectedEventData.data.modelUuid) || null;
|
||||
};
|
||||
|
||||
const getAssetType = () => {
|
||||
const event = getCurrentEventData();
|
||||
const determineAssetType = (event: EventsSchema | null) => {
|
||||
if (!event) return null;
|
||||
|
||||
switch (event.type) {
|
||||
@@ -59,221 +41,24 @@ const EventProperties: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const getAvailableActions = () => {
|
||||
switch (getAssetType()) {
|
||||
case "conveyor":
|
||||
return {
|
||||
defaultOption: "default",
|
||||
options: ["default", "spawn", "swap", "despawn"],
|
||||
};
|
||||
case "vehicle":
|
||||
return {
|
||||
defaultOption: "travel",
|
||||
options: ["travel"],
|
||||
};
|
||||
case "roboticArm":
|
||||
return {
|
||||
defaultOption: "pickAndPlace",
|
||||
options: ["pickAndPlace"],
|
||||
};
|
||||
case "machine":
|
||||
return {
|
||||
defaultOption: "process",
|
||||
options: ["process"],
|
||||
};
|
||||
case "storageUnit":
|
||||
return {
|
||||
defaultOption: "store",
|
||||
options: ["store", "spawn"],
|
||||
};
|
||||
default:
|
||||
return {
|
||||
defaultOption: "default",
|
||||
options: ["default"],
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Get actions based on asset type
|
||||
const getActions = () => {
|
||||
if (!selectedEventData?.data) return [];
|
||||
|
||||
const event = selectedEventData.data;
|
||||
switch (getAssetType()) {
|
||||
case "conveyor":
|
||||
return (event as ConveyorEventSchema).points
|
||||
.find((point) => point.uuid === selectedEventData?.selectedPoint)
|
||||
?.action?.triggers.map((trigger) => ({
|
||||
uuid: trigger.triggerUuid,
|
||||
name: trigger.triggerName,
|
||||
})) || [];
|
||||
case "vehicle":
|
||||
return (event as VehicleEventSchema).point.action.triggers.map(
|
||||
(trigger) => ({
|
||||
uuid: trigger.triggerUuid,
|
||||
name: trigger.triggerName,
|
||||
})
|
||||
) || [];
|
||||
case "roboticArm":
|
||||
return (event as RoboticArmEventSchema).point.actions.flatMap(
|
||||
(action) =>
|
||||
action.triggers.map((trigger) => ({
|
||||
uuid: trigger.triggerUuid,
|
||||
name: trigger.triggerName,
|
||||
}))
|
||||
) || [];
|
||||
case "machine":
|
||||
return (event as MachineEventSchema).point.action.triggers.map(
|
||||
(trigger) => ({
|
||||
uuid: trigger.triggerUuid,
|
||||
name: trigger.triggerName,
|
||||
})
|
||||
) || [];
|
||||
case "storageUnit":
|
||||
return [
|
||||
{
|
||||
uuid: (event as StorageEventSchema).point.action.actionUuid,
|
||||
name: (event as StorageEventSchema).point.action.actionName,
|
||||
},
|
||||
];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
const handleActionToggle = (actionUuid: string) => {
|
||||
const actions = getActions();
|
||||
const selected = actions.find(action => action.uuid === actionUuid);
|
||||
if (selected) {
|
||||
setSelectedItem({ item: selected });
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteAction = (actionUuid: string) => {
|
||||
|
||||
};
|
||||
|
||||
const actions = getActions();
|
||||
|
||||
const getSpeed = () => {
|
||||
if (!selectedEventData) return "0.5";
|
||||
if ("speed" in selectedEventData.data) return selectedEventData.data.speed.toString();
|
||||
return "0.5";
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{getCurrentEventData() &&
|
||||
<div className="event-proprties-wrapper">
|
||||
<div className="header">
|
||||
<div className="header-value">{selectedEventData?.data.modelName}</div>
|
||||
</div>
|
||||
<div className="global-props">
|
||||
<div className="property-list-container">
|
||||
<div className="property-item">
|
||||
<InputWithDropDown
|
||||
label="Speed"
|
||||
value="0.5"
|
||||
min={0}
|
||||
step={0.1}
|
||||
defaultValue={getSpeed()}
|
||||
max={10}
|
||||
activeOption="s"
|
||||
onClick={() => { }}
|
||||
onChange={(value) => console.log(value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="property-item">
|
||||
<InputWithDropDown
|
||||
label="Delay"
|
||||
value="0.5"
|
||||
min={0}
|
||||
step={0.1}
|
||||
defaultValue="0.5"
|
||||
max={10}
|
||||
activeOption="s"
|
||||
onClick={() => { }}
|
||||
onChange={(value) => console.log(value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="event-proprties-wrapper">
|
||||
{currentEventData &&
|
||||
<>
|
||||
<div className="header">
|
||||
<div className="header-value">{selectedEventData?.data.modelName}</div>
|
||||
</div>
|
||||
</div>
|
||||
{getAssetType() === 'roboticArm' &&
|
||||
<div className="actions-list-container">
|
||||
<div className="actions">
|
||||
<div className="header">
|
||||
<div className="header-value">Actions</div>
|
||||
<div className="add-button" onClick={() => { }}>
|
||||
<AddIcon /> Add
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="lists-main-container"
|
||||
ref={actionsContainerRef}
|
||||
style={{ height: "120px" }}
|
||||
>
|
||||
<div className="list-container">
|
||||
{actions.map((action) => (
|
||||
<div
|
||||
key={action.uuid}
|
||||
className={`list-item ${selectedItem.item?.uuid === action.uuid ? "active" : ""}`}
|
||||
>
|
||||
<div
|
||||
className="value"
|
||||
onClick={() => handleActionToggle(action.uuid)}
|
||||
>
|
||||
<RenameInput value={action.name} />
|
||||
</div>
|
||||
{actions.length > 1 && (
|
||||
<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>
|
||||
}
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput value="Action Name" />
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption={getAvailableActions().defaultOption}
|
||||
options={getAvailableActions().options}
|
||||
onSelect={(option) => setActiveOption(option)}
|
||||
/>
|
||||
{activeOption === "default" && <DefaultAction />}
|
||||
{activeOption === "spawn" && <SpawnAction />}
|
||||
{activeOption === "swap" && <SwapAction />}
|
||||
{activeOption === "despawn" && <DespawnAction />}
|
||||
{activeOption === "travel" && <TravelAction />}
|
||||
{activeOption === "pickAndPlace" && <PickAndPlaceAction />}
|
||||
{activeOption === "process" && <ProcessAction />}
|
||||
{activeOption === "store" && <StorageAction />}
|
||||
</div>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
{assetType === 'conveyor' && <ConveyorMechanics />}
|
||||
{assetType === 'vehicle' && <VehicleMechanics />}
|
||||
{assetType === 'roboticArm' && <RoboticArmMechanics />}
|
||||
{assetType === 'machine' && <MachineMechanics />}
|
||||
{assetType === 'storageUnit' && <StorageMechanics />}
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default EventProperties;
|
||||
export default EventProperties;
|
||||
@@ -0,0 +1,30 @@
|
||||
import React from "react";
|
||||
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
|
||||
|
||||
interface DelayActionProps {
|
||||
value: string;
|
||||
defaultValue: string;
|
||||
min: number;
|
||||
max: number;
|
||||
onChange: (value: string) => void;
|
||||
}
|
||||
|
||||
const DelayAction: React.FC<DelayActionProps> = ({ value, defaultValue, min, max, onChange }) => {
|
||||
return (
|
||||
<>
|
||||
<InputWithDropDown
|
||||
label="Delay"
|
||||
value={value}
|
||||
min={min}
|
||||
step={0.1}
|
||||
defaultValue={defaultValue}
|
||||
max={max}
|
||||
activeOption="s"
|
||||
onClick={() => { }}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default DelayAction;
|
||||
@@ -4,17 +4,6 @@ import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
|
||||
const DespawnAction: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<InputWithDropDown
|
||||
label="Delay"
|
||||
value=""
|
||||
min={0}
|
||||
step={0.1}
|
||||
max={10}
|
||||
defaultValue="0"
|
||||
activeOption="s"
|
||||
onClick={() => {}}
|
||||
onChange={(value) => console.log(value)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
import React from "react";
|
||||
import EyeDropInput from "../../../../../ui/inputs/EyeDropInput";
|
||||
|
||||
const PickAndPlaceAction: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<EyeDropInput label="Pick Point" value="na" onChange={() => {}} />
|
||||
<EyeDropInput label="Unload Point" value="na" onChange={() => {}} />
|
||||
</>
|
||||
);
|
||||
interface PickAndPlaceActionProps {
|
||||
pickPointValue: string;
|
||||
pickPointOnChange: (value: string) => void;
|
||||
placePointValue: string;
|
||||
placePointOnChange: (value: string) => void;
|
||||
}
|
||||
|
||||
const PickAndPlaceAction: React.FC<PickAndPlaceActionProps> = ({
|
||||
pickPointValue,
|
||||
pickPointOnChange,
|
||||
placePointValue,
|
||||
placePointOnChange,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<EyeDropInput label="Pick Point" value={pickPointValue} onChange={pickPointOnChange} />
|
||||
<EyeDropInput label="Unload Point" value={placePointValue} onChange={placePointOnChange} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default PickAndPlaceAction;
|
||||
|
||||
@@ -2,23 +2,47 @@ import React from "react";
|
||||
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
|
||||
import SwapAction from "./SwapAction";
|
||||
|
||||
const ProcessAction: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<InputWithDropDown
|
||||
label="Process Time"
|
||||
value="6"
|
||||
min={0}
|
||||
step={1}
|
||||
max={10}
|
||||
defaultValue="0"
|
||||
activeOption="s"
|
||||
onClick={() => {}}
|
||||
onChange={(value) => console.log(value)}
|
||||
/>
|
||||
<SwapAction />
|
||||
</>
|
||||
);
|
||||
interface ProcessActionProps {
|
||||
value: string;
|
||||
min: number;
|
||||
max: number;
|
||||
defaultValue: string;
|
||||
onChange: (value: string) => void;
|
||||
swapOptions: string[];
|
||||
swapDefaultOption: string;
|
||||
onSwapSelect: (value: string) => void;
|
||||
}
|
||||
|
||||
const ProcessAction: React.FC<ProcessActionProps> = ({
|
||||
value,
|
||||
min,
|
||||
max,
|
||||
defaultValue,
|
||||
onChange,
|
||||
swapOptions,
|
||||
swapDefaultOption,
|
||||
onSwapSelect,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<InputWithDropDown
|
||||
label="Process Time"
|
||||
value={value}
|
||||
min={min}
|
||||
step={1}
|
||||
max={max}
|
||||
defaultValue={defaultValue}
|
||||
activeOption="s"
|
||||
onClick={() => { }}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<SwapAction
|
||||
options={swapOptions}
|
||||
defaultOption={swapDefaultOption}
|
||||
onSelect={onSwapSelect}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProcessAction;
|
||||
|
||||
@@ -1,35 +1,72 @@
|
||||
import React from "react";
|
||||
import PreviewSelectionWithUpload from "../../../../../ui/inputs/PreviewSelectionWithUpload";
|
||||
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
|
||||
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
|
||||
|
||||
const SpawnAction: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<InputWithDropDown
|
||||
label="Spawn interval"
|
||||
value="0"
|
||||
min={0}
|
||||
step={1}
|
||||
defaultValue="0"
|
||||
max={10}
|
||||
activeOption="s"
|
||||
onClick={() => {}}
|
||||
onChange={(value) => console.log(value)}
|
||||
/>
|
||||
<InputWithDropDown
|
||||
label="Spawn count"
|
||||
value="0"
|
||||
min={0}
|
||||
step={1}
|
||||
defaultValue="0"
|
||||
max={10}
|
||||
activeOption="s"
|
||||
onClick={() => {}}
|
||||
onChange={(value) => console.log(value)}
|
||||
/>
|
||||
<PreviewSelectionWithUpload />
|
||||
</>
|
||||
);
|
||||
interface SpawnActionProps {
|
||||
onChangeInterval: (value: string) => void;
|
||||
onChangeCount: (value: string) => void;
|
||||
defaultOption: string;
|
||||
options: string[];
|
||||
onSelect: (option: string) => void;
|
||||
intervalValue: string;
|
||||
countValue: string;
|
||||
intervalMin: number;
|
||||
intervalMax: number;
|
||||
intervalDefaultValue: string;
|
||||
countMin: number;
|
||||
countMax: number;
|
||||
countDefaultValue: string;
|
||||
}
|
||||
|
||||
const SpawnAction: React.FC<SpawnActionProps> = ({
|
||||
onChangeInterval,
|
||||
onChangeCount,
|
||||
defaultOption,
|
||||
options,
|
||||
onSelect,
|
||||
intervalValue,
|
||||
countValue,
|
||||
intervalMin,
|
||||
intervalMax,
|
||||
intervalDefaultValue,
|
||||
countMin,
|
||||
countMax,
|
||||
countDefaultValue,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<InputWithDropDown
|
||||
label="Spawn interval"
|
||||
value={intervalValue}
|
||||
min={intervalMin}
|
||||
step={1}
|
||||
defaultValue={intervalDefaultValue}
|
||||
max={intervalMax}
|
||||
activeOption="s"
|
||||
onClick={() => { }}
|
||||
onChange={onChangeInterval}
|
||||
/>
|
||||
<InputWithDropDown
|
||||
label="Spawn count"
|
||||
value={countValue}
|
||||
min={countMin}
|
||||
step={1}
|
||||
defaultValue={countDefaultValue}
|
||||
max={countMax}
|
||||
activeOption="s"
|
||||
onClick={() => { }}
|
||||
onChange={onChangeCount}
|
||||
/>
|
||||
{/* <PreviewSelectionWithUpload /> */}
|
||||
<LabledDropdown
|
||||
label="Presets"
|
||||
defaultOption={defaultOption}
|
||||
options={options}
|
||||
onSelect={onSelect}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SpawnAction;
|
||||
|
||||
@@ -1,20 +1,28 @@
|
||||
import React from "react";
|
||||
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
|
||||
|
||||
const StorageAction: React.FC = () => {
|
||||
return (
|
||||
<InputWithDropDown
|
||||
label="Storage Capacity"
|
||||
value=""
|
||||
min={0}
|
||||
step={0.1}
|
||||
max={10}
|
||||
defaultValue="0"
|
||||
activeOption="s"
|
||||
onClick={() => {}}
|
||||
onChange={(value) => console.log(value)}
|
||||
/>
|
||||
);
|
||||
interface StorageActionProps {
|
||||
value: string;
|
||||
min: number;
|
||||
max: number;
|
||||
defaultValue: string;
|
||||
onChange: (value: string) => void;
|
||||
}
|
||||
|
||||
const StorageAction: React.FC<StorageActionProps> = ({ value, min, max, defaultValue, onChange }) => {
|
||||
return (
|
||||
<InputWithDropDown
|
||||
label="Storage Capacity"
|
||||
value={value}
|
||||
min={min}
|
||||
step={1}
|
||||
max={max}
|
||||
defaultValue={defaultValue}
|
||||
activeOption="s"
|
||||
onClick={() => { }}
|
||||
onChange={onChange}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default StorageAction;
|
||||
|
||||
@@ -1,12 +1,27 @@
|
||||
import React from "react";
|
||||
import PreviewSelectionWithUpload from "../../../../../ui/inputs/PreviewSelectionWithUpload";
|
||||
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
|
||||
|
||||
const SwapAction: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<PreviewSelectionWithUpload />
|
||||
</>
|
||||
);
|
||||
interface SwapActionProps {
|
||||
onSelect: (option: string) => void;
|
||||
defaultOption: string;
|
||||
options: string[];
|
||||
}
|
||||
|
||||
const SwapAction: React.FC<SwapActionProps> = ({ onSelect, defaultOption, options }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* <PreviewSelectionWithUpload /> */}
|
||||
|
||||
<LabledDropdown
|
||||
label="Presets"
|
||||
defaultOption={defaultOption}
|
||||
options={options}
|
||||
onSelect={onSelect}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SwapAction;
|
||||
|
||||
@@ -2,35 +2,77 @@ import React from "react";
|
||||
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
|
||||
import EyeDropInput from "../../../../../ui/inputs/EyeDropInput";
|
||||
|
||||
const TravelAction: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<InputWithDropDown
|
||||
label="Load Capacity"
|
||||
value=""
|
||||
min={0}
|
||||
step={0.1}
|
||||
max={10}
|
||||
defaultValue="0"
|
||||
activeOption="s"
|
||||
onClick={() => {}}
|
||||
onChange={(value) => console.log(value)}
|
||||
/>
|
||||
<InputWithDropDown
|
||||
label="Unload Duration"
|
||||
value=""
|
||||
min={0}
|
||||
step={0.1}
|
||||
max={10}
|
||||
defaultValue="0"
|
||||
activeOption="s"
|
||||
onClick={() => {}}
|
||||
onChange={(value) => console.log(value)}
|
||||
/>
|
||||
<EyeDropInput label="Pick Point" value="na" onChange={() => {}} />
|
||||
<EyeDropInput label="Unload Point" value="na" onChange={() => {}} />
|
||||
</>
|
||||
);
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
||||
const TravelAction: React.FC<TravelActionProps> = ({
|
||||
loadCapacity,
|
||||
unloadDuration,
|
||||
pickPoint,
|
||||
unloadPoint,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<InputWithDropDown
|
||||
label="Load Capacity"
|
||||
value={loadCapacity.value}
|
||||
min={loadCapacity.min}
|
||||
max={loadCapacity.max}
|
||||
defaultValue={loadCapacity.defaultValue}
|
||||
step={0.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}
|
||||
/>
|
||||
{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;
|
||||
|
||||
@@ -1,8 +1,210 @@
|
||||
import React from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import InputWithDropDown from '../../../../../ui/inputs/InputWithDropDown'
|
||||
import DelayAction from '../actions/DelayAction'
|
||||
import RenameInput from '../../../../../ui/inputs/RenameInput'
|
||||
import LabledDropdown from '../../../../../ui/inputs/LabledDropdown'
|
||||
import DespawnAction from '../actions/DespawnAction'
|
||||
import SwapAction from '../actions/SwapAction'
|
||||
import SpawnAction from '../actions/SpawnAction'
|
||||
import DefaultAction from '../actions/DefaultAction'
|
||||
import Trigger from '../trigger/Trigger'
|
||||
import { useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
||||
|
||||
function ConveyorMechanics() {
|
||||
const [activeOption, setActiveOption] = useState<"default" | "spawn" | "swap" | "delay" | "despawn">("default");
|
||||
const [selectedPointData, setSelectedPointData] = useState<ConveyorPointSchema | undefined>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getPointByUuid, updateEvent, updateAction } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData?.data.modelUuid,
|
||||
selectedEventData?.selectedPoint
|
||||
) as ConveyorPointSchema | undefined;
|
||||
if (point && 'action' in point) {
|
||||
setSelectedPointData(point);
|
||||
setActiveOption(point.action.actionType as "default" | "spawn" | "swap" | "delay" | "despawn");
|
||||
}
|
||||
}
|
||||
}, [selectedProduct, selectedEventData])
|
||||
|
||||
const handleSpeedChange = (value: string) => {
|
||||
if (!selectedEventData) return;
|
||||
updateEvent(
|
||||
selectedProduct.productId,
|
||||
selectedEventData.data.modelUuid,
|
||||
{ speed: parseFloat(value) }
|
||||
);
|
||||
};
|
||||
|
||||
const handleActionTypeChange = (option: string) => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
const validOption = option as "default" | "spawn" | "swap" | "delay" | "despawn";
|
||||
setActiveOption(validOption);
|
||||
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ actionType: validOption }
|
||||
);
|
||||
};
|
||||
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ actionName: newName }
|
||||
);
|
||||
};
|
||||
|
||||
const handleSpawnCountChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ spawnCount: value === "inherit" ? "inherit" : parseFloat(value) }
|
||||
);
|
||||
};
|
||||
|
||||
const handleSpawnIntervalChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ spawnInterval: value === "inherit" ? "inherit" : parseFloat(value) }
|
||||
);
|
||||
};
|
||||
|
||||
const handleMaterialSelect = (material: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ material }
|
||||
);
|
||||
};
|
||||
|
||||
const handleDelayChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ delay: value === "inherit" ? "inherit" : parseFloat(value) }
|
||||
);
|
||||
};
|
||||
|
||||
const availableActions = {
|
||||
defaultOption: "default",
|
||||
options: ["default", "spawn", "swap", "delay", "despawn"],
|
||||
};
|
||||
|
||||
// Get current values from store
|
||||
const currentSpeed = selectedEventData?.data.type === "transfer"
|
||||
? selectedEventData.data.speed.toString()
|
||||
: "0.5";
|
||||
|
||||
const currentActionName = selectedPointData
|
||||
? selectedPointData.action.actionName
|
||||
: "Action Name";
|
||||
|
||||
const currentMaterial = selectedPointData
|
||||
? selectedPointData.action.material
|
||||
: "Default material";
|
||||
|
||||
const currentSpawnCount = selectedPointData
|
||||
? selectedPointData.action.spawnCount?.toString() || "1"
|
||||
: "1";
|
||||
|
||||
const currentSpawnInterval = selectedPointData
|
||||
? selectedPointData.action.spawnInterval?.toString() || "1"
|
||||
: "1";
|
||||
|
||||
const currentDelay = selectedPointData
|
||||
? selectedPointData.action.delay?.toString() || "0"
|
||||
: "0";
|
||||
|
||||
return (
|
||||
<>
|
||||
{selectedEventData &&
|
||||
<>
|
||||
<div key={selectedPointData?.uuid} className="global-props">
|
||||
<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>
|
||||
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={currentActionName}
|
||||
onRename={handleRenameAction}
|
||||
/>
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption={selectedPointData
|
||||
? selectedPointData.action.actionType
|
||||
: "default"}
|
||||
options={availableActions.options}
|
||||
onSelect={handleActionTypeChange}
|
||||
/>
|
||||
{activeOption === "default" &&
|
||||
<DefaultAction />
|
||||
}
|
||||
{activeOption === "spawn" &&
|
||||
<SpawnAction
|
||||
onChangeCount={handleSpawnCountChange}
|
||||
options={["Default material", "Material 1", "Material 2"]}
|
||||
defaultOption={currentMaterial}
|
||||
onSelect={handleMaterialSelect}
|
||||
onChangeInterval={handleSpawnIntervalChange}
|
||||
intervalValue={currentSpawnInterval}
|
||||
countValue={currentSpawnCount}
|
||||
intervalMin={1}
|
||||
intervalMax={60}
|
||||
intervalDefaultValue="1"
|
||||
countMin={1}
|
||||
countMax={100}
|
||||
countDefaultValue="1"
|
||||
/>
|
||||
}
|
||||
{activeOption === "swap" &&
|
||||
<SwapAction
|
||||
options={["Default material", "Material 1", "Material 2"]}
|
||||
defaultOption={currentMaterial}
|
||||
onSelect={handleMaterialSelect}
|
||||
/>
|
||||
}
|
||||
{activeOption === "despawn" &&
|
||||
<DespawnAction />
|
||||
}
|
||||
{activeOption === "delay" &&
|
||||
<DelayAction
|
||||
value={currentDelay}
|
||||
defaultValue="0"
|
||||
min={0}
|
||||
max={60}
|
||||
onChange={handleDelayChange}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger />
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,121 @@
|
||||
import React from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import RenameInput from '../../../../../ui/inputs/RenameInput'
|
||||
import LabledDropdown from '../../../../../ui/inputs/LabledDropdown'
|
||||
import Trigger from '../trigger/Trigger'
|
||||
import { useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
||||
import ProcessAction from '../actions/ProcessAction'
|
||||
|
||||
function MachineMechanics() {
|
||||
const [activeOption, setActiveOption] = useState<"default" | "process">("default");
|
||||
const [selectedPointData, setSelectedPointData] = useState<MachinePointSchema | undefined>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getPointByUuid, updateAction } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData?.data.modelUuid,
|
||||
selectedEventData?.selectedPoint
|
||||
) as MachinePointSchema | undefined;
|
||||
if (point && 'action' in point) {
|
||||
setSelectedPointData(point);
|
||||
setActiveOption(point.action.actionType as "process");
|
||||
}
|
||||
}
|
||||
}, [selectedProduct, selectedEventData])
|
||||
|
||||
const handleActionTypeChange = (option: string) => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
const validOption = option as "process";
|
||||
setActiveOption(validOption);
|
||||
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ actionType: validOption }
|
||||
);
|
||||
};
|
||||
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ actionName: newName }
|
||||
);
|
||||
};
|
||||
|
||||
const handleProcessTimeChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ processTime: parseFloat(value) }
|
||||
);
|
||||
};
|
||||
|
||||
const handleMaterialSelect = (material: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ swapMaterial: material }
|
||||
);
|
||||
};
|
||||
|
||||
// Get current values from store
|
||||
const currentActionName = selectedPointData
|
||||
? selectedPointData.action.actionName
|
||||
: "Action Name";
|
||||
|
||||
const currentProcessTime = selectedPointData
|
||||
? selectedPointData.action.processTime.toString()
|
||||
: "1";
|
||||
|
||||
const currentMaterial = selectedPointData
|
||||
? selectedPointData.action.swapMaterial
|
||||
: "Default material";
|
||||
|
||||
const availableActions = {
|
||||
defaultOption: "process",
|
||||
options: ["process"],
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{selectedEventData &&
|
||||
<>
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={currentActionName}
|
||||
onRename={handleRenameAction}
|
||||
/>
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption="process"
|
||||
options={availableActions.options}
|
||||
onSelect={handleActionTypeChange}
|
||||
/>
|
||||
{activeOption === "process" &&
|
||||
<ProcessAction
|
||||
value={currentProcessTime}
|
||||
min={0.1}
|
||||
max={60}
|
||||
defaultValue="1"
|
||||
onChange={handleProcessTimeChange}
|
||||
swapOptions={["Default material", "Material 1", "Material 2"]}
|
||||
swapDefaultOption={currentMaterial}
|
||||
onSwapSelect={handleMaterialSelect}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger />
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,274 @@
|
||||
import React from 'react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import * as THREE 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 { useSelectedEventData, useSelectedProduct, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
||||
import { AddIcon, RemoveIcon, ResizeHeightIcon } from '../../../../../icons/ExportCommonIcons'
|
||||
import { handleResize } from '../../../../../../functions/handleResizePannel'
|
||||
import PickAndPlaceAction from '../actions/PickAndPlaceAction'
|
||||
|
||||
function RoboticArmMechanics() {
|
||||
const actionsContainerRef = useRef<HTMLDivElement>(null);
|
||||
const [activeOption, setActiveOption] = useState<"default" | "pickAndPlace">("default");
|
||||
const [selectedPointData, setSelectedPointData] = useState<RoboticArmPointSchema | undefined>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getPointByUuid, updateEvent, updateAction, addAction, removeAction } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint
|
||||
) as RoboticArmPointSchema | undefined;
|
||||
if (point) {
|
||||
setSelectedPointData(point);
|
||||
setActiveOption(point.actions[0].actionType as "default" | "pickAndPlace");
|
||||
if (point.actions.length > 0 && !selectedAction.actionId) {
|
||||
setSelectedAction(point.actions[0].actionUuid, point.actions[0].actionName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
clearSelectedAction();
|
||||
}
|
||||
}, [selectedEventData, selectedProduct]);
|
||||
|
||||
const handleActionSelect = (actionUuid: string, actionName: string) => {
|
||||
setSelectedAction(actionUuid, actionName);
|
||||
};
|
||||
|
||||
const handleAddAction = () => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
|
||||
const newAction = {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: `Action ${selectedPointData.actions.length + 1}`,
|
||||
actionType: "pickAndPlace" as "pickAndPlace",
|
||||
process: {
|
||||
startPoint: null,
|
||||
endPoint: null
|
||||
},
|
||||
triggers: [] as TriggerSchema[]
|
||||
};
|
||||
|
||||
addAction(
|
||||
selectedProduct.productId,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint,
|
||||
newAction
|
||||
);
|
||||
|
||||
const updatedPoint = {
|
||||
...selectedPointData,
|
||||
actions: [...selectedPointData.actions, newAction]
|
||||
};
|
||||
setSelectedPointData(updatedPoint);
|
||||
setSelectedAction(newAction.actionUuid, newAction.actionName);
|
||||
};
|
||||
|
||||
const handleDeleteAction = (actionUuid: string) => {
|
||||
if (!selectedPointData) return;
|
||||
|
||||
removeAction(actionUuid);
|
||||
const newActions = selectedPointData.actions.filter(a => a.actionUuid !== actionUuid);
|
||||
|
||||
const updatedPoint = {
|
||||
...selectedPointData,
|
||||
actions: newActions
|
||||
};
|
||||
setSelectedPointData(updatedPoint);
|
||||
|
||||
if (selectedAction.actionId === actionUuid) {
|
||||
if (newActions.length > 0) {
|
||||
setSelectedAction(newActions[0].actionUuid, newActions[0].actionName);
|
||||
} else {
|
||||
clearSelectedAction();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedAction.actionId) return;
|
||||
updateAction(
|
||||
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 handleSpeedChange = (value: string) => {
|
||||
if (!selectedEventData) return;
|
||||
updateEvent(
|
||||
selectedProduct.productId,
|
||||
selectedEventData.data.modelUuid,
|
||||
{ speed: parseFloat(value) }
|
||||
);
|
||||
};
|
||||
|
||||
const handlePickPointChange = (value: string) => {
|
||||
if (!selectedAction.actionId || !selectedPointData) return;
|
||||
const [x, y, z] = value.split(',').map(Number);
|
||||
|
||||
updateAction(
|
||||
selectedAction.actionId,
|
||||
{
|
||||
process: {
|
||||
startPoint: [x, y, z] as [number, number, number],
|
||||
endPoint: selectedPointData.actions.find(a => a.actionUuid === selectedAction.actionId)?.process.endPoint || null
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const handlePlacePointChange = (value: string) => {
|
||||
if (!selectedAction.actionId || !selectedPointData) return;
|
||||
const [x, y, z] = value.split(',').map(Number);
|
||||
|
||||
updateAction(
|
||||
selectedAction.actionId,
|
||||
{
|
||||
process: {
|
||||
startPoint: selectedPointData.actions.find(a => a.actionUuid === selectedAction.actionId)?.process.startPoint || null,
|
||||
endPoint: [x, y, z] as [number, number, number]
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const availableActions = {
|
||||
defaultOption: "pickAndPlace",
|
||||
options: ["pickAndPlace"],
|
||||
};
|
||||
|
||||
const currentSpeed = selectedEventData?.data.type === "roboticArm"
|
||||
? selectedEventData.data.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 (
|
||||
<>
|
||||
{selectedEventData && selectedPointData && (
|
||||
<>
|
||||
<div className="global-props">
|
||||
<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>
|
||||
|
||||
<div className="actions-list-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">
|
||||
{selectedPointData.actions.map((action) => (
|
||||
<div
|
||||
key={action.actionUuid}
|
||||
className={`list-item ${selectedAction.actionId === action.actionUuid ? "active" : ""}`}
|
||||
>
|
||||
<div
|
||||
className="value"
|
||||
onClick={() => handleActionSelect(action.actionUuid, action.actionName)}
|
||||
>
|
||||
<RenameInput
|
||||
value={action.actionName}
|
||||
onRename={handleRenameAction}
|
||||
/>
|
||||
</div>
|
||||
{selectedPointData.actions.length > 1 && (
|
||||
<div
|
||||
className="remove-button"
|
||||
onClick={() => handleDeleteAction(action.actionUuid)}
|
||||
>
|
||||
<RemoveIcon />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div
|
||||
className="resize-icon"
|
||||
id="action-resize"
|
||||
onMouseDown={(e) => handleResize(e, actionsContainerRef)}
|
||||
>
|
||||
<ResizeHeightIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{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 />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,111 @@
|
||||
import React from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import RenameInput from '../../../../../ui/inputs/RenameInput'
|
||||
import LabledDropdown from '../../../../../ui/inputs/LabledDropdown'
|
||||
import Trigger from '../trigger/Trigger'
|
||||
import { useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
||||
import StorageAction from '../actions/StorageAction';
|
||||
|
||||
function StorageMechanics() {
|
||||
const [activeOption, setActiveOption] = useState<"default" | "store" | "spawn">("default");
|
||||
const [selectedPointData, setSelectedPointData] = useState<StoragePointSchema | undefined>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getPointByUuid, updateAction } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData?.data.modelUuid,
|
||||
selectedEventData?.selectedPoint
|
||||
) as StoragePointSchema | undefined;
|
||||
if (point && 'action' in point) {
|
||||
setSelectedPointData(point);
|
||||
setActiveOption(point.action.actionType as "store" | "spawn");
|
||||
}
|
||||
}
|
||||
}, [selectedProduct, selectedEventData])
|
||||
|
||||
const handleActionTypeChange = (option: string) => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
const validOption = option as "store" | "spawn";
|
||||
setActiveOption(validOption);
|
||||
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ actionType: validOption }
|
||||
);
|
||||
};
|
||||
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ actionName: newName }
|
||||
);
|
||||
};
|
||||
|
||||
const handleCapacityChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ storageCapacity: parseInt(value) }
|
||||
);
|
||||
};
|
||||
|
||||
// Get current values from store
|
||||
const currentActionName = selectedPointData
|
||||
? selectedPointData.action.actionName
|
||||
: "Action Name";
|
||||
|
||||
const currentCapacity = selectedPointData
|
||||
? selectedPointData.action.storageCapacity.toString()
|
||||
: "0";
|
||||
|
||||
const availableActions = {
|
||||
defaultOption: "store",
|
||||
options: ["store", "spawn"],
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{selectedEventData &&
|
||||
<>
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={currentActionName}
|
||||
onRename={handleRenameAction}
|
||||
/>
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption={activeOption}
|
||||
options={availableActions.options}
|
||||
onSelect={handleActionTypeChange}
|
||||
/>
|
||||
{activeOption === "store" &&
|
||||
<StorageAction
|
||||
value={currentCapacity}
|
||||
defaultValue="0"
|
||||
min={0}
|
||||
max={20}
|
||||
onChange={handleCapacityChange}
|
||||
/>
|
||||
}
|
||||
{activeOption === "spawn" && (
|
||||
<div className="spawn-options">
|
||||
<p>Spawn configuration options would go here</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger />
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,195 @@
|
||||
import React from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import InputWithDropDown from '../../../../../ui/inputs/InputWithDropDown'
|
||||
import RenameInput from '../../../../../ui/inputs/RenameInput'
|
||||
import LabledDropdown from '../../../../../ui/inputs/LabledDropdown'
|
||||
import Trigger from '../trigger/Trigger'
|
||||
import { useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
||||
import TravelAction from '../actions/TravelAction'
|
||||
|
||||
function VehicleMechanics() {
|
||||
const [activeOption, setActiveOption] = useState<"default" | "travel">("default");
|
||||
const [selectedPointData, setSelectedPointData] = useState<VehiclePointSchema | undefined>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getPointByUuid, updateEvent, updateAction } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint
|
||||
) as VehiclePointSchema | undefined;
|
||||
|
||||
if (point) {
|
||||
setSelectedPointData(point);
|
||||
setActiveOption(point.action.actionType as "travel");
|
||||
}
|
||||
}
|
||||
}, [selectedProduct, selectedEventData])
|
||||
|
||||
const handleSpeedChange = (value: string) => {
|
||||
if (!selectedEventData) return;
|
||||
updateEvent(
|
||||
selectedProduct.productId,
|
||||
selectedEventData.data.modelUuid,
|
||||
{ speed: parseFloat(value) }
|
||||
);
|
||||
};
|
||||
|
||||
const handleActionTypeChange = (option: string) => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
const validOption = option as "travel";
|
||||
setActiveOption(validOption);
|
||||
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ actionType: validOption }
|
||||
);
|
||||
};
|
||||
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ actionName: newName }
|
||||
);
|
||||
};
|
||||
|
||||
const handleLoadCapacityChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ loadCapacity: parseFloat(value) }
|
||||
);
|
||||
};
|
||||
|
||||
const handleUnloadDurationChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ unLoadDuration: parseFloat(value) }
|
||||
);
|
||||
};
|
||||
|
||||
const handlePickPointChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
const [x, y, z] = value.split(',').map(Number);
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ pickUpPoint: { x, y, z } }
|
||||
);
|
||||
};
|
||||
|
||||
const handleUnloadPointChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
const [x, y, z] = value.split(',').map(Number);
|
||||
updateAction(
|
||||
selectedPointData.action.actionUuid,
|
||||
{ unLoadPoint: { x, y, z } }
|
||||
);
|
||||
};
|
||||
|
||||
// Get current values from store
|
||||
const currentSpeed = selectedEventData?.data.type === "vehicle"
|
||||
? selectedEventData.data.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
|
||||
? `${selectedPointData.action.pickUpPoint.x},${selectedPointData.action.pickUpPoint.y},${selectedPointData.action.pickUpPoint.z}`
|
||||
: "";
|
||||
|
||||
const currentUnloadPoint = selectedPointData?.action.unLoadPoint
|
||||
? `${selectedPointData.action.unLoadPoint.x},${selectedPointData.action.unLoadPoint.y},${selectedPointData.action.unLoadPoint.z}`
|
||||
: "";
|
||||
|
||||
const availableActions = {
|
||||
defaultOption: "travel",
|
||||
options: ["travel"],
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{selectedEventData &&
|
||||
<>
|
||||
<div className="global-props">
|
||||
<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>
|
||||
|
||||
<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 />
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { useProductStore } from "../../../../store/simulation/useProductStore";
|
||||
import { generateUUID } from "three/src/math/MathUtils";
|
||||
import RenderOverlay from "../../../templates/Overlay";
|
||||
import EditWidgetOption from "../../../ui/menu/EditWidgetOption";
|
||||
import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertProductOrEventApi";
|
||||
|
||||
interface Event {
|
||||
pathName: string;
|
||||
@@ -75,6 +76,11 @@ const Simulations: React.FC = () => {
|
||||
const handleAddEventToProduct = () => {
|
||||
if (selectedAsset) {
|
||||
addEvent(selectedProduct.productId, selectedAsset);
|
||||
// upsertProductOrEventApi({
|
||||
// productName: selectedProduct.productName,
|
||||
// productId: selectedProduct.productId,
|
||||
// eventDatas: selectedAsset
|
||||
// });
|
||||
clearSelectedAsset();
|
||||
}
|
||||
};
|
||||
@@ -90,7 +96,7 @@ const Simulations: React.FC = () => {
|
||||
(product) => product.productId === selectedProduct.productId
|
||||
);
|
||||
|
||||
const events: Event[] = selectedProductData?.eventsData.map((event) => ({
|
||||
const events: Event[] = selectedProductData?.eventDatas.map((event) => ({
|
||||
pathName: event.modelName,
|
||||
})) || [];
|
||||
|
||||
|
||||
@@ -35,12 +35,6 @@ const PreviewSelectionWithUpload: React.FC = () => {
|
||||
Upload here
|
||||
</label>
|
||||
</div>
|
||||
<LabledDropdown
|
||||
label="Presets"
|
||||
defaultOption={"Default material"}
|
||||
options={["Default material", "Product 1", "Product 2"]}
|
||||
onSelect={(option) => console.log(option)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -142,9 +142,6 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
console.log('newName: ', newName);
|
||||
|
||||
}
|
||||
const checkZoneNameDuplicate = (name: string) => {
|
||||
return zones.some(
|
||||
|
||||
Reference in New Issue
Block a user