Refactor Trigger component usage in mechanics files: pass selectedPointData and type props for Machine, RoboticArm, StorageUnit, and Vehicle to enhance functionality and maintain consistency.

This commit is contained in:
Jerald-Golden-B 2025-05-03 10:09:39 +05:30
parent 439f917884
commit 94c306c813
11 changed files with 275 additions and 52 deletions

View File

@ -137,7 +137,7 @@ function MachineMechanics() {
</div>
</div>
<div className="tirgger">
<Trigger />
<Trigger selectedPointData={selectedPointData as any} type= {'Machine'} />
</div>
</section>
)}

View File

@ -280,7 +280,7 @@ function RoboticArmMechanics() {
/>
</div>
<div className="tirgger">
<Trigger />
<Trigger selectedPointData={selectedPointData as any} type= {'RoboticArm'} />
</div>
</div>
)}

View File

@ -146,7 +146,7 @@ function StorageMechanics() {
</div>
</div>
<div className="tirgger">
<Trigger />
<Trigger selectedPointData={selectedPointData as any} type= {'StorageUnit'} />
</div>
</section>
)}

View File

@ -235,7 +235,7 @@ function VehicleMechanics() {
</div>
</div>
<div className="tirgger">
<Trigger />
<Trigger selectedPointData={selectedPointData as any} type= {'Vehicle'} />
</div>
</section>
</>

View File

@ -1,4 +1,5 @@
import React, { useEffect, useRef, useState } from "react";
import React, { useEffect, useMemo, useRef, useState } from "react";
import * as THREE from "three";
import {
AddIcon,
RemoveIcon,
@ -9,6 +10,7 @@ import RenameInput from "../../../../../ui/inputs/RenameInput";
import { handleResize } from "../../../../../../functions/handleResizePannel";
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import { useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/UpsertProductOrEventApi";
type TriggerProps = {
selectedPointData?: PointsScheme | undefined;
@ -18,35 +20,215 @@ type TriggerProps = {
const Trigger = ({ selectedPointData, type }: TriggerProps) => {
const [currentAction, setCurrentAction] = useState<string | undefined>();
const { selectedProduct } = useSelectedProduct();
const { getActionByUuid } = useProductStore();
const { getActionByUuid, addTrigger, removeTrigger, updateTrigger, renameTrigger, getProductById } = useProductStore();
const [triggers, setTriggers] = useState<TriggerSchema[]>([]);
const [selectedTrigger, setSelectedTrigger] = useState<TriggerSchema | undefined>();
const [activeOption, setActiveOption] = useState("onComplete");
const [activeOption, setActiveOption] = useState<"onComplete" | "onStart" | "onStop" | "delay" | "onError">("onComplete");
const triggersContainerRef = useRef<HTMLDivElement>(null);
const email = localStorage.getItem('email')
const organization = (email!.split("@")[1]).split(".")[0];
useEffect(() => {
if (!selectedPointData) return;
if (!selectedPointData || !selectedProduct) return;
let actionUuid: string | undefined;
if (type === 'Conveyor' || type === 'Vehicle' || type === 'Machine' || type === 'StorageUnit') {
setCurrentAction((selectedPointData as ConveyorPointSchema).action.actionUuid);
actionUuid = (selectedPointData as ConveyorPointSchema | VehiclePointSchema | MachinePointSchema | StoragePointSchema).action?.actionUuid;
} else if (type === 'RoboticArm') {
actionUuid = (selectedPointData as RoboticArmPointSchema).actions[0]?.actionUuid;
}
setCurrentAction(actionUuid);
}, [selectedPointData, selectedProduct, type]);
const updateBackend = (
productName: string,
productId: string,
organization: string,
eventData: EventsSchema
) => {
upsertProductOrEventApi({
productName: productName,
productId: productId,
organization: organization,
eventDatas: eventData
})
}
}, [selectedPointData]);
useEffect(() => {
if (!currentAction || !selectedProduct) return;
const action = getActionByUuid(selectedProduct.productId, currentAction);
setTriggers(action?.triggers || []);
setSelectedTrigger(action?.triggers[0] || undefined);
const actionTriggers = action?.triggers || [];
setTriggers(actionTriggers);
setSelectedTrigger(actionTriggers[0]);
}, [currentAction, selectedProduct]);
const addTrigger = (): void => {
const handleAddTrigger = () => {
if (!selectedProduct || !currentAction) return;
const newTrigger: TriggerSchema = {
triggerUuid: THREE.MathUtils.generateUUID(),
triggerName: `New Trigger ${triggers.length + 1}`,
triggerType: activeOption,
delay: 0,
triggeredAsset: null
};
const removeTrigger = (triggerUuid: string): void => {
addTrigger(selectedProduct.productId, currentAction, newTrigger);
setSelectedTrigger(newTrigger);
};
const handleRemoveTrigger = (triggerUuid: string) => {
if (!selectedProduct) return;
removeTrigger(selectedProduct.productId, triggerUuid);
if (selectedTrigger?.triggerUuid === triggerUuid) {
const remainingTriggers = triggers.filter(t => t.triggerUuid !== triggerUuid);
setSelectedTrigger(remainingTriggers[0]);
}
};
const handleTriggerRename = (triggerUuid: string, newName: string) => {
if (!selectedProduct) return;
renameTrigger(selectedProduct.productId, triggerUuid, newName);
};
const handleTriggerTypeChange = (option: string) => {
if (!selectedTrigger || !selectedProduct) return;
const validTypes: Array<TriggerSchema['triggerType']> = ["onComplete", "onStart", "onStop", "delay", "onError"];
if (!validTypes.includes(option as TriggerSchema['triggerType'])) return;
setActiveOption(option as TriggerSchema['triggerType']);
updateTrigger(selectedProduct.productId, selectedTrigger.triggerUuid, {
triggerType: option as TriggerSchema['triggerType']
});
};
const triggeredModel = selectedTrigger?.triggeredAsset?.triggeredModel || { modelName: "Select Model", modelUuid: "" };
const triggeredPoint = selectedTrigger?.triggeredAsset?.triggeredPoint || { pointName: "Select Point", pointUuid: "" };
const triggeredAction = selectedTrigger?.triggeredAsset?.triggeredAction || { actionName: "Select Action", actionUuid: "" };
console.log('selectedTrigger: ', selectedTrigger);
console.log('triggeredAction: ', triggeredAction);
const modelOptions = getProductById(selectedProduct.productId)?.eventDatas || [];
const pointOptions: PointsScheme[] = useMemo(() => {
if (!triggeredModel.modelUuid) return [];
const model = modelOptions.find(m => m.modelUuid === triggeredModel.modelUuid);
if (!model) return [];
if ('points' in model) {
return (model as ConveyorEventSchema).points;
} else if ('point' in model) {
return [(model as VehicleEventSchema | RoboticArmEventSchema | MachineEventSchema | StorageEventSchema).point];
}
return [];
}, [triggeredModel.modelUuid, modelOptions]);
const actionOptions: any = useMemo(() => {
if (!triggeredPoint.pointUuid) return [];
const point = pointOptions.find((p) => p.uuid === triggeredPoint.pointUuid);
if (!point) return [];
if ('action' in point) {
const typedPoint = point as ConveyorPointSchema | VehiclePointSchema | MachinePointSchema | StoragePointSchema;
return typedPoint.action ? [typedPoint.action] : [];
} else if ('actions' in point) {
const typedPoint = point as RoboticArmPointSchema;
return typedPoint.actions;
}
return [];
}, [triggeredPoint.pointUuid, pointOptions]);
const handleModelSelect = (option: string, triggerUuid: string) => {
if (!selectedProduct) return;
const selectedModel = modelOptions.find(m => m.modelName === option);
if (!selectedModel) return;
const event = updateTrigger(selectedProduct.productId, triggerUuid, {
triggeredAsset: {
triggeredModel: {
modelName: selectedModel.modelName,
modelUuid: selectedModel.modelUuid
},
triggeredPoint: null,
triggeredAction: null
}
});
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
};
const handlePointSelect = (option: string, triggerUuid: string) => {
if (!selectedProduct || !selectedTrigger) return;
const pointUuid = pointOptions.find(p => `Point ${p.uuid.slice(0, 5)}` === option)?.uuid;
if (!pointUuid) return;
if (selectedTrigger.triggeredAsset?.triggeredModel) {
const event = updateTrigger(selectedProduct.productId, triggerUuid, {
triggeredAsset: {
...selectedTrigger.triggeredAsset,
triggeredPoint: {
pointName: option,
pointUuid: pointUuid
},
triggeredAction: null
}
});
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
}
};
const handleActionSelect = (option: string, triggerUuid: string) => {
if (!selectedProduct || !selectedTrigger) return;
const selectedAction = actionOptions.find((a: any) => a.actionName === option);
if (!selectedAction) return;
if (selectedTrigger.triggeredAsset?.triggeredPoint) {
const event = updateTrigger(selectedProduct.productId, triggerUuid, {
triggeredAsset: {
...selectedTrigger.triggeredAsset,
triggeredAction: {
actionName: option,
actionUuid: selectedAction.actionUuid
}
}
});
if (event) {
updateBackend(
selectedProduct.productName,
selectedProduct.productId,
organization,
event
);
}
}
};
return (
<div className="trigger-wrapper">
@ -54,8 +236,9 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
<div className="title">Trigger</div>
<button
className="add-button"
onClick={addTrigger}
onClick={handleAddTrigger}
style={{ cursor: "pointer" }}
disabled={!currentAction}
>
<AddIcon /> Add
</button>
@ -73,13 +256,19 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
className={`list-item ${selectedTrigger?.triggerUuid === trigger.triggerUuid ? "active" : ""}`}
onClick={() => setSelectedTrigger(trigger)}
>
<button className="value" onClick={() => { }}>
<RenameInput value={trigger.triggerName} onRename={() => { }} />
<button className="value">
<RenameInput
value={trigger.triggerName}
onRename={(newName) => handleTriggerRename(trigger.triggerUuid, newName)}
/>
</button>
{triggers.length > 1 && (
<button
className="remove-button"
onClick={() => removeTrigger(trigger.triggerUuid)}
onClick={(e) => {
e.stopPropagation();
handleRemoveTrigger(trigger.triggerUuid);
}}
>
<RemoveIcon />
</button>
@ -95,35 +284,39 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
<ResizeHeightIcon />
</button>
</div>
{selectedTrigger && (
<div className="trigger-item">
<div className="trigger-name">{selectedTrigger?.triggerName}</div>
<div className="trigger-name">{selectedTrigger.triggerName}</div>
<LabledDropdown
label="Trigger Type"
defaultOption={activeOption}
options={["onComplete", "onStart", "onStop", "delay"]}
onSelect={(option) => setActiveOption(option)}
defaultOption={selectedTrigger.triggerType}
options={["onComplete", "onStart", "onStop", "delay", "onError"]}
onSelect={handleTriggerTypeChange}
/>
<div className="trigger-options">
<LabledDropdown
label="Triggered Object"
defaultOption={triggeredModel.modelName}
options={[]}
onSelect={(option) => { }}
options={[...modelOptions.map((option) => (option.modelName))]}
onSelect={(option) => { handleModelSelect(option, selectedTrigger.triggerUuid) }}
/>
<LabledDropdown
label="Triggered Point"
defaultOption={triggeredPoint.pointName}
options={[]}
onSelect={(option) => { }}
options={[...pointOptions.map((option) => (`Point ${option.uuid.slice(0, 5)}`))]}
onSelect={(option) => { handlePointSelect(option, selectedTrigger.triggerUuid) }}
/>
<LabledDropdown
label="Triggered Action"
defaultOption={triggeredAction.actionName}
options={[]}
onSelect={(option) => { }}
options={[...actionOptions.map((option: any) => (option.actionName))]}
onSelect={(option) => { handleActionSelect(option, selectedTrigger.triggerUuid) }}
/>
</div>
</div>
)}
</div>
</div>
);

View File

@ -8,7 +8,6 @@ import * as Types from "../../../types/world/worldTypes";
import { initializeDB, retrieveGLTF, storeGLTF } from '../../../utils/indexDB/idbUtils';
import { getCamera } from '../../../services/factoryBuilder/camera/getCameraApi';
import { getFloorAssets } from '../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi';
import PointsCalculator from '../../simulation/events/points/functions/pointsCalculator';
async function loadInitialFloorItems(
itemsGroup: Types.RefGroup,

View File

@ -235,7 +235,7 @@ async function handleModelLoad(
const nextPoint = ConveyorEvent.points[i + 1];
if (currentPoint.action.triggers.length > 0) {
currentPoint.action.triggers[0].triggeredAsset!.triggeredPoint.pointUuid = nextPoint.uuid;
currentPoint.action.triggers[0].triggeredAsset!.triggeredPoint!.pointUuid = nextPoint.uuid;
currentPoint.action.triggers[0].triggeredAsset!.triggeredAction!.actionUuid = nextPoint.action.actionUuid;
}
}

View File

@ -68,7 +68,7 @@ function TriggerConnector() {
event.points.forEach(point => {
if (point.action?.triggers) {
point.action.triggers.forEach(trigger => {
if (trigger.triggeredAsset) {
if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint) {
newConnections.push({
id: `${point.uuid}-${trigger.triggeredAsset.triggeredPoint.pointUuid}-${trigger.triggerUuid}`,
startPointUuid: point.uuid,
@ -85,7 +85,7 @@ function TriggerConnector() {
const point = event.point;
if (point.action?.triggers) {
point.action.triggers.forEach(trigger => {
if (trigger.triggeredAsset) {
if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint) {
newConnections.push({
id: `${point.uuid}-${trigger.triggeredAsset.triggeredPoint.pointUuid}-${trigger.triggerUuid}`,
startPointUuid: point.uuid,
@ -101,7 +101,7 @@ function TriggerConnector() {
const point = event.point;
point.actions?.forEach(action => {
action.triggers?.forEach(trigger => {
if (trigger.triggeredAsset) {
if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint) {
newConnections.push({
id: `${point.uuid}-${trigger.triggeredAsset.triggeredPoint.pointUuid}-${trigger.triggerUuid}`,
startPointUuid: point.uuid,
@ -117,7 +117,7 @@ function TriggerConnector() {
const point = event.point;
if (point.action?.triggers) {
point.action.triggers.forEach(trigger => {
if (trigger.triggeredAsset) {
if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint) {
newConnections.push({
id: `${point.uuid}-${trigger.triggeredAsset.triggeredPoint.pointUuid}-${trigger.triggerUuid}`,
startPointUuid: point.uuid,

View File

@ -0,0 +1,26 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const renameProductApi = async (body: { productName: string, productId: string, organization: string }) => {
try {
const response = await fetch(`${url_Backend_dwinzo}/api/v2/productRename`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
if (!response.ok) {
throw new Error("Failed to rename product");
}
const result = await response.json();
return result;
} catch (error) {
if (error instanceof Error) {
throw new Error(error.message);
} else {
throw new Error("An unknown error occurred");
}
}
};

View File

@ -51,7 +51,7 @@ type ProductsStore = {
productId: string,
triggerUuid: string,
updates: Partial<TriggerSchema>
) => void;
) => EventsSchema | undefined;
// Renaming functions
renameProduct: (productId: string, newName: string) => void;
@ -392,6 +392,7 @@ export const useProductStore = create<ProductsStore>()(
},
updateTrigger: (productId, triggerUuid, updates) => {
let updatedEvent: EventsSchema | undefined;
set((state) => {
const product = state.products.find(p => p.productId === productId);
if (product) {
@ -402,6 +403,7 @@ export const useProductStore = create<ProductsStore>()(
const trigger = point.action.triggers.find(t => t.triggerUuid === triggerUuid);
if (trigger) {
Object.assign(trigger, updates);
updatedEvent = JSON.parse(JSON.stringify(event));
return;
}
}
@ -412,6 +414,7 @@ export const useProductStore = create<ProductsStore>()(
const trigger = point.action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
if (trigger) {
Object.assign(trigger, updates);
updatedEvent = JSON.parse(JSON.stringify(event));
return;
}
} else if ('actions' in point) {
@ -420,6 +423,7 @@ export const useProductStore = create<ProductsStore>()(
const trigger = action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
if (trigger) {
Object.assign(trigger, updates);
updatedEvent = JSON.parse(JSON.stringify(event));
return;
}
}
@ -429,6 +433,7 @@ export const useProductStore = create<ProductsStore>()(
}
}
});
return updatedEvent;
},
// Renaming functions

View File

@ -13,7 +13,7 @@ interface TriggerSchema {
delay: number;
triggeredAsset: {
triggeredModel: { modelName: string, modelUuid: string };
triggeredPoint: { pointName: string, pointUuid: string };
triggeredPoint: { pointName: string, pointUuid: string } | null;
triggeredAction: { actionName: string, actionUuid: string } | null;
} | null;
}