Merge remote-tracking branch 'origin/v2' into v2-ui

This commit is contained in:
Vishnu 2025-05-09 18:49:47 +05:30
commit 183c945ab4
5 changed files with 144 additions and 21 deletions

View File

@ -1,4 +1,4 @@
import React, { useRef, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import {
AddIcon,
ArrowIcon,
@ -20,9 +20,12 @@ import { useEventsStore } from "../../../../store/simulation/useEventsStore";
import { deleteEventDataApi } from "../../../../services/simulation/deleteEventDataApi";
import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertProductOrEventApi";
import { deleteProductApi } from "../../../../services/simulation/deleteProductApi";
import { renameProductApi } from "../../../../services/simulation/renameProductApi";
import { determineExecutionMachineSequences } from "../../../../modules/simulation/simulator/functions/determineExecutionMachineSequences";
interface Event {
pathName: string;
modelName: string;
modelId: string;
}
interface ListProps {
@ -32,7 +35,7 @@ interface ListProps {
const List: React.FC<ListProps> = ({ val }) => {
return (
<div className="process-container">
<div className="value">{val.pathName}</div>
<div className="value">{val.modelName}</div>
</div>
);
};
@ -46,6 +49,7 @@ const Simulations: React.FC = () => {
renameProduct,
addEvent,
removeEvent,
getProductById
} = useProductStore();
const { selectedProduct, setSelectedProduct } = useSelectedProduct();
const { getEventByModelUuid } = useEventsStore();
@ -53,6 +57,7 @@ const Simulations: React.FC = () => {
const email = localStorage.getItem("email");
const organization = email!.split("@")[1].split(".")[0];
const [openObjects, setOpenObjects] = useState(true);
const [processes, setProcesses] = useState<Event[][]>();
const handleAddProduct = () => {
const id = generateUUID();
@ -92,6 +97,7 @@ const Simulations: React.FC = () => {
const handleRenameProduct = (productId: string, newName: string) => {
renameProduct(productId, newName);
renameProductApi({ productName: newName, productId, organization });
if (selectedProduct.productId === productId) {
setSelectedProduct(productId, newName);
}
@ -111,14 +117,27 @@ const Simulations: React.FC = () => {
}
};
const selectedProductData = products.find(
(product) => product.productId === selectedProduct.productId
);
useEffect(() => {
const processes: Event[][] = [];
const selectedProductData = getProductById(selectedProduct.productId);
if (selectedProductData) {
determineExecutionMachineSequences([selectedProductData])
.then((sequences) => {
sequences.forEach((sequence) => {
const events: Event[] =
selectedProductData?.eventDatas.map((event) => ({
pathName: event.modelName,
sequence.map((event) => ({
modelName: event.modelName,
modelId: event.modelUuid
})) || [];
processes.push(events);
})
console.log('processes: ', processes);
setProcesses(processes)
})
}
}, [selectedProduct.productId])
return (
<div className="simulations-container">
@ -197,9 +216,14 @@ const Simulations: React.FC = () => {
</div>
</button>
{openObjects &&
events.map((event, index) => (
<List key={`${index}-${event.pathName}`} val={event} />
processes?.map((process, index) =>
<section key={index}>
{process.map((event, index) => (
<List key={`${index}-${event.modelName}`} val={event} />
))}
</section>
)
}
</div>
<div className="compare-simulations-container">

View File

@ -0,0 +1,101 @@
import { extractTriggersFromPoint } from "./extractTriggersFromPoint";
export async function determineExecutionMachineSequences(products: productsSchema): Promise<EventsSchema[][]> {
const pointToEventMap = new Map<string, EventsSchema>();
const allPoints: PointsScheme[] = [];
// First pass: map points to their corresponding events
products.forEach(product => {
product.eventDatas.forEach(event => {
if (event.type === 'transfer') {
event.points.forEach(point => {
pointToEventMap.set(point.uuid, event);
allPoints.push(point);
});
} else if (
event.type === 'vehicle' ||
event.type === 'machine' ||
event.type === 'storageUnit' ||
event.type === 'roboticArm'
) {
pointToEventMap.set(event.point.uuid, event);
allPoints.push(event.point);
}
});
});
// Build dependency graph
const dependencyGraph = new Map<string, string[]>();
const reverseDependencyGraph = new Map<string, string[]>();
const triggeredPoints = new Set<string>();
allPoints.forEach(point => {
const triggers = extractTriggersFromPoint(point);
const dependencies: string[] = [];
triggers.forEach(trigger => {
const targetUuid = trigger.triggeredAsset?.triggeredPoint?.pointUuid;
if (targetUuid && pointToEventMap.has(targetUuid)) {
dependencies.push(targetUuid);
triggeredPoints.add(targetUuid);
if (!reverseDependencyGraph.has(targetUuid)) {
reverseDependencyGraph.set(targetUuid, []);
}
reverseDependencyGraph.get(targetUuid)!.push(point.uuid);
}
});
dependencyGraph.set(point.uuid, dependencies);
});
// Find root points (points that trigger others but are not triggered themselves)
const rootPoints = allPoints.filter(point => {
const hasOutgoingTriggers = extractTriggersFromPoint(point).some(
t => t.triggeredAsset?.triggeredPoint?.pointUuid
);
return hasOutgoingTriggers && !triggeredPoints.has(point.uuid);
});
const executionSequences: EventsSchema[][] = [];
function buildSequence(startUuid: string): EventsSchema[] {
const sequence: EventsSchema[] = [];
const visited = new Set<string>();
function traverse(uuid: string) {
if (visited.has(uuid)) return;
visited.add(uuid);
const event = pointToEventMap.get(uuid);
if (event && !sequence.includes(event)) {
sequence.push(event);
}
const nextPoints = dependencyGraph.get(uuid) || [];
nextPoints.forEach(nextUuid => traverse(nextUuid));
}
traverse(startUuid);
return sequence;
}
// Build sequences from root points
rootPoints.forEach(root => {
executionSequences.push(buildSequence(root.uuid));
});
// Handle any isolated triggered points
const processedEvents = new Set(
executionSequences.flat().map(event => event)
);
allPoints.forEach(point => {
const event = pointToEventMap.get(point.uuid);
if (triggeredPoints.has(point.uuid) && event && !processedEvents.has(event)) {
executionSequences.push(buildSequence(point.uuid));
}
});
return executionSequences;
}

View File

@ -18,10 +18,8 @@ export function determineExecutionOrder(products: productsSchema): PointsScheme[
});
} else if (event.type === 'vehicle' ||
event.type === 'machine' ||
event.type === 'storageUnit') {
pointMap.set(event.point.uuid, event.point);
allPoints.push(event.point);
} else if (event.type === 'roboticArm') {
event.type === 'storageUnit' ||
event.type === 'roboticArm') {
pointMap.set(event.point.uuid, event.point);
allPoints.push(event.point);
}

View File

@ -1,6 +1,6 @@
import { extractTriggersFromPoint } from "./extractTriggersFromPoint";
export function determineExecutionSequences(products: productsSchema): PointsScheme[][] {
export async function determineExecutionSequences(products: productsSchema): Promise<PointsScheme[][]> {
// Create maps for all points
const pointMap = new Map<string, PointsScheme>();
const allPoints: PointsScheme[] = [];

View File

@ -14,7 +14,7 @@ function Simulator() {
if (!isPlaying || isReset) return;
const executionOrder = determineExecutionOrder(products);
executionOrder.map(point => {
executionOrder.forEach(point => {
const action = 'actions' in point ? point.actions[0] : point.action;
handleAction(action);
});