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

This commit is contained in:
2025-04-24 15:44:28 +05:30
23 changed files with 895 additions and 244 deletions

View File

@@ -72,9 +72,8 @@ const SideBarRight: React.FC = () => {
<div className="sidebar-actions-container">
{/* {activeModule === "builder" && ( */}
<div
className={`sidebar-action-list ${
subModule === "properties" ? "active" : ""
}`}
className={`sidebar-action-list ${subModule === "properties" ? "active" : ""
}`}
onClick={() => setSubModule("properties")}
>
<PropertiesIcon isActive={subModule === "properties"} />
@@ -83,25 +82,22 @@ const SideBarRight: React.FC = () => {
{activeModule === "simulation" && (
<>
<div
className={`sidebar-action-list ${
subModule === "mechanics" ? "active" : ""
}`}
className={`sidebar-action-list ${subModule === "mechanics" ? "active" : ""
}`}
onClick={() => setSubModule("mechanics")}
>
<MechanicsIcon isActive={subModule === "mechanics"} />
</div>
<div
className={`sidebar-action-list ${
subModule === "simulations" ? "active" : ""
}`}
className={`sidebar-action-list ${subModule === "simulations" ? "active" : ""
}`}
onClick={() => setSubModule("simulations")}
>
<SimulationIcon isActive={subModule === "simulations"} />
</div>
<div
className={`sidebar-action-list ${
subModule === "analysis" ? "active" : ""
}`}
className={`sidebar-action-list ${subModule === "analysis" ? "active" : ""
}`}
onClick={() => setSubModule("analysis")}
>
<AnalysisIcon isActive={subModule === "analysis"} />

View File

@@ -1,147 +1,172 @@
import React, { useRef, useState } from "react";
import React, { useEffect, useRef } from "react";
import {
AddIcon,
ArrowIcon,
RemoveIcon,
ResizeHeightIcon,
AddIcon,
ArrowIcon,
RemoveIcon,
ResizeHeightIcon,
} from "../../../icons/ExportCommonIcons";
import RenameInput from "../../../ui/inputs/RenameInput";
import { handleResize } from "../../../../functions/handleResizePannel";
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../store/simulation/useProductStore";
import { generateUUID } from "three/src/math/MathUtils";
interface Path {
pathName: string; // Represents the name of the path
Children: string[]; // Represents the list of child points
interface Event {
pathName: string;
}
interface DropListProps {
val: Path; // Use the Path interface for the val prop
interface ListProps {
val: Event;
}
const DropList: React.FC<DropListProps> = ({ val }) => {
const [openDrop, setOpenDrop] = useState(false);
return (
<div className="process-container">
<div
className="value"
onClick={() => {
setOpenDrop(!openDrop);
}}
>
{val.pathName}
<div className={`arrow-container${openDrop ? " active" : ""}`}>
<ArrowIcon />
</div>
</div>
{val.Children && openDrop && (
<div className="children-drop">
{val.Children.map((child, index) => (
<div key={index} className="value">
{child}
const List: React.FC<ListProps> = ({ val }) => {
return (
<div className="process-container">
<div className="value">
{val.pathName}
</div>
))}
</div>
)}
</div>
);
);
};
const Simulations: React.FC = () => {
const productsContainerRef = useRef<HTMLDivElement>(null);
const [productsList, setProductsList] = useState<string[]>([]);
const [selectedItem, setSelectedItem] = useState<string>();
const productsContainerRef = useRef<HTMLDivElement>(null);
const { products, addProduct, removeProduct, renameProduct } = useProductStore();
const { selectedProduct, setSelectedProduct } = useSelectedProduct();
const handleAddAction = () => {
setProductsList([...productsList, `Product ${productsList.length + 1}`]);
};
useEffect(() => {
if (products.length > 0 && selectedProduct.productId === '' && selectedProduct.productName === '') {
setSelectedProduct(products[0].productId, products[0].productName);
}
}, [products, selectedProduct]);
const handleRemoveAction = (index: number) => {
setProductsList(productsList.filter((_, i) => i !== index));
if (selectedItem === productsList[index]) {
setSelectedItem("");
}
};
const handleAddProduct = () => {
addProduct(`Product ${products.length + 1}`, generateUUID());
};
const Value = [
{ pathName: "Path 1", Children: ["Point 1", "Point 2"] },
{ pathName: "Path 2", Children: ["Point 1", "Point 2"] },
{ pathName: "Path 3", Children: ["Point 1", "Point 2"] },
];
const handleRemoveProduct = (productId: string) => {
const currentIndex = products.findIndex(p => p.productId === productId);
const isSelected = selectedProduct.productId === productId;
return (
<div className="simulations-container">
<div className="header">Simulations</div>
<div className="add-product-container">
<div className="actions">
<div className="header">
<div className="header-value">Products</div>
<div className="add-button" onClick={handleAddAction}>
<AddIcon /> Add
</div>
</div>
<div
className="lists-main-container"
ref={productsContainerRef}
style={{ height: "120px" }}
>
<div className="list-container">
{productsList.map((action, index) => (
<div
key={index}
className={`list-item ${
selectedItem === action ? "active" : ""
}`}
>
<div
className="value"
onClick={() => setSelectedItem(action)}
>
<input type="radio" name="products" id="products" />
<RenameInput value={action} />
</div>
<div
className="remove-button"
onClick={() => handleRemoveAction(index)}
>
<RemoveIcon />
</div>
const updatedProducts = products.filter(p => p.productId !== productId);
if (isSelected) {
if (updatedProducts.length > 0) {
let newSelectedIndex = currentIndex;
if (currentIndex >= updatedProducts.length) {
newSelectedIndex = updatedProducts.length - 1;
}
setSelectedProduct(
updatedProducts[newSelectedIndex].productId,
updatedProducts[newSelectedIndex].productName
);
} else {
setSelectedProduct('', '');
}
}
removeProduct(productId);
};
const handleRenameProduct = (productId: string, newName: string) => {
renameProduct(productId, newName);
if (selectedProduct.productId === productId) {
setSelectedProduct(productId, newName);
}
};
const selectedProductData = products.find(
(product) => product.productId === selectedProduct.productId
);
const events: Event[] = selectedProductData?.eventsData.map((event, index) => ({
pathName: `${event.modelName} - ${event.type} #${index + 1}`,
})) || [];
return (
<div className="simulations-container">
<div className="header">Simulations</div>
<div className="add-product-container">
<div className="actions">
<div className="header">
<div className="header-value">Products</div>
<div className="add-button" onClick={handleAddProduct}>
<AddIcon /> Add
</div>
</div>
<div
className="lists-main-container"
ref={productsContainerRef}
style={{ height: "120px" }}
>
<div className="list-container">
{products.map((product, index) => (
<div
key={product.productId}
className={`list-item ${selectedProduct.productId === product.productId ? "active" : ""}`}
>
<div
className="value"
onClick={() => setSelectedProduct(product.productId, product.productName)}
>
<input
type="radio"
name="products"
checked={selectedProduct.productId === product.productId}
readOnly
/>
<RenameInput
value={product.productName}
onRename={(newName) => handleRenameProduct(product.productId, newName)}
/>
</div>
{products.length > 1 && (
<div
className="remove-button"
onClick={() => handleRemoveProduct(product.productId)}
>
<RemoveIcon />
</div>
)}
</div>
))}
</div>
<div
className="resize-icon"
id="action-resize"
onMouseDown={(e) => handleResize(e, productsContainerRef)}
>
<ResizeHeightIcon />
</div>
</div>
</div>
<div className="simulation-process">
<div className="collapse-header-container">
<div className="header">Events</div>
<div className="arrow-container">
<ArrowIcon />
</div>
</div>
{events.map((event, index) => (
<List key={index} val={event} />
))}
</div>
<div className="compare-simulations-container">
<div className="compare-simulations-header">
Need to Compare Layout?
</div>
<div className="content">
Click <span>'Compare'</span> to review and analyze the layout differences between them.
</div>
<div className="input">
<input type="button" value={"Compare"} className="submit" />
</div>
</div>
))}
</div>
<div
className="resize-icon"
id="action-resize"
onMouseDown={(e) => handleResize(e, productsContainerRef)}
>
<ResizeHeightIcon />
</div>
</div>
</div>
<div className="simulation-process">
<div className="collapse-header-container">
<div className="header">Operations</div>
<div className="arrow-container">
<ArrowIcon />
</div>
</div>
{Value.map((val, index) => (
<DropList key={index} val={val} />
))}
</div>
<div className="compare-simulations-container">
<div className="compare-simulations-header">
Need to Compare Layout?
</div>
<div className="content">
Click <span>'Compare'</span> to review and analyze the layout
differences between them.
</div>
<div className="input">
<input type="button" value={"Compare"} className="submit" />
</div>
</div>
</div>
</div>
);
);
};
export default Simulations;