feat: Enhance ArmBotMechanics with connected models and process management; update ConveyorMechanics for radio input behavior; adjust NavMeshDetails cell size; add depthWrite to ZoneGroup material; include triggers in copy and duplication controls; refine path connector actions filtering; improve socket store zone management
This commit is contained in:
parent
d4e0358f4b
commit
f7a0f3b3d6
|
@ -1,32 +1,128 @@
|
|||
import React, { useRef, useMemo, useCallback, useState } from "react";
|
||||
import { InfoIcon } from "../../../icons/ExportCommonIcons";
|
||||
import { InfoIcon, AddIcon, RemoveIcon, ResizeHeightIcon } from "../../../icons/ExportCommonIcons";
|
||||
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||
import {
|
||||
useSelectedActionSphere,
|
||||
useSimulationStates,
|
||||
useSocketStore
|
||||
} from "../../../../store/store";
|
||||
import { useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store";
|
||||
import * as Types from '../../../../types/world/worldTypes';
|
||||
import LabeledButton from "../../../ui/inputs/LabledButton";
|
||||
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
|
||||
import { handleResize } from "../../../../functions/handleResizePannel";
|
||||
|
||||
interface ConnectedModel {
|
||||
modelUUID: string;
|
||||
modelName: string;
|
||||
points: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
index?: number;
|
||||
}[];
|
||||
triggers?: {
|
||||
uuid: string;
|
||||
name: string;
|
||||
type: string;
|
||||
isUsed: boolean;
|
||||
}[];
|
||||
}
|
||||
|
||||
const ArmBotMechanics: React.FC = () => {
|
||||
const { selectedActionSphere } = useSelectedActionSphere();
|
||||
const { simulationStates, setSimulationStates } = useSimulationStates();
|
||||
const { socket } = useSocketStore();
|
||||
const [selectedTrigger, setSelectedTrigger] = useState<string | null>(null);
|
||||
const [selectedProcessIndex, setSelectedProcessIndex] = useState<number | null>(null);
|
||||
const actionsContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const propertiesContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// Get connected models for dropdowns
|
||||
const connectedModels = useMemo(() => {
|
||||
// Get connected models and their triggers
|
||||
const connectedModels = useMemo<ConnectedModel[]>(() => {
|
||||
if (!selectedActionSphere?.points?.uuid) return [];
|
||||
|
||||
const armBotPaths = simulationStates.filter(
|
||||
(path): path is Types.ArmBotEventsSchema => path.type === "ArmBot"
|
||||
);
|
||||
|
||||
const currentPoint = armBotPaths.find(
|
||||
(path) => path.points.uuid === selectedActionSphere.points.uuid
|
||||
)?.points;
|
||||
|
||||
if (!currentPoint?.connections?.targets) return [];
|
||||
|
||||
return currentPoint.connections.targets.reduce<ConnectedModel[]>((acc, target) => {
|
||||
const connectedModel = simulationStates.find(
|
||||
(model) => model.modeluuid === target.modelUUID
|
||||
);
|
||||
|
||||
if (!connectedModel) return acc;
|
||||
|
||||
let triggers: { uuid: string; name: string; type: string; isUsed: boolean }[] = [];
|
||||
let points: { uuid: string; position: [number, number, number] }[] = [];
|
||||
|
||||
if (connectedModel.type === "Conveyor") {
|
||||
const conveyor = connectedModel as Types.ConveyorEventsSchema;
|
||||
|
||||
const connectedPointUUIDs = currentPoint?.connections?.targets
|
||||
.filter(t => t.modelUUID === connectedModel.modeluuid)
|
||||
.map(t => t.pointUUID) || [];
|
||||
|
||||
points = conveyor.points
|
||||
.map((point, idx) => ({
|
||||
uuid: point.uuid,
|
||||
position: point.position,
|
||||
index: idx
|
||||
}))
|
||||
.filter(point => connectedPointUUIDs.includes(point.uuid));
|
||||
|
||||
|
||||
triggers = conveyor.points.flatMap(p => p.triggers?.filter(t => t.isUsed) || []);
|
||||
}
|
||||
else if (connectedModel.type === "StaticMachine") {
|
||||
const staticMachine = connectedModel as Types.StaticMachineEventsSchema;
|
||||
|
||||
points = [{
|
||||
uuid: staticMachine.points.uuid,
|
||||
position: staticMachine.points.position
|
||||
}];
|
||||
|
||||
triggers = staticMachine.points.triggers ?
|
||||
[{
|
||||
uuid: staticMachine.points.triggers.uuid,
|
||||
name: staticMachine.points.triggers.name,
|
||||
type: staticMachine.points.triggers.type,
|
||||
isUsed: true // StaticMachine triggers are always considered used
|
||||
}] : [];
|
||||
}
|
||||
|
||||
if (!acc.some(m => m.modelUUID === connectedModel.modeluuid)) {
|
||||
acc.push({
|
||||
modelUUID: connectedModel.modeluuid,
|
||||
modelName: connectedModel.modelName,
|
||||
points,
|
||||
triggers
|
||||
});
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
}, [selectedActionSphere, simulationStates]);
|
||||
|
||||
// Get triggers only from connected models
|
||||
// Get triggers from connected models
|
||||
const connectedTriggers = useMemo(() => {
|
||||
}, [connectedModels, simulationStates]);
|
||||
return connectedModels.flatMap(model =>
|
||||
(model.triggers || []).map(trigger => ({
|
||||
...trigger,
|
||||
displayName: `${model.modelName} - ${trigger.name}`,
|
||||
modelUUID: model.modelUUID
|
||||
}))
|
||||
);
|
||||
}, [connectedModels]);
|
||||
|
||||
// Get all points from connected models
|
||||
const connectedPoints = useMemo(() => {
|
||||
return connectedModels.flatMap(model =>
|
||||
model.points.map(point => ({
|
||||
...point,
|
||||
displayName: `${model.modelName} - Point${typeof point.index === 'number' ? ` ${point.index}` : ''}`,
|
||||
modelUUID: model.modelUUID
|
||||
}))
|
||||
);
|
||||
}, [connectedModels]);
|
||||
|
||||
|
||||
const { selectedPoint } = useMemo(() => {
|
||||
if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null };
|
||||
|
@ -45,77 +141,148 @@ const ArmBotMechanics: React.FC = () => {
|
|||
}, [selectedActionSphere, simulationStates]);
|
||||
|
||||
const updateBackend = async (updatedPath: Types.ArmBotEventsSchema | undefined) => {
|
||||
// if (!updatedPath) return;
|
||||
// const email = localStorage.getItem("email");
|
||||
// const organization = email ? email.split("@")[1].split(".")[0] : "";
|
||||
if (!updatedPath) return;
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email ? email.split("@")[1].split(".")[0] : "";
|
||||
|
||||
// const data = {
|
||||
// organization: organization,
|
||||
// modeluuid: updatedPath.modeluuid,
|
||||
// eventData: { type: "ArmBot", points: updatedPath.points }
|
||||
// }
|
||||
const data = {
|
||||
organization: organization,
|
||||
modeluuid: updatedPath.modeluuid,
|
||||
eventData: { type: "ArmBot", points: updatedPath.points }
|
||||
}
|
||||
console.log('data: ', data);
|
||||
|
||||
// socket.emit('v2:model-asset:updateEventData', data);
|
||||
socket.emit('v2:model-asset:updateEventData', data);
|
||||
}
|
||||
|
||||
// const handleActionUpdate = useCallback((updatedAction: Partial<Types.ArmBotEventsSchema['points']['actions']>) => {
|
||||
// if (!selectedActionSphere?.points?.uuid) return;
|
||||
const handleActionUpdate = useCallback((updatedAction: Partial<Types.ArmBotEventsSchema['points']['actions']>) => {
|
||||
if (!selectedActionSphere?.points?.uuid || !selectedPoint) return;
|
||||
|
||||
// const updatedPaths = simulationStates.map((path) => {
|
||||
// return path;
|
||||
// });
|
||||
const updatedPaths = simulationStates.map((path) => {
|
||||
if (path.type === "ArmBot" && path.points.uuid === selectedActionSphere.points.uuid) {
|
||||
return {
|
||||
...path,
|
||||
points: {
|
||||
...path.points,
|
||||
actions: {
|
||||
...path.points.actions,
|
||||
...updatedAction
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return path;
|
||||
});
|
||||
|
||||
// const updatedPath = updatedPaths.find(
|
||||
// (path): path is Types.ArmBotEventsSchema =>
|
||||
// path.type === "ArmBot" &&
|
||||
// path.points.uuid === selectedActionSphere.points.uuid
|
||||
// );
|
||||
// updateBackend(updatedPath);
|
||||
const updatedPath = updatedPaths.find(
|
||||
(path): path is Types.ArmBotEventsSchema =>
|
||||
path.type === "ArmBot" &&
|
||||
path.points.uuid === selectedActionSphere.points.uuid
|
||||
);
|
||||
updateBackend(updatedPath);
|
||||
|
||||
// setSimulationStates(updatedPaths);
|
||||
// }, [selectedActionSphere?.points?.uuid, simulationStates, setSimulationStates]);
|
||||
setSimulationStates(updatedPaths);
|
||||
}, [selectedActionSphere?.points?.uuid, selectedPoint, simulationStates, setSimulationStates]);
|
||||
|
||||
// const handleSpeedChange = useCallback((speed: number) => {
|
||||
// handleActionUpdate({ speed });
|
||||
// }, [handleActionUpdate]);
|
||||
const handleSpeedChange = useCallback((speed: number) => {
|
||||
handleActionUpdate({ speed });
|
||||
}, [handleActionUpdate]);
|
||||
|
||||
// const handleProcessChange = useCallback((processes: Types.ArmBotEventsSchema['points']['actions']['processes']) => {
|
||||
// handleActionUpdate({ processes });
|
||||
// }, [handleActionUpdate]);
|
||||
const handleProcessChange = useCallback((processes: Types.ArmBotEventsSchema['points']['actions']['processes']) => {
|
||||
handleActionUpdate({ processes });
|
||||
}, [handleActionUpdate]);
|
||||
|
||||
// const handleTriggerSelect = useCallback((displayName: string) => {
|
||||
// const selected = connectedTriggers.find(t => t.displayName === displayName);
|
||||
// setSelectedTrigger(selected?.uuid || null);
|
||||
// }, [connectedTriggers]);
|
||||
const handleAddProcess = useCallback(() => {
|
||||
if (!selectedPoint) return;
|
||||
|
||||
// const handleStartPointSelect = useCallback((pointUUID: string) => {
|
||||
// if (!selectedTrigger || !selectedPoint) return;
|
||||
const newProcess: any = {
|
||||
triggerId: "",
|
||||
startPoint: "",
|
||||
endPoint: ""
|
||||
};
|
||||
|
||||
// const updatedProcesses = selectedPoint.actions.processes?.map(process =>
|
||||
// process.triggerId === selectedTrigger
|
||||
// ? { ...process, startPoint: pointUUID }
|
||||
// : process
|
||||
// ) || [];
|
||||
const updatedProcesses = selectedPoint.actions.processes ? [...selectedPoint.actions.processes, newProcess] : [newProcess];
|
||||
|
||||
// handleProcessChange(updatedProcesses);
|
||||
// }, [selectedTrigger, selectedPoint, handleProcessChange]);
|
||||
handleProcessChange(updatedProcesses);
|
||||
setSelectedProcessIndex(updatedProcesses.length - 1);
|
||||
}, [selectedPoint, handleProcessChange]);
|
||||
|
||||
// const handleEndPointSelect = useCallback((pointUUID: string) => {
|
||||
// if (!selectedTrigger || !selectedPoint) return;
|
||||
const handleDeleteProcess = useCallback((index: number) => {
|
||||
if (!selectedPoint?.actions.processes) return;
|
||||
|
||||
// const updatedProcesses = selectedPoint.actions.processes?.map(process =>
|
||||
// process.triggerId === selectedTrigger
|
||||
// ? { ...process, endPoint: pointUUID }
|
||||
// : process
|
||||
// ) || [];
|
||||
const updatedProcesses = [...selectedPoint.actions.processes];
|
||||
updatedProcesses.splice(index, 1);
|
||||
|
||||
// handleProcessChange(updatedProcesses);
|
||||
// }, [selectedTrigger, selectedPoint, handleProcessChange]);
|
||||
handleProcessChange(updatedProcesses);
|
||||
|
||||
// const getCurrentProcess = useCallback(() => {
|
||||
// if (!selectedTrigger || !selectedPoint) return null;
|
||||
// return selectedPoint.actions.processes?.find(p => p.triggerId === selectedTrigger);
|
||||
// }, [selectedTrigger, selectedPoint]);
|
||||
// Reset selection if deleting the currently selected process
|
||||
if (selectedProcessIndex === index) {
|
||||
setSelectedProcessIndex(null);
|
||||
} else if (selectedProcessIndex !== null && selectedProcessIndex > index) {
|
||||
// Adjust selection index if needed
|
||||
setSelectedProcessIndex(selectedProcessIndex - 1);
|
||||
}
|
||||
}, [selectedPoint, selectedProcessIndex, handleProcessChange]);
|
||||
|
||||
const handleTriggerSelect = useCallback((displayName: string, index: number) => {
|
||||
const selected = connectedTriggers.find(t => t.displayName === displayName);
|
||||
if (!selected || !selectedPoint?.actions.processes) return;
|
||||
|
||||
const oldProcess = selectedPoint.actions.processes[index];
|
||||
|
||||
const updatedProcesses = [...selectedPoint.actions.processes];
|
||||
|
||||
// Only reset start/end if new trigger invalidates them (your logic can expand this)
|
||||
updatedProcesses[index] = {
|
||||
...oldProcess,
|
||||
triggerId: selected.uuid,
|
||||
startPoint: oldProcess.startPoint || "", // preserve if exists
|
||||
endPoint: oldProcess.endPoint || "" // preserve if exists
|
||||
};
|
||||
|
||||
handleProcessChange(updatedProcesses);
|
||||
}, [connectedTriggers, selectedPoint, handleProcessChange]);
|
||||
|
||||
const handleStartPointSelect = useCallback((displayName: string, index: number) => {
|
||||
if (!selectedPoint?.actions.processes) return;
|
||||
|
||||
const point = connectedPoints.find(p => p.displayName === displayName);
|
||||
if (!point) return;
|
||||
|
||||
const updatedProcesses = [...selectedPoint.actions.processes];
|
||||
updatedProcesses[index] = {
|
||||
...updatedProcesses[index],
|
||||
startPoint: point.uuid
|
||||
};
|
||||
|
||||
handleProcessChange(updatedProcesses);
|
||||
}, [selectedPoint, connectedPoints, handleProcessChange]);
|
||||
|
||||
const handleEndPointSelect = useCallback((displayName: string, index: number) => {
|
||||
if (!selectedPoint?.actions.processes) return;
|
||||
|
||||
const point = connectedPoints.find(p => p.displayName === displayName);
|
||||
if (!point) return;
|
||||
|
||||
const updatedProcesses = [...selectedPoint.actions.processes];
|
||||
updatedProcesses[index] = {
|
||||
...updatedProcesses[index],
|
||||
endPoint: point.uuid
|
||||
};
|
||||
|
||||
handleProcessChange(updatedProcesses);
|
||||
}, [selectedPoint, connectedPoints, handleProcessChange]);
|
||||
|
||||
const getProcessByIndex = useCallback((index: number) => {
|
||||
if (!selectedPoint?.actions.processes || index >= selectedPoint.actions.processes.length) return null;
|
||||
return selectedPoint.actions.processes[index];
|
||||
}, [selectedPoint]);
|
||||
|
||||
const getFilteredTriggerOptions = (currentIndex: number) => {
|
||||
const usedTriggerUUIDs = selectedPoint?.actions.processes?.filter((_, i) => i !== currentIndex).map(p => p.triggerId).filter(Boolean) ?? [];
|
||||
|
||||
return connectedTriggers.filter(trigger => !usedTriggerUUIDs.includes(trigger.uuid)).map(trigger => trigger.displayName);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="machine-mechanics-container" key={selectedPoint?.uuid}>
|
||||
|
@ -124,10 +291,10 @@ const ArmBotMechanics: React.FC = () => {
|
|||
</div>
|
||||
|
||||
<div className="machine-mechanics-content-container">
|
||||
<div className="selected-properties-container" ref={propertiesContainerRef}>
|
||||
<div className="selected-properties-container">
|
||||
<div className="properties-header">ArmBot Properties</div>
|
||||
|
||||
{/* {selectedPoint && (
|
||||
{selectedPoint && (
|
||||
<>
|
||||
<InputWithDropDown
|
||||
key={`speed-${selectedPoint.uuid}`}
|
||||
|
@ -136,36 +303,90 @@ const ArmBotMechanics: React.FC = () => {
|
|||
onChange={(value) => handleSpeedChange(parseInt(value))}
|
||||
/>
|
||||
|
||||
<div className="actions">
|
||||
<div className="header">
|
||||
<div className="header-value">Processes</div>
|
||||
<div className="add-button" onClick={handleAddProcess}>
|
||||
<AddIcon /> Add
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="lists-main-container"
|
||||
ref={actionsContainerRef}
|
||||
style={{ height: "120px" }}
|
||||
>
|
||||
<div className="list-container">
|
||||
{selectedPoint.actions.processes?.map((process, index) => (
|
||||
<div
|
||||
key={`process-${index}`}
|
||||
className={`list-item ${selectedProcessIndex === index ? "active" : ""}`}
|
||||
>
|
||||
<div
|
||||
className="value"
|
||||
onClick={() => setSelectedProcessIndex(index)}
|
||||
>
|
||||
Process {index + 1}
|
||||
</div>
|
||||
<div
|
||||
className="remove-button"
|
||||
onClick={() => handleDeleteProcess(index)}
|
||||
>
|
||||
<RemoveIcon />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div
|
||||
className="resize-icon"
|
||||
id="action-resize"
|
||||
onMouseDown={(e) => handleResize(e, actionsContainerRef)}
|
||||
>
|
||||
<ResizeHeightIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{selectedProcessIndex !== null && (
|
||||
<div className="process-configuration">
|
||||
<LabledDropdown
|
||||
key={`trigger-select-${selectedPoint.uuid}`}
|
||||
key={`trigger-select-${selectedProcessIndex}`}
|
||||
label="Select Trigger"
|
||||
defaultOption={connectedTriggers.find(t => t.uuid === selectedTrigger)?.displayName || ''}
|
||||
onSelect={handleTriggerSelect}
|
||||
options={connectedTriggers.map(trigger => trigger.displayName)}
|
||||
defaultOption={
|
||||
connectedTriggers.find(t =>
|
||||
t.uuid === getProcessByIndex(selectedProcessIndex)?.triggerId
|
||||
)?.displayName || 'Select a trigger'
|
||||
}
|
||||
onSelect={(value) => handleTriggerSelect(value, selectedProcessIndex)}
|
||||
options={getFilteredTriggerOptions(selectedProcessIndex)}
|
||||
/>
|
||||
|
||||
{selectedTrigger && (
|
||||
<>
|
||||
<LabledDropdown
|
||||
key={`start-point-${selectedTrigger}`}
|
||||
key={`start-point-${selectedProcessIndex}`}
|
||||
label="Start Point"
|
||||
defaultOption={getCurrentProcess()?.startPoint || ''}
|
||||
onSelect={handleStartPointSelect}
|
||||
options={connectedModels.map((model, index) => `${model.modelName} [${index}]`)}
|
||||
defaultOption={
|
||||
connectedPoints.find(p =>
|
||||
p.uuid === getProcessByIndex(selectedProcessIndex)?.startPoint
|
||||
)?.displayName || 'Select start point'
|
||||
}
|
||||
onSelect={(value) => handleStartPointSelect(value, selectedProcessIndex)}
|
||||
options={connectedPoints.map(point => point.displayName)}
|
||||
/>
|
||||
|
||||
<LabledDropdown
|
||||
key={`end-point-${selectedTrigger}`}
|
||||
key={`end-point-${selectedProcessIndex}`}
|
||||
label="End Point"
|
||||
defaultOption={getCurrentProcess()?.endPoint || ''}
|
||||
onSelect={handleEndPointSelect}
|
||||
options={connectedModels.map((model, index) => `${model.modelName} [${index}]`)}
|
||||
defaultOption={
|
||||
connectedPoints.find(p =>
|
||||
p.uuid === getProcessByIndex(selectedProcessIndex)?.endPoint
|
||||
)?.displayName || 'Select end point'
|
||||
}
|
||||
onSelect={(value) => handleEndPointSelect(value, selectedProcessIndex)}
|
||||
options={connectedPoints.map(point => point.displayName)}
|
||||
/>
|
||||
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)} */}
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="footer">
|
||||
|
|
|
@ -647,7 +647,7 @@ const ConveyorMechanics: React.FC = () => {
|
|||
setSelectedItem({ type: "action", item: action })
|
||||
}
|
||||
>
|
||||
<input type="radio" name="action" id="action" defaultChecked={action.isUsed} />
|
||||
<input type="radio" name="action" id="action" checked={action.isUsed} readOnly />
|
||||
<RenameInput value={action.name} />
|
||||
</div>
|
||||
<div
|
||||
|
@ -696,7 +696,7 @@ const ConveyorMechanics: React.FC = () => {
|
|||
setSelectedItem({ type: "trigger", item: trigger })
|
||||
}
|
||||
>
|
||||
<input type="radio" name="trigger" id="trigger" defaultChecked={trigger.isUsed} />
|
||||
<input type="radio" name="trigger" id="trigger" checked={trigger.isUsed} readOnly />
|
||||
<RenameInput value={trigger.name} />
|
||||
</div>
|
||||
<div
|
||||
|
|
|
@ -32,7 +32,7 @@ export default function NavMeshDetails({
|
|||
|
||||
const [positions, indices] = getPositionsAndIndices(meshes);
|
||||
|
||||
const cellSize = 0.35;
|
||||
const cellSize = 0.2;
|
||||
const cellHeight = 0.7;
|
||||
const walkableRadius = 0.5;
|
||||
const { success, navMesh } = generateSoloNavMesh(positions, indices, {
|
||||
|
|
|
@ -50,6 +50,7 @@ const ZoneGroup: React.FC = () => {
|
|||
uColor: { value: new THREE.Color(CONSTANTS.zoneConfig.color) },
|
||||
},
|
||||
transparent: true,
|
||||
depthWrite: false
|
||||
}), []);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -345,6 +345,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
|||
uuid: THREE.MathUtils.generateUUID()
|
||||
}
|
||||
: defaultAction,
|
||||
triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
|
||||
connections: {
|
||||
source: { modelUUID: obj.uuid, pointUUID },
|
||||
targets: []
|
||||
|
|
|
@ -327,6 +327,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
|||
uuid: THREE.MathUtils.generateUUID()
|
||||
}
|
||||
: defaultAction,
|
||||
triggers: {uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete'},
|
||||
connections: {
|
||||
source: { modelUUID: obj.uuid, pointUUID },
|
||||
targets: []
|
||||
|
|
|
@ -952,8 +952,17 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
|||
);
|
||||
})
|
||||
},
|
||||
// Ensure all required ArmBot point properties are included
|
||||
actions: state.points.actions,
|
||||
actions: {
|
||||
...state.points.actions,
|
||||
processes: state.points.actions.processes?.filter(process => {
|
||||
return !(
|
||||
process.startPoint === connection1.point ||
|
||||
process.endPoint === connection1.point ||
|
||||
process.startPoint === connection2.point ||
|
||||
process.endPoint === connection2.point
|
||||
);
|
||||
}) || []
|
||||
},
|
||||
triggers: state.points.triggers
|
||||
}
|
||||
};
|
||||
|
|
|
@ -68,7 +68,11 @@ export const useWalls = create<any>((set: any) => ({
|
|||
|
||||
export const useZones = create<any>((set: any) => ({
|
||||
zones: [],
|
||||
setZones: (x: any) => set(() => ({ zones: x })),
|
||||
setZones: (callback: any) =>
|
||||
set((state: any) => ({
|
||||
zones:
|
||||
typeof callback === 'function' ? callback(state.zones) : callback
|
||||
}))
|
||||
}));
|
||||
|
||||
interface ZonePointsState {
|
||||
|
|
Loading…
Reference in New Issue