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

View File

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

View File

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