fix: add optional chaining to prevent runtime errors in action handlers and instances

This commit is contained in:
Jerald-Golden-B 2025-05-20 15:07:14 +05:30
parent 6da65eba7b
commit 92ae705399
8 changed files with 119 additions and 110 deletions

View File

@ -83,13 +83,13 @@ export function useSpawnHandler() {
}, },
}; };
if (action.triggers[0].triggeredAsset?.triggeredModel.modelUuid && if (action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid &&
action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid && action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid &&
action.triggers[0].triggeredAsset?.triggeredAction?.actionUuid action.triggers[0]?.triggeredAsset?.triggeredAction?.actionUuid
) { ) {
newMaterial.next = { newMaterial.next = {
modelUuid: action.triggers[0].triggeredAsset?.triggeredModel.modelUuid, modelUuid: action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid,
pointUuid: action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid, pointUuid: action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid,
} }
} }

View File

@ -55,9 +55,9 @@ export function useRetrieveHandler() {
actionUuid: action.actionUuid actionUuid: action.actionUuid
}, },
current: { current: {
modelUuid: action.triggers[0].triggeredAsset.triggeredModel.modelUuid, modelUuid: action.triggers[0]?.triggeredAsset.triggeredModel.modelUuid,
pointUuid: action.triggers[0].triggeredAsset.triggeredPoint.pointUuid, pointUuid: action.triggers[0]?.triggeredAsset.triggeredPoint.pointUuid,
actionUuid: action.triggers[0].triggeredAsset.triggeredAction.actionUuid actionUuid: action.triggers[0]?.triggeredAsset.triggeredAction.actionUuid
}, },
}; };
@ -110,13 +110,13 @@ export function useRetrieveHandler() {
return; return;
} }
if (retrieval.action.triggers.length === 0 || !retrieval.action.triggers[0].triggeredAsset) { if (retrieval.action.triggers.length === 0 || !retrieval.action.triggers[0]?.triggeredAsset) {
return; return;
} }
const triggeredModel = getEventByModelUuid( const triggeredModel = getEventByModelUuid(
selectedProduct.productId, selectedProduct.productId,
retrieval.action.triggers[0].triggeredAsset.triggeredModel.modelUuid retrieval.action.triggers[0]?.triggeredAsset.triggeredModel.modelUuid
); );
if (!triggeredModel) return; if (!triggeredModel) return;
@ -160,10 +160,10 @@ export function useRetrieveHandler() {
const lastMaterial = getLastMaterial(storageUnit.modelUuid); const lastMaterial = getLastMaterial(storageUnit.modelUuid);
if (lastMaterial) { if (lastMaterial) {
if (retrieval.action.triggers[0].triggeredAsset.triggeredAction?.actionUuid) { if (retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid) {
const action = getActionByUuid(selectedProduct.productId, retrieval.action.triggers[0].triggeredAsset.triggeredAction.actionUuid); const action = getActionByUuid(selectedProduct.productId, retrieval.action.triggers[0]?.triggeredAsset.triggeredAction.actionUuid);
if (action && action.triggers.length > 0 && action.triggers[0].triggeredAsset?.triggeredModel.modelUuid) { if (action && action.triggers.length > 0 && action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid) {
const model = getEventByModelUuid(selectedProduct.productId, action.triggers[0].triggeredAsset.triggeredModel.modelUuid); const model = getEventByModelUuid(selectedProduct.productId, action.triggers[0]?.triggeredAsset.triggeredModel.modelUuid);
if (model) { if (model) {
if (model.type === 'vehicle') { if (model.type === 'vehicle') {
const vehicle = getVehicleById(model.modelUuid); const vehicle = getVehicleById(model.modelUuid);
@ -178,7 +178,7 @@ export function useRetrieveHandler() {
addCurrentAction( addCurrentAction(
triggeredModel.modelUuid, triggeredModel.modelUuid,
retrieval.action.triggers[0].triggeredAsset.triggeredAction?.actionUuid ?? '', retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid ?? '',
material.materialType, material.materialType,
material.materialId material.materialId
); );
@ -195,7 +195,7 @@ export function useRetrieveHandler() {
addCurrentAction( addCurrentAction(
triggeredModel.modelUuid, triggeredModel.modelUuid,
retrieval.action.triggers[0].triggeredAsset.triggeredAction?.actionUuid ?? '', retrieval.action.triggers[0]?.triggeredAsset.triggeredAction?.actionUuid ?? '',
material.materialType, material.materialType,
material.materialId material.materialId
); );

View File

@ -1,14 +1,22 @@
import React, { useEffect } from 'react' import { useEffect } from 'react'
import { useMaterialStore } from '../../../../../store/simulation/useMaterialStore'; import { useMaterialStore } from '../../../../../store/simulation/useMaterialStore';
import { useConveyorStore } from '../../../../../store/simulation/useConveyorStore'; import { useConveyorStore } from '../../../../../store/simulation/useConveyorStore';
import { useResetButtonStore } from '../../../../../store/usePlayButtonStore'; import { useResetButtonStore } from '../../../../../store/usePlayButtonStore';
import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore';
import { useProductStore } from '../../../../../store/simulation/useProductStore';
// import { findConveyorSubsequence } from '../../../simulator/functions/getConveyorSequencesInProduct';
function ConveyorInstance({ conveyor }: { conveyor: ConveyorStatus }) { function ConveyorInstance({ conveyor }: { conveyor: ConveyorStatus }) {
const { getProductById } = useProductStore();
const { selectedProduct } = useSelectedProduct();
const { materials, getMaterialsByCurrentModelUuid } = useMaterialStore(); const { materials, getMaterialsByCurrentModelUuid } = useMaterialStore();
const { isReset } = useResetButtonStore(); const { isReset } = useResetButtonStore();
const { setConveyorPaused } = useConveyorStore(); const { setConveyorPaused } = useConveyorStore();
useEffect(() => { useEffect(() => {
const product = getProductById(selectedProduct.productId);
if (!product) return;
const conveyorMaterials = getMaterialsByCurrentModelUuid(conveyor.modelUuid); const conveyorMaterials = getMaterialsByCurrentModelUuid(conveyor.modelUuid);
if (conveyorMaterials && conveyorMaterials?.length > 0) { if (conveyorMaterials && conveyorMaterials?.length > 0) {
@ -19,11 +27,32 @@ function ConveyorInstance({ conveyor }: { conveyor: ConveyorStatus }) {
} else { } else {
setConveyorPaused(conveyor.modelUuid, false); setConveyorPaused(conveyor.modelUuid, false);
} }
}else{ } else {
setConveyorPaused(conveyor.modelUuid, false); setConveyorPaused(conveyor.modelUuid, false);
} }
}, [materials, conveyor.modelUuid, getMaterialsByCurrentModelUuid, setConveyorPaused, isReset]); // const conveyorSubsequence = findConveyorSubsequence(product, conveyor.modelUuid);
// if (!conveyorSubsequence || !conveyorSubsequence.currentSubSequence) {
// setConveyorPaused(conveyor.modelUuid, false);
// return;
// }
// const { currentSubSequence } = conveyorSubsequence;
// const allMaterials = currentSubSequence.flatMap(event =>
// getMaterialsByCurrentModelUuid(event.modelUuid)
// );
// const hasPausedMaterials = allMaterials.some(mat => mat?.isPaused);
// currentSubSequence.forEach(event => {
// if (event.type === 'transfer') {
// setConveyorPaused(event.modelUuid, hasPausedMaterials);
// }
// });
}, [materials, conveyor.modelUuid, getMaterialsByCurrentModelUuid, setConveyorPaused, isReset, selectedProduct.productId, getProductById]);
useEffect(() => { useEffect(() => {
// console.log('conveyor: ', conveyor); // console.log('conveyor: ', conveyor);

View File

@ -13,7 +13,6 @@ import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore
import { useStorageUnitStore } from '../../../../../store/simulation/useStorageUnitStore'; import { useStorageUnitStore } from '../../../../../store/simulation/useStorageUnitStore';
import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore'; import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore';
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler'; import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
import { useCheckActiveRoboticArmsInSubsequence } from '../../../simulator/functions/checkActiveRoboticArmsInSubsequence';
function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) { function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
@ -88,8 +87,8 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
if (armBot.currentAction) { if (armBot.currentAction) {
const action = getActionByUuid(selectedProduct.productId, armBot.currentAction.actionUuid); const action = getActionByUuid(selectedProduct.productId, armBot.currentAction.actionUuid);
const model = getEventByModelUuid(selectedProduct.productId, action?.triggers[0].triggeredAsset?.triggeredModel.modelUuid || ''); const model = getEventByModelUuid(selectedProduct.productId, action?.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid || '');
if (action && action.triggers[0].triggeredAsset?.triggeredModel.modelUuid) { if (action && action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid) {
if (!model) return; if (!model) return;
if (model.type === 'transfer') { if (model.type === 'transfer') {
setIsVisible(armBot.currentAction.materialId || '', true); setIsVisible(armBot.currentAction.materialId || '', true);

View File

@ -1,49 +0,0 @@
import { getConveyorSequencesInProduct } from "./getConveyorSequencesForProduct";
export function findConveyorInSequences(
product: {
productName: string;
productId: string;
eventDatas: EventsSchema[];
},
conveyorUuid: string
): {
allSequences: EventsSchema[][][];
parentSequence: EventsSchema[][];
currentSubSequence: EventsSchema[];
} | null {
// Get all conveyor sequences
const allSequences = getConveyorSequencesInProduct(product);
// Search through all sequences
for (const parentSequence of allSequences) {
for (const currentSubSequence of parentSequence) {
for (const conveyor of currentSubSequence) {
// Check if this is the conveyor we're looking for
if (conveyor.modelUuid === conveyorUuid) {
return {
allSequences,
parentSequence,
currentSubSequence
};
}
// Also check points in case the UUID matches a point's conveyor
if (conveyor.type === 'transfer') {
for (const point of conveyor.points) {
if (point.uuid === conveyorUuid) {
return {
allSequences,
parentSequence,
currentSubSequence
};
}
}
}
}
}
}
// Conveyor not found
return null;
}

View File

@ -1,49 +1,79 @@
import { extractTriggersFromPoint } from "./extractTriggersFromPoint"; import { extractTriggersFromPoint } from "./extractTriggersFromPoint";
// Gets all conveyor sequences split by non-transfer events
export function getConveyorSequencesInProduct( export function getConveyorSequencesInProduct(
product: { product: {
productName: string; productName: string;
productId: string; productId: string;
eventDatas: EventsSchema[]; eventDatas: EventsSchema[];
} }
): EventsSchema[][][] { // Now returns array of array of arrays ): EventsSchema[][][] {
// Get all machine sequences for this product
const machineSequences = determineExecutionMachineSequences([product]); const machineSequences = determineExecutionMachineSequences([product]);
const allConveyorSequences: EventsSchema[][][] = []; const allConveyorSequences: EventsSchema[][][] = [];
// Process each machine sequence separately
for (const machineSequence of machineSequences) { for (const machineSequence of machineSequences) {
const conveyorSequencesForThisMachineSequence: EventsSchema[][] = []; const conveyorSequencesForMachine: EventsSchema[][] = [];
let currentConveyorSequence: EventsSchema[] = []; let currentSequence: EventsSchema[] = [];
for (const event of machineSequence) { for (const event of machineSequence) {
if (event.type === 'transfer') { if (event.type === 'transfer') {
// Add conveyor to current sequence currentSequence.push(event);
currentConveyorSequence.push(event); } else {
} else if (event.type === 'vehicle') { // Split sequence when non-transfer event is encountered
// Vehicle encountered - split the sequence if (currentSequence.length > 0) {
if (currentConveyorSequence.length > 0) { conveyorSequencesForMachine.push([...currentSequence]);
conveyorSequencesForThisMachineSequence.push([...currentConveyorSequence]); currentSequence = [];
currentConveyorSequence = [];
} }
} }
// Other machine types don't affect the conveyor sequence
} }
// Add any remaining conveyors in the current sequence // Add the last sequence if it exists
if (currentConveyorSequence.length > 0) { if (currentSequence.length > 0) {
conveyorSequencesForThisMachineSequence.push([...currentConveyorSequence]); conveyorSequencesForMachine.push([...currentSequence]);
} }
if (conveyorSequencesForThisMachineSequence.length > 0) { if (conveyorSequencesForMachine.length > 0) {
allConveyorSequences.push(conveyorSequencesForThisMachineSequence); allConveyorSequences.push(conveyorSequencesForMachine);
} }
} }
return allConveyorSequences; return allConveyorSequences;
} }
// Finds the subsequence containing a specific conveyor
export function findConveyorSubsequence(
product: {
productName: string;
productId: string;
eventDatas: EventsSchema[];
},
conveyorModelUuid: string
): {
allSequences: EventsSchema[][][];
parentSequence: EventsSchema[][];
currentSubSequence: EventsSchema[];
} | null {
const allSequences = getConveyorSequencesInProduct(product);
for (const parentSequence of allSequences) {
for (const currentSubSequence of parentSequence) {
const hasTargetConveyor = currentSubSequence.some(
event => event.type === 'transfer' && event.modelUuid === conveyorModelUuid
);
if (hasTargetConveyor) {
return {
allSequences,
parentSequence,
currentSubSequence
};
}
}
}
return null;
}
// Helper function to get machine sequences (simplified from your example) // Helper function to get machine sequences (simplified from your example)
function determineExecutionMachineSequences(products: productsSchema): EventsSchema[][] { function determineExecutionMachineSequences(products: productsSchema): EventsSchema[][] {
const pointToEventMap = new Map<string, EventsSchema>(); const pointToEventMap = new Map<string, EventsSchema>();

View File

@ -188,12 +188,12 @@ export function useTriggerHandler() {
setIsVisible(materialId, true); setIsVisible(materialId, true);
if (action && if (action &&
action.triggers[0].triggeredAsset?.triggeredModel.modelUuid && action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid &&
action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid
) { ) {
setNextLocation(material.materialId, { setNextLocation(material.materialId, {
modelUuid: action.triggers[0].triggeredAsset?.triggeredModel.modelUuid, modelUuid: action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid,
pointUuid: action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid, pointUuid: action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid,
}); });
handleAction(action, materialId); handleAction(action, materialId);
@ -330,9 +330,9 @@ export function useTriggerHandler() {
if (armBot.isActive === false && armBot.state === 'idle') { if (armBot.isActive === false && armBot.state === 'idle') {
// Handle current action from arm bot // Handle current action from arm bot
const model = getEventByModelUuid(selectedProduct.productId, action.triggers[0].triggeredAsset?.triggeredModel.modelUuid || ''); const model = getEventByModelUuid(selectedProduct.productId, action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid || '');
if (model?.type === 'transfer') { if (model?.type === 'transfer') {
const conveyor = getConveyorById(action.triggers[0].triggeredAsset?.triggeredModel.modelUuid || ''); const conveyor = getConveyorById(action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid || '');
if (conveyor) { if (conveyor) {
addConveyorToMonitor(conveyor.modelUuid, addConveyorToMonitor(conveyor.modelUuid,
() => { () => {
@ -350,9 +350,9 @@ export function useTriggerHandler() {
// Event Manager Needed // Event Manager Needed
addArmBotToMonitor(armBot.modelUuid, addArmBotToMonitor(armBot.modelUuid,
() => { () => {
const model = getEventByModelUuid(selectedProduct.productId, action.triggers[0].triggeredAsset?.triggeredModel.modelUuid || ''); const model = getEventByModelUuid(selectedProduct.productId, action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid || '');
if (model?.type === 'transfer') { if (model?.type === 'transfer') {
const conveyor = getConveyorById(action.triggers[0].triggeredAsset?.triggeredModel.modelUuid || ''); const conveyor = getConveyorById(action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid || '');
if (conveyor) { if (conveyor) {
addConveyorToMonitor(conveyor.modelUuid, addConveyorToMonitor(conveyor.modelUuid,
() => { () => {
@ -397,22 +397,22 @@ export function useTriggerHandler() {
const action = getActionByUuid(selectedProduct.productId, trigger.triggeredAsset.triggeredAction.actionUuid); const action = getActionByUuid(selectedProduct.productId, trigger.triggeredAsset.triggeredAction.actionUuid);
if (action && action.triggers.length > 0 && if (action && action.triggers.length > 0 &&
action.triggers[0].triggeredAsset?.triggeredModel.modelUuid && action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid &&
action.triggers[0].triggeredAsset?.triggeredAction?.actionUuid && action.triggers[0]?.triggeredAsset?.triggeredAction?.actionUuid &&
action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid) { action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid) {
const model = getEventByModelUuid(selectedProduct.productId, action.triggers[0].triggeredAsset?.triggeredModel.modelUuid); const model = getEventByModelUuid(selectedProduct.productId, action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid);
if (model?.type === 'roboticArm') { if (model?.type === 'roboticArm') {
handleAction(action, material.materialId); handleAction(action, material.materialId);
} else if (model?.type === 'vehicle') { } else if (model?.type === 'vehicle') {
const nextAction = getActionByUuid(selectedProduct.productId, action.triggers[0].triggeredAsset?.triggeredAction.actionUuid); const nextAction = getActionByUuid(selectedProduct.productId, action.triggers[0]?.triggeredAsset?.triggeredAction.actionUuid);
if (action) { if (action) {
handleAction(action, material.materialId); handleAction(action, material.materialId);
const vehicle = getVehicleById(action.triggers[0].triggeredAsset?.triggeredModel.modelUuid); const vehicle = getVehicleById(action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid);
setPreviousLocation(material.materialId, { setPreviousLocation(material.materialId, {
modelUuid: material.current.modelUuid, modelUuid: material.current.modelUuid,
@ -449,18 +449,18 @@ export function useTriggerHandler() {
} }
} else if (model?.type === 'transfer') { } else if (model?.type === 'transfer') {
const conveyor = getConveyorById(action.triggers[0].triggeredAsset?.triggeredModel.modelUuid); const conveyor = getConveyorById(action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid);
if (conveyor) { if (conveyor) {
setNextLocation(material.materialId, { setNextLocation(material.materialId, {
modelUuid: action.triggers[0].triggeredAsset?.triggeredModel.modelUuid, modelUuid: action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid,
pointUuid: action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid, pointUuid: action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid,
}) })
handleAction(action, material.materialId); handleAction(action, material.materialId);
} }
} else { } else {
setNextLocation(material.materialId, { setNextLocation(material.materialId, {
modelUuid: action.triggers[0].triggeredAsset?.triggeredModel.modelUuid, modelUuid: action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid,
pointUuid: action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid, pointUuid: action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid,
}) })
handleAction(action, material.materialId); handleAction(action, material.materialId);

View File

@ -217,7 +217,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
function startUnloadingProcess() { function startUnloadingProcess() {
if (agvDetail.point.action.triggers.length > 0) { if (agvDetail.point.action.triggers.length > 0) {
const trigger = getTriggerByUuid(selectedProduct.productId, agvDetail.point.action.triggers[0].triggerUuid); const trigger = getTriggerByUuid(selectedProduct.productId, agvDetail.point.action.triggers[0]?.triggerUuid);
const model = getEventByModelUuid(selectedProduct.productId, trigger?.triggeredAsset?.triggeredModel?.modelUuid || ''); const model = getEventByModelUuid(selectedProduct.productId, trigger?.triggeredAsset?.triggeredModel?.modelUuid || '');
if (trigger && model) { if (trigger && model) {