Enhance TriggerConnector and useProductStore: add removeTrigger return value and improve event handling in TriggerConnector
This commit is contained in:
parent
571da0a78a
commit
d3f5c5e506
|
@ -1,5 +1,5 @@
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { useThree } from "@react-three/fiber";
|
import { useFrame, useThree } from "@react-three/fiber";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { useSubModuleStore } from "../../../../store/useModuleStore";
|
import { useSubModuleStore } from "../../../../store/useModuleStore";
|
||||||
import { useSelectedAsset } from "../../../../store/simulation/useSimulationStore";
|
import { useSelectedAsset } from "../../../../store/simulation/useSimulationStore";
|
||||||
|
@ -9,6 +9,7 @@ import { useSelectedProduct } from "../../../../store/simulation/useSimulationSt
|
||||||
import { handleAddEventToProduct } from "../../events/points/functions/handleAddEventToProduct";
|
import { handleAddEventToProduct } from "../../events/points/functions/handleAddEventToProduct";
|
||||||
import { QuadraticBezierLine } from "@react-three/drei";
|
import { QuadraticBezierLine } from "@react-three/drei";
|
||||||
import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertProductOrEventApi";
|
import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertProductOrEventApi";
|
||||||
|
import { useDeleteTool } from "../../../../store/store";
|
||||||
|
|
||||||
interface ConnectionLine {
|
interface ConnectionLine {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -18,13 +19,16 @@ interface ConnectionLine {
|
||||||
}
|
}
|
||||||
|
|
||||||
function TriggerConnector() {
|
function TriggerConnector() {
|
||||||
const { gl, raycaster, scene } = useThree();
|
const { gl, raycaster, scene, pointer, camera } = useThree();
|
||||||
const { subModule } = useSubModuleStore();
|
const { subModule } = useSubModuleStore();
|
||||||
const { products, getPointByUuid, getIsEventInProduct, getActionByUuid, addTrigger, addEvent, getEventByModelUuid, getProductById } = useProductStore();
|
const { products, getPointByUuid, getIsEventInProduct, getActionByUuid, addTrigger, removeTrigger, addEvent, getEventByModelUuid, getProductById } = useProductStore();
|
||||||
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
|
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
|
||||||
const { selectedProduct } = useSelectedProduct();
|
const { selectedProduct } = useSelectedProduct();
|
||||||
const [hoveredLineKey, setHoveredLineKey] = useState<string | null>(null);
|
const [hoveredLineKey, setHoveredLineKey] = useState<string | null>(null);
|
||||||
const groupRefs = useRef<Record<string, any>>({});
|
const groupRefs = useRef<Record<string, any>>({});
|
||||||
|
const [helperlineColor, setHelperLineColor] = useState<string>("red");
|
||||||
|
const [currentLine, setCurrentLine] = useState<{ start: THREE.Vector3; end: THREE.Vector3; mid: THREE.Vector3; } | null>(null);
|
||||||
|
const { deleteTool } = useDeleteTool();
|
||||||
|
|
||||||
const [firstSelectedPoint, setFirstSelectedPoint] = useState<{
|
const [firstSelectedPoint, setFirstSelectedPoint] = useState<{
|
||||||
productId: string;
|
productId: string;
|
||||||
|
@ -303,6 +307,61 @@ function TriggerConnector() {
|
||||||
|
|
||||||
}, [gl, subModule, selectedProduct, firstSelectedPoint]);
|
}, [gl, subModule, selectedProduct, firstSelectedPoint]);
|
||||||
|
|
||||||
|
|
||||||
|
useFrame(() => {
|
||||||
|
if (firstSelectedPoint) {
|
||||||
|
raycaster.setFromCamera(pointer, camera);
|
||||||
|
const intersects = raycaster.intersectObjects(scene.children, true).filter(
|
||||||
|
(intersect) =>
|
||||||
|
!intersect.object.name.includes("Roof") &&
|
||||||
|
!intersect.object.name.includes("agv-collider") &&
|
||||||
|
!intersect.object.name.includes("MeasurementReference") &&
|
||||||
|
!intersect.object.userData.isPathObject &&
|
||||||
|
!(intersect.object.type === "GridHelper")
|
||||||
|
);
|
||||||
|
|
||||||
|
let point: THREE.Vector3 | null = null;
|
||||||
|
|
||||||
|
if (intersects.length > 0) {
|
||||||
|
point = intersects[0].point;
|
||||||
|
if (point.y < 0.05) {
|
||||||
|
point = new THREE.Vector3(point.x, 0.05, point.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sphereIntersects = raycaster.intersectObjects(scene.children, true).filter((intersect) => intersect.object.name === ('Event-Sphere'));
|
||||||
|
const startPoint = getWorldPositionFromScene(firstSelectedPoint.pointUuid);
|
||||||
|
|
||||||
|
if (point && startPoint) {
|
||||||
|
|
||||||
|
const distance = startPoint.distanceTo(point);
|
||||||
|
const heightFactor = Math.max(0.5, distance * 0.2);
|
||||||
|
const midPoint = new THREE.Vector3(
|
||||||
|
(startPoint.x + point.x) / 2,
|
||||||
|
Math.max(startPoint.y, point.y) + heightFactor,
|
||||||
|
(startPoint.z + point.z) / 2
|
||||||
|
);
|
||||||
|
|
||||||
|
setCurrentLine({
|
||||||
|
start: startPoint,
|
||||||
|
mid: midPoint,
|
||||||
|
end: point,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (sphereIntersects.length > 0) {
|
||||||
|
setHelperLineColor("#6cf542");
|
||||||
|
} else {
|
||||||
|
setHelperLineColor("red");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setCurrentLine(null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setCurrentLine(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
const getWorldPositionFromScene = (pointUuid: string): THREE.Vector3 | null => {
|
const getWorldPositionFromScene = (pointUuid: string): THREE.Vector3 | null => {
|
||||||
const pointObj = scene.getObjectByProperty("uuid", pointUuid);
|
const pointObj = scene.getObjectByProperty("uuid", pointUuid);
|
||||||
if (!pointObj) return null;
|
if (!pointObj) return null;
|
||||||
|
@ -312,8 +371,23 @@ function TriggerConnector() {
|
||||||
return worldPosition;
|
return worldPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const removeConnection = (connection: ConnectionLine) => {
|
||||||
|
if (connection.trigger.triggerUuid) {
|
||||||
|
const event = removeTrigger(connection.trigger.triggerUuid);
|
||||||
|
if (event) {
|
||||||
|
console.log('event: ', event);
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<group>
|
<group name="simulationConnectionGroup" >
|
||||||
{connections.map((connection) => {
|
{connections.map((connection) => {
|
||||||
const startPoint = getWorldPositionFromScene(connection.startPointUuid);
|
const startPoint = getWorldPositionFromScene(connection.startPointUuid);
|
||||||
const endPoint = getWorldPositionFromScene(connection.endPointUuid);
|
const endPoint = getWorldPositionFromScene(connection.endPointUuid);
|
||||||
|
@ -335,20 +409,37 @@ function TriggerConnector() {
|
||||||
start={startPoint.toArray()}
|
start={startPoint.toArray()}
|
||||||
end={endPoint.toArray()}
|
end={endPoint.toArray()}
|
||||||
mid={midPoint.toArray()}
|
mid={midPoint.toArray()}
|
||||||
color={hoveredLineKey === connection.id ? "red" : "#42a5f5"}
|
color={deleteTool && hoveredLineKey === connection.id ? "red" : "#42a5f5"}
|
||||||
lineWidth={4}
|
lineWidth={4}
|
||||||
dashed={hoveredLineKey !== connection.id}
|
dashed={deleteTool && hoveredLineKey === connection.id ? false : true}
|
||||||
dashSize={0.75}
|
dashSize={0.75}
|
||||||
dashScale={20}
|
dashScale={20}
|
||||||
onPointerOver={() => setHoveredLineKey(connection.id)}
|
onPointerOver={() => setHoveredLineKey(connection.id)}
|
||||||
onPointerOut={() => setHoveredLineKey(null)}
|
onPointerOut={() => setHoveredLineKey(null)}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
console.log("Connection clicked:", connection);
|
if (deleteTool) {
|
||||||
|
setHoveredLineKey(null);
|
||||||
|
setCurrentLine(null);
|
||||||
|
removeConnection(connection);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
userData={connection.trigger}
|
userData={connection.trigger}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
{currentLine && (
|
||||||
|
<QuadraticBezierLine
|
||||||
|
start={currentLine.start.toArray()}
|
||||||
|
end={currentLine.end.toArray()}
|
||||||
|
mid={currentLine.mid.toArray()}
|
||||||
|
color={helperlineColor}
|
||||||
|
lineWidth={4}
|
||||||
|
dashed
|
||||||
|
dashSize={1}
|
||||||
|
dashScale={20}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</group>
|
</group>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ type ProductsStore = {
|
||||||
actionUuid: string,
|
actionUuid: string,
|
||||||
trigger: TriggerSchema
|
trigger: TriggerSchema
|
||||||
) => EventsSchema | undefined;
|
) => EventsSchema | undefined;
|
||||||
removeTrigger: (triggerUuid: string) => void;
|
removeTrigger: (triggerUuid: string) => EventsSchema | undefined;
|
||||||
updateTrigger: (
|
updateTrigger: (
|
||||||
triggerUuid: string,
|
triggerUuid: string,
|
||||||
updates: Partial<TriggerSchema>
|
updates: Partial<TriggerSchema>
|
||||||
|
@ -318,6 +318,7 @@ export const useProductStore = create<ProductsStore>()(
|
||||||
},
|
},
|
||||||
|
|
||||||
removeTrigger: (triggerUuid) => {
|
removeTrigger: (triggerUuid) => {
|
||||||
|
let updatedEvent: EventsSchema | undefined;
|
||||||
set((state) => {
|
set((state) => {
|
||||||
for (const product of state.products) {
|
for (const product of state.products) {
|
||||||
for (const event of product.eventDatas) {
|
for (const event of product.eventDatas) {
|
||||||
|
@ -325,16 +326,19 @@ export const useProductStore = create<ProductsStore>()(
|
||||||
for (const point of (event as ConveyorEventSchema).points) {
|
for (const point of (event as ConveyorEventSchema).points) {
|
||||||
if (point.action && 'triggers' in point.action) {
|
if (point.action && 'triggers' in point.action) {
|
||||||
point.action.triggers = point.action.triggers.filter(t => t.triggerUuid !== triggerUuid);
|
point.action.triggers = point.action.triggers.filter(t => t.triggerUuid !== triggerUuid);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ('point' in event) {
|
} else if ('point' in event) {
|
||||||
const point = (event as any).point;
|
const point = (event as any).point;
|
||||||
if ('action' in point && 'triggers' in point.action) {
|
if ('action' in point && 'triggers' in point.action) {
|
||||||
point.action.triggers = point.action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid);
|
point.action.triggers = point.action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
} else if ('actions' in point) {
|
} else if ('actions' in point) {
|
||||||
for (const action of point.actions) {
|
for (const action of point.actions) {
|
||||||
if ('triggers' in action) {
|
if ('triggers' in action) {
|
||||||
action.triggers = action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid);
|
action.triggers = action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -342,6 +346,7 @@ export const useProductStore = create<ProductsStore>()(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return updatedEvent;
|
||||||
},
|
},
|
||||||
|
|
||||||
updateTrigger: (triggerUuid, updates) => {
|
updateTrigger: (triggerUuid, updates) => {
|
||||||
|
|
Loading…
Reference in New Issue