Merge branch 'main-demo' into dev-resourceManagement

This commit is contained in:
2025-08-25 10:28:32 +05:30
63 changed files with 2059 additions and 1406 deletions

View File

@@ -15,270 +15,293 @@ import safety from "../../../assets/image/categories/safety.png";
import feneration from "../../../assets/image/categories/feneration.png";
import decal from "../../../assets/image/categories/decal.png";
import SkeletonUI from "../../templates/SkeletonUI";
import { AlertIcon, DecalInfoIcon, HangTagIcon, NavigationIcon } from "../../icons/ExportCommonIcons";
import {
AlertIcon,
DecalInfoIcon,
HangTagIcon,
NavigationIcon,
} from "../../icons/ExportCommonIcons";
// -------------------------------------
interface AssetProp {
filename: string;
thumbnail?: string;
category: string;
description?: string;
tags: string;
url?: string;
uploadDate?: number;
isArchieve?: boolean;
animated?: boolean;
price?: number;
CreatedBy?: string;
filename: string;
thumbnail?: string;
category: string;
description?: string;
tags: string;
url?: string;
uploadDate?: number;
isArchieve?: boolean;
animated?: boolean;
price?: number;
CreatedBy?: string;
}
interface CategoryListProp {
assetImage?: string;
assetName?: string;
categoryImage: string;
category: string;
assetImage?: string;
assetName?: string;
categoryImage: string;
category: string;
}
const Assets: React.FC = () => {
const { setSelectedItem } = useSelectedItem();
const [searchValue, setSearchValue] = useState<string>("");
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
const [categoryAssets, setCategoryAssets] = useState<AssetProp[]>([]);
const [filtereredAssets, setFiltereredAssets] = useState<AssetProp[]>([]);
const [categoryList, setCategoryList] = useState<CategoryListProp[]>([]);
const [isLoading, setisLoading] = useState<boolean>(false); // Loading state for assets
const { setSelectedItem } = useSelectedItem();
const [searchValue, setSearchValue] = useState<string>("");
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
const [categoryAssets, setCategoryAssets] = useState<AssetProp[]>([]);
const [filtereredAssets, setFiltereredAssets] = useState<AssetProp[]>([]);
const [categoryList, setCategoryList] = useState<CategoryListProp[]>([]);
const [isLoading, setisLoading] = useState<boolean>(false); // Loading state for assets
const handleSearchChange = (value: string) => {
const searchTerm = value.toLowerCase();
setSearchValue(value);
if (searchTerm.trim() === "" && !selectedCategory) {
setCategoryAssets([]);
return;
}
const filteredModels = filtereredAssets?.filter((model) => {
if (!model?.tags || !model?.filename || !model?.category) return false;
if (searchTerm.startsWith(":") && searchTerm.length > 1) {
const tagSearchTerm = searchTerm.slice(1);
return model.tags.toLowerCase().includes(tagSearchTerm);
} else if (selectedCategory) {
return (
model.category
.toLowerCase()
.includes(selectedCategory.toLowerCase()) &&
model.filename.toLowerCase().includes(searchTerm)
);
} else {
return model.filename.toLowerCase().includes(searchTerm);
}
});
const handleSearchChange = (value: string) => {
const searchTerm = value.toLowerCase();
setSearchValue(value);
if (searchTerm.trim() === "" && !selectedCategory) {
setCategoryAssets([]);
return;
}
const filteredModels = filtereredAssets?.filter((model) => {
if (!model?.tags || !model?.filename || !model?.category) return false;
if (searchTerm.startsWith(":") && searchTerm.length > 1) {
const tagSearchTerm = searchTerm.slice(1);
return model.tags.toLowerCase().includes(tagSearchTerm);
} else if (selectedCategory) {
return (
model.category
.toLowerCase()
.includes(selectedCategory.toLowerCase()) &&
model.filename.toLowerCase().includes(searchTerm)
);
} else {
return model.filename.toLowerCase().includes(searchTerm);
}
});
setCategoryAssets(filteredModels);
setCategoryAssets(filteredModels);
};
useEffect(() => {
const filteredAssets = async () => {
try {
const filt = await fetchAssets();
setFiltereredAssets(filt);
} catch {
echo.error("Filter asset not found");
}
};
filteredAssets();
}, [categoryAssets]);
useEffect(() => {
const filteredAssets = async () => {
try {
const filt = await fetchAssets();
setFiltereredAssets(filt);
} catch {
echo.error("Filter asset not found");
useEffect(() => {
setCategoryList([
{ category: "Fenestration", categoryImage: feneration },
{ category: "Decals", categoryImage: decal },
{ category: "Vehicles", categoryImage: vehicle },
{ category: "Workstation", categoryImage: workStation },
{ category: "Machines", categoryImage: machines },
{ category: "Workers", categoryImage: worker },
{ category: "Storage", categoryImage: storage },
{ category: "Safety", categoryImage: safety },
{ category: "Office", categoryImage: office },
]);
}, []);
const fetchCategoryAssets = async (asset: any) => {
setisLoading(true);
setSelectedCategory(asset);
try {
const res = await getCategoryAsset(asset);
setCategoryAssets(res);
setFiltereredAssets(res);
setisLoading(false); // End loading
// eslint-disable-next-line
} catch (error) {
echo.error("failed to fetch assets");
setisLoading(false);
}
};
const activeSubcategories = [
{ name: "Safety", icon: <AlertIcon /> },
{ name: "Navigation", icon: <NavigationIcon /> },
{ name: "Branding", icon: <HangTagIcon /> },
{ name: "Informational", icon: <DecalInfoIcon /> },
];
const { selectedSubCategory, setSelectedSubCategory } = useDecalStore();
return (
<div className="assets-container-main">
<Search onChange={handleSearchChange} />
<div className="assets-list-section">
<section>
{(() => {
if (isLoading) {
return <SkeletonUI type="asset" />; // Show skeleton when loading
}
};
filteredAssets();
}, [categoryAssets]);
if (searchValue) {
return (
<div className="assets-result">
<div className="assets-wrapper">
<div className="searched-content">
<p>Results for {searchValue}</p>
</div>
<div className="assets-container">
{categoryAssets?.map((asset: any, index: number) => (
<div
key={`${index}-${asset.filename}`}
className="assets"
id={asset.filename}
title={asset.filename}
>
<img
src={asset?.thumbnail}
alt={asset.filename}
className="asset-image"
onPointerDown={() => {
setSelectedItem({
name: asset.filename,
id: asset.AssetID,
type:
asset.type === "undefined"
? undefined
: asset.type,
});
}}
/>
useEffect(() => {
setCategoryList([
{ category: "Fenestration", categoryImage: feneration },
{ category: "Decals", categoryImage: decal },
{ category: "Vehicles", categoryImage: vehicle },
{ category: "Workstation", categoryImage: workStation },
{ category: "Machines", categoryImage: machines },
{ category: "Workers", categoryImage: worker },
{ category: "Storage", categoryImage: storage },
{ category: "Safety", categoryImage: safety },
{ category: "Office", categoryImage: office },
]);
}, []);
<div className="asset-name">
{asset.filename
.split("_")
.map(
(word: any) =>
word.charAt(0).toUpperCase() + word.slice(1)
)
.join(" ")}
</div>
</div>
))}
</div>
</div>
</div>
);
}
const fetchCategoryAssets = async (asset: any) => {
setisLoading(true);
setSelectedCategory(asset);
try {
const res = await getCategoryAsset(asset);
setCategoryAssets(res);
setFiltereredAssets(res);
setisLoading(false); // End loading
// eslint-disable-next-line
} catch (error) {
echo.error("failed to fetch assets");
setisLoading(false);
}
};
if (selectedCategory) {
return (
<div className="assets-wrapper">
<h2>
{selectedCategory}
<button
className="back-button"
id="asset-backButtom"
onClick={() => {
setSelectedCategory(null);
setSelectedSubCategory(null);
setCategoryAssets([]);
}}
>
Back
</button>
</h2>
{selectedCategory === "Decals" && (
<>
<div className="catogory-asset-filter">
{activeSubcategories.map((cat, index) => (
<div
key={index}
className={`catogory-asset-filter-wrapper ${
selectedSubCategory === cat.name ? "active" : ""
}`}
onClick={() => setSelectedSubCategory(cat.name)}
>
<div className="sub-catagory">{cat.icon}</div>
<div className="sub-catagory">{cat.name}</div>
</div>
))}
</div>
</>
)}
<div className="assets-container">
{categoryAssets?.map((asset: any, index: number) => (
<div
key={`${index}-${asset}`}
className="assets"
id={asset.filename}
title={asset.filename}
>
<img
src={asset?.thumbnail}
alt={asset.filename}
className="asset-image"
onPointerDown={() => {
setSelectedItem({
name: asset.filename,
id: asset.AssetID,
type:
asset.type === "undefined"
? undefined
: asset.type,
category: asset.category,
subType: asset.subType,
});
}}
/>
<div className="asset-name">
{asset.filename
.split("_")
.map(
(word: any) =>
word.charAt(0).toUpperCase() + word.slice(1)
)
.join(" ")}
</div>
</div>
))}
{categoryAssets.length === 0 && (
<div className="no-asset">
🚧 The asset shelf is empty. We're working on filling it
up!
</div>
)}
</div>
</div>
);
}
const activeSubcategories = [
{ name: "Safety", icon: <AlertIcon /> },
{ name: "Navigation", icon: <NavigationIcon /> },
{ name: "Branding", icon: <HangTagIcon /> },
{ name: "Informational", icon: <DecalInfoIcon /> }
]
const { selectedSubCategory, setSelectedSubCategory } = useDecalStore();
return (
<div className="assets-container-main">
<Search onChange={handleSearchChange} />
<div className="assets-list-section">
<section>
{(() => {
if (isLoading) {
return <SkeletonUI type="asset" />; // Show skeleton when loading
}
if (searchValue) {
return (
<div className="assets-result">
<div className="assets-wrapper">
<div className="searched-content">
<p>Results for {searchValue}</p>
</div>
<div className="assets-container">
{categoryAssets?.map((asset: any, index: number) => (
<div
key={`${index}-${asset.filename}`}
className="assets"
id={asset.filename}
title={asset.filename}
>
<img
src={asset?.thumbnail}
alt={asset.filename}
className="asset-image"
onPointerDown={() => {
setSelectedItem({
name: asset.filename,
id: asset.AssetID,
type: asset.type === "undefined" ? undefined : asset.type
});
}}
/>
<div className="asset-name">
{asset.filename
.split("_")
.map(
(word: any) =>
word.charAt(0).toUpperCase() + word.slice(1)
)
.join(" ")}
</div>
</div>
))}
</div>
</div>
</div>
);
}
if (selectedCategory) {
return (
<div className="assets-wrapper">
<h2>
{selectedCategory}
<button
className="back-button"
id="asset-backButtom"
onClick={() => {
setSelectedCategory(null);
setCategoryAssets([]);
}}
>
Back
</button>
</h2>
{selectedCategory === "Decals" &&
<>
<div className="catogory-asset-filter">
{activeSubcategories.map((cat, index) => (
<div className={`catogory-asset-filter-wrapper ${selectedSubCategory === cat.name ? "active" : ""}`} onClick={() => setSelectedSubCategory(cat.name)}>
<div className="sub-catagory">{cat.icon}</div>
<div className="sub-catagory">{cat.name}</div>
</div>
))}
</div>
</>
}
<div className="assets-container">
{categoryAssets?.map((asset: any, index: number) => (
<div
key={`${index}-${asset}`}
className="assets"
id={asset.filename}
title={asset.filename}
>
<img
src={asset?.thumbnail}
alt={asset.filename}
className="asset-image"
onPointerDown={() => {
setSelectedItem({
name: asset.filename,
id: asset.AssetID,
type: asset.type === "undefined" ? undefined : asset.type,
category: asset.category,
subType: asset.subType
});
}}
/>
<div className="asset-name">
{asset.filename.split("_").map((word: any) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ")}
</div>
</div>
))}
{categoryAssets.length === 0 && (
<div className="no-asset">
🚧 The asset shelf is empty. We're working on filling it up!
</div>
)}
</div>
</div>
);
}
return (
<div className="assets-wrapper">
<h2>Categories</h2>
<div className="categories-container">
{Array.from(
new Set(categoryList.map((asset) => asset.category))
).map((category, index) => {
const categoryInfo = categoryList.find(
(asset) => asset.category === category
);
return (
<div
key={`${index}-${category}`}
className="category"
id={category}
onClick={() => fetchCategoryAssets(category)}
>
<img
src={categoryInfo?.categoryImage ?? ""}
alt={category}
className="category-image"
draggable={false}
/>
<div className="category-name">{category}</div>
</div>
);
})}
</div>
</div>
);
})()}
</section>
</div>
</div>
);
return (
<div className="assets-wrapper">
<h2>Categories</h2>
<div className="categories-container">
{Array.from(
new Set(categoryList.map((asset) => asset.category))
).map((category, index) => {
const categoryInfo = categoryList.find(
(asset) => asset.category === category
);
return (
<div
key={`${index}-${category}`}
className="category"
id={category}
onClick={() => fetchCategoryAssets(category)}
>
<img
src={categoryInfo?.categoryImage ?? ""}
alt={category}
className="category-image"
draggable={false}
/>
<div className="category-name">{category}</div>
</div>
);
})}
</div>
</div>
);
})()}
</section>
</div>
</div>
);
};
export default Assets;

View File

@@ -1,26 +1,28 @@
import React, { useEffect, useState } from "react";
import Header from "./Header";
import useModuleStore, { useSubModuleStore } from "../../../store/useModuleStore";
import useModuleStore, {
useSubModuleStore,
} from "../../../store/useModuleStore";
import {
AnalysisIcon,
FilePackageIcon,
MechanicsIcon,
PropertiesIcon,
SimulationIcon,
AnalysisIcon,
FilePackageIcon,
MechanicsIcon,
PropertiesIcon,
SimulationIcon,
} from "../../icons/SimulationIcons";
import { useToggleStore } from "../../../store/useUIToggleStore";
import Visualization from "./visualization/Visualization";
import Analysis from "./analysis/Analysis";
import Simulations from "./simulation/Simulations";
import useVersionHistoryVisibleStore, {
useDecalStore,
useSaveVersion,
useSelectedFloorItem,
useToolMode,
useDecalStore,
useSaveVersion,
useSelectedFloorItem,
useToolMode,
} from "../../../store/builder/store";
import {
useSelectedEventData,
useSelectedEventSphere,
useSelectedEventData,
useSelectedEventSphere,
} from "../../../store/simulation/useSimulationStore";
import { useBuilderStore } from "../../../store/builder/useBuilderStore";
import GlobalProperties from "./properties/GlobalProperties";
@@ -33,277 +35,319 @@ import WallProperties from "./properties/WallProperties";
import FloorProperties from "./properties/FloorProperties";
import SelectedWallProperties from "./properties/SelectedWallProperties";
import SelectedFloorProperties from "./properties/SelectedFloorProperties";
import DecalTransformation from "./decals/DecalTransformation";
import ResourceManagement from "./resourceManagement/ResourceManagement";
import DecalProperties from "./properties/DecalProperties";
type DisplayComponent =
| "versionHistory"
| "globalProperties"
| "aisleProperties"
| "wallProperties"
| "floorProperties"
| "assetProperties"
| "selectedWallProperties"
| "selectedFloorProperties"
| "zoneProperties"
| "simulations"
| "mechanics"
| "analysis"
| "visualization"
| "decals"
| "resourceManagement"
| "none";
| "versionHistory"
| "globalProperties"
| "aisleProperties"
| "wallProperties"
| "floorProperties"
| "assetProperties"
| "selectedWallProperties"
| "selectedFloorProperties"
| "zoneProperties"
| "simulations"
| "mechanics"
| "analysis"
| "visualization"
| "selectedDecalProperties"
| "resourceManagement"
| "none";
const SideBarRight: React.FC = () => {
const { activeModule } = useModuleStore();
const { toggleUIRight } = useToggleStore();
const { toolMode } = useToolMode();
const { subModule, setSubModule } = useSubModuleStore();
const { selectedFloorItem } = useSelectedFloorItem();
const { selectedWall, selectedFloor, selectedAisle } = useBuilderStore();
const { selectedEventData } = useSelectedEventData();
const { selectedEventSphere } = useSelectedEventSphere();
const { viewVersionHistory, setVersionHistoryVisible } = useVersionHistoryVisibleStore();
const { isVersionSaved } = useSaveVersion();
const { selectedSubCategory } = useDecalStore();
const { activeModule } = useModuleStore();
const { toggleUIRight } = useToggleStore();
const { toolMode } = useToolMode();
const { subModule, setSubModule } = useSubModuleStore();
const { selectedFloorItem } = useSelectedFloorItem();
const { selectedWall, selectedFloor, selectedAisle } = useBuilderStore();
const { selectedEventData } = useSelectedEventData();
const { selectedEventSphere } = useSelectedEventSphere();
const { viewVersionHistory, setVersionHistoryVisible } =
useVersionHistoryVisibleStore();
const { isVersionSaved } = useSaveVersion();
const { selectedSubCategory } = useDecalStore();
const [displayComponent, setDisplayComponent] = useState<DisplayComponent>("none");
const [displayComponent, setDisplayComponent] =
useState<DisplayComponent>("none");
useEffect(() => {
if (activeModule !== "simulation") setSubModule("properties");
if (activeModule === "simulation") setSubModule("simulations");
}, [activeModule, setSubModule]);
useEffect(() => {
if (activeModule !== "simulation") setSubModule("properties");
if (activeModule === "simulation") setSubModule("simulations");
}, [activeModule, setSubModule]);
useEffect(() => {
if (activeModule !== "mechanics" && selectedEventData && selectedEventSphere) {
setSubModule("mechanics");
} else if (!selectedEventData && !selectedEventSphere) {
if (activeModule === "simulation") {
setSubModule("simulations");
}
useEffect(() => {
if (
activeModule !== "mechanics" &&
selectedEventData &&
selectedEventSphere
) {
setSubModule("mechanics");
} else if (!selectedEventData && !selectedEventSphere) {
if (activeModule === "simulation") {
setSubModule("simulations");
}
}
if (activeModule !== "simulation") {
setSubModule("properties");
}
}, [activeModule, selectedEventData, selectedEventSphere, setSubModule]);
useEffect(() => {
if (activeModule === "visualization") {
setDisplayComponent("visualization");
return;
}
if (!isVersionSaved && activeModule === "simulation") {
if (subModule === "simulations") {
setDisplayComponent("simulations");
return;
}
if (subModule === "mechanics") {
setDisplayComponent("mechanics");
return;
}
if (subModule === "analysis") {
setDisplayComponent("analysis");
return;
}
if (subModule === "resourceManagement") {
setDisplayComponent("resourceManagement");
return;
}
}
if (activeModule === "simulation" || activeModule === "builder") {
if (subModule === "resourceManagement") {
setDisplayComponent("resourceManagement");
return;
}
}
if (subModule === "properties" && activeModule !== "visualization") {
if (selectedFloorItem) {
setDisplayComponent("assetProperties");
return;
}
if (
!selectedFloorItem &&
!selectedFloor &&
!selectedAisle &&
selectedWall
) {
setDisplayComponent("selectedWallProperties");
return;
}
if (
!selectedFloorItem &&
!selectedWall &&
!selectedAisle &&
selectedFloor
) {
setDisplayComponent("selectedFloorProperties");
return;
}
if (viewVersionHistory) {
setDisplayComponent("versionHistory");
return;
}
if (selectedSubCategory) {
setDisplayComponent("selectedDecalProperties");
return;
}
if (
!selectedFloorItem &&
!selectedFloor &&
!selectedWall &&
!selectedSubCategory
) {
if (toolMode === "Aisle") {
setDisplayComponent("aisleProperties");
return;
}
if (activeModule !== "simulation") {
setSubModule("properties");
if (toolMode === "Wall") {
setDisplayComponent("wallProperties");
return;
}
}, [activeModule, selectedEventData, selectedEventSphere, setSubModule]);
useEffect(() => {
if (activeModule === "visualization") {
setDisplayComponent("visualization");
return;
if (toolMode === "Floor") {
setDisplayComponent("floorProperties");
return;
}
setDisplayComponent("globalProperties");
return;
}
}
if (!isVersionSaved && activeModule === "simulation") {
if (subModule === "simulations") {
setDisplayComponent("simulations");
return;
}
if (subModule === "mechanics") {
setDisplayComponent("mechanics");
return;
}
if (subModule === "analysis") {
setDisplayComponent("analysis");
return;
}
if (subModule === "resourceManagement") {
setDisplayComponent("resourceManagement");
return;
}
}
if (
subModule === "zoneProperties" &&
(activeModule === "builder" || activeModule === "simulation")
) {
setDisplayComponent("zoneProperties");
return;
}
setDisplayComponent("none");
}, [
viewVersionHistory,
activeModule,
subModule,
isVersionSaved,
selectedFloorItem,
selectedWall,
selectedFloor,
selectedAisle,
toolMode,
selectedSubCategory,
]);
const renderComponent = () => {
switch (displayComponent) {
case "versionHistory":
return <VersionHistory />;
case "globalProperties":
return <GlobalProperties />;
case "aisleProperties":
return <AisleProperties />;
case "wallProperties":
return <WallProperties />;
case "floorProperties":
return <FloorProperties />;
case "assetProperties":
return <AssetProperties />;
case "selectedWallProperties":
return <SelectedWallProperties />;
case "selectedFloorProperties":
return <SelectedFloorProperties />;
case "zoneProperties":
return <ZoneProperties />;
case "simulations":
return <Simulations />;
case "mechanics":
return <EventProperties />;
case "analysis":
return <Analysis />;
case "visualization":
return <Visualization />;
case "selectedDecalProperties":
return <DecalProperties />;
case "resourceManagement":
return <ResourceManagement />;
default:
return null;
}
};
if (activeModule === "simulation" || activeModule === "builder") {
if (subModule === "resourceManagement") {
setDisplayComponent("resourceManagement");
return;
}
}
if (subModule === "properties" && activeModule !== "visualization") {
if (selectedFloorItem) {
setDisplayComponent("assetProperties");
return;
}
if (!selectedFloorItem && !selectedFloor && !selectedAisle && selectedWall) {
setDisplayComponent("selectedWallProperties");
return;
}
if (!selectedFloorItem && !selectedWall && !selectedAisle && selectedFloor) {
setDisplayComponent("selectedFloorProperties");
return;
}
if (viewVersionHistory) {
setDisplayComponent("versionHistory");
return;
}
if (selectedSubCategory) {
setDisplayComponent("decals");
return;
}
if (!selectedFloorItem && !selectedFloor && !selectedWall && !selectedSubCategory) {
if (toolMode === "Aisle") {
setDisplayComponent("aisleProperties");
return;
}
if (toolMode === "Wall") {
setDisplayComponent("wallProperties");
return;
}
if (toolMode === "Floor") {
setDisplayComponent("floorProperties");
return;
}
setDisplayComponent("globalProperties");
return;
}
}
if (subModule === "zoneProperties" && (activeModule === "builder" || activeModule === "simulation")) {
setDisplayComponent("zoneProperties");
return;
}
setDisplayComponent("none");
}, [viewVersionHistory, activeModule, subModule, isVersionSaved, selectedFloorItem, selectedWall, selectedFloor, selectedAisle, toolMode, selectedSubCategory]);
const renderComponent = () => {
switch (displayComponent) {
case "versionHistory":
return <VersionHistory />;
case "globalProperties":
return <GlobalProperties />;
case "aisleProperties":
return <AisleProperties />;
case "wallProperties":
return <WallProperties />;
case "floorProperties":
return <FloorProperties />;
case "assetProperties":
return <AssetProperties />;
case "selectedWallProperties":
return <SelectedWallProperties />;
case "selectedFloorProperties":
return <SelectedFloorProperties />;
case "zoneProperties":
return <ZoneProperties />;
case "simulations":
return <Simulations />;
case "mechanics":
return <EventProperties />;
case "analysis":
return <Analysis />;
case "visualization":
return <Visualization />;
case "decals":
return <DecalTransformation />;
case "resourceManagement":
return <ResourceManagement />;
default:
return null;
}
};
return (
<div
className={`sidebar-right-wrapper ${toggleUIRight && (!isVersionSaved || activeModule !== "simulation") ? "open" : "closed"
}`}
>
<Header />
{toggleUIRight && (
return (
<div
className={`sidebar-right-wrapper ${
toggleUIRight && (!isVersionSaved || activeModule !== "simulation")
? "open"
: "closed"
}`}
>
<Header />
{toggleUIRight && (
<>
{(!isVersionSaved || activeModule !== "simulation") && (
<div className="sidebar-actions-container">
{activeModule !== "simulation" && (
<>
{(!isVersionSaved || activeModule !== "simulation") && (
<div className="sidebar-actions-container">
{activeModule !== "simulation" && (
<>
<button
id="sidebar-action-list-properties"
className={`sidebar-action-list ${subModule === "properties" ? "active" : ""}`}
onClick={() => {
setSubModule("properties");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">properties</div>
<PropertiesIcon isActive={subModule === "properties"} />
</button>
</>
)}
{activeModule === "simulation" && (
<>
<button
id="sidebar-action-list-simulation"
className={`sidebar-action-list ${subModule === "simulations" ? "active" : ""}`}
onClick={() => {
setSubModule("simulations");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">simulations</div>
<SimulationIcon isActive={subModule === "simulations"} />
</button>
<button
id="sidebar-action-list-mechanics"
className={`sidebar-action-list ${subModule === "mechanics" ? "active" : ""}`}
onClick={() => {
setSubModule("mechanics");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">mechanics</div>
<MechanicsIcon isActive={subModule === "mechanics"} />
</button>
<button
id="sidebar-action-list-analysis"
className={`sidebar-action-list ${subModule === "analysis" ? "active" : ""}`}
onClick={() => {
setSubModule("analysis");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">analysis</div>
<AnalysisIcon isActive={subModule === "analysis"} />
</button>
</>
)}
{(activeModule === "builder" || activeModule === "simulation") && (
<button
id="sidebar-action-list-properties"
className={`sidebar-action-list ${subModule === "resourceManagement" ? "active" : ""}`}
onClick={() => {
setSubModule("resourceManagement");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">Resource Management</div>
<FilePackageIcon isActive={subModule === "resourceManagement"} />
</button>
)}
</div>
)}
{displayComponent !== "none" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
{renderComponent()}
{/* <ResourceManagement /> */}
</div>
</div>
)}
<button
id="sidebar-action-list-properties"
className={`sidebar-action-list ${
subModule === "properties" ? "active" : ""
}`}
onClick={() => {
setSubModule("properties");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">properties</div>
<PropertiesIcon isActive={subModule === "properties"} />
</button>
</>
)}
</div>
);
)}
{activeModule === "simulation" && (
<>
<button
id="sidebar-action-list-simulation"
className={`sidebar-action-list ${
subModule === "simulations" ? "active" : ""
}`}
onClick={() => {
setSubModule("simulations");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">simulations</div>
<SimulationIcon isActive={subModule === "simulations"} />
</button>
<button
id="sidebar-action-list-mechanics"
className={`sidebar-action-list ${
subModule === "mechanics" ? "active" : ""
}`}
onClick={() => {
setSubModule("mechanics");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">mechanics</div>
<MechanicsIcon isActive={subModule === "mechanics"} />
</button>
<button
id="sidebar-action-list-analysis"
className={`sidebar-action-list ${
subModule === "analysis" ? "active" : ""
}`}
onClick={() => {
setSubModule("analysis");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">analysis</div>
<AnalysisIcon isActive={subModule === "analysis"} />
</button>
</>
)}
{(activeModule === "builder" ||
activeModule === "simulation") && (
<button
id="sidebar-action-list-properties"
className={`sidebar-action-list ${
subModule === "resourceManagement" ? "active" : ""
}`}
onClick={() => {
setSubModule("resourceManagement");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">Resource Management</div>
<FilePackageIcon
isActive={subModule === "resourceManagement"}
/>
</button>
)}
</div>
)}
{displayComponent !== "none" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
{renderComponent()}
{/* <ResourceManagement /> */}
</div>
</div>
)}
</>
)}
</div>
);
};
export default SideBarRight;
export default SideBarRight;

View File

@@ -1,6 +1,4 @@
import React from "react";
import { EyeDroperIcon } from "../../../icons/ExportCommonIcons";
// import { useThree } from "@react-three/fiber";
interface PositionInputProps {
onChange: (value: [number, number, number]) => void; // Callback for value change
@@ -24,7 +22,7 @@ const Vector3Input: React.FC<PositionInputProps> = ({
if (!value) return;
const updatedValue = [...value] as [number, number, number];
updatedValue[index] = parseFloat(newValue) || 0;
// console.log('updatedValue: ', updatedValue);
console.log('updatedValue: ', updatedValue);
onChange(updatedValue);
};
@@ -42,8 +40,8 @@ const Vector3Input: React.FC<PositionInputProps> = ({
<input
className="custom-input-field"
type={type}
value={value?.[i] !== undefined ? value[i].toFixed(2) : ""}
// onChange={(e) => handleChange(i, e.target.value)}
value={value?.[i] !== undefined ? value[i].toFixed(1) : ""}
onChange={(e) => handleChange(i, e.target.value)}
placeholder={placeholder}
disabled={disabled}
/>

View File

@@ -1,59 +0,0 @@
import React, { useState } from 'react';
import RotationInput from '../customInput/RotationInput';
import PositionInput from '../customInput/PositionInputs';
import { LockIcon } from '../../../icons/RealTimeVisulationIcons';
import { LayeringBottomIcon, LayeringTopIcon, ValueUpdateIcon } from '../../../icons/ExportCommonIcons';
import decalImage from "../../../../assets/image/sampleDecal.png"
const DecalTransformation = () => {
return (
<div className='decal-transformation-container'>
{["position", "rotation", "scale"].map((transformation) => (
<div className="transformation-wrapper">
<div className="header">{transformation}</div>
<div className="input-wrapppers">
<input type="number" name="" id="" />
<div className="icon"><ValueUpdateIcon /></div>
<input type="number" name="" id="" />
<div className="icon"><ValueUpdateIcon /></div>
<input type="number" name="" id="" />
<div className="icon"><ValueUpdateIcon /></div>
<div className="icon"><LockIcon /></div>
</div>
</div>
))}
<div className="transformation-wrapper opacity">
<div className="header">opacity</div>
<div className="input-wrapppers">
<input type="number" name="" id="" />
<div className="icon"><ValueUpdateIcon /></div>
</div>
</div>
<div className="transformation-wrapper opacity">
<div className="header">Layering</div>
<div className="layers">
<div className="icon">
<LayeringBottomIcon />
</div>
<div className="icon">
<LayeringTopIcon />
</div>
</div>
</div>
<div className="preview">
<img src={decalImage} alt="" />
<div className="replace-btn">replace</div>
</div>
</div>
);
};
export default DecalTransformation;

View File

@@ -103,32 +103,32 @@ const AssetProperties: React.FC = () => {
</section>
<div className="header">Animations</div>
<section className="animations-lists">
{assets.map((asset) => (
<>
{asset.modelUuid === selectedFloorItem.uuid &&
asset.animations &&
asset.animations.length > 0 &&
asset.animations.map((animation, index) => (
<div key={index} className="animations-list-wrapper">
<div
onClick={() => handleAnimationClick(animation)}
onMouseEnter={() => setHoveredIndex(index)}
onMouseLeave={() => setHoveredIndex(null)}
className="animations-list"
style={{
background:
hoveredIndex === index
? "#7b4cd3"
: "var(--background-color)",
}}
>
{animation.charAt(0).toUpperCase() +
animation.slice(1).toLowerCase()}
</div>
</div>
))}
</>
))}
{assets.map((asset) => {
if (asset.modelUuid !== selectedFloorItem.uuid || !asset.animations)
return null;
return asset.animations.map((animation, index) => (
<div key={index} className="animations-list-wrapper">
<div
onClick={() => handleAnimationClick(animation)}
onMouseEnter={() => setHoveredIndex(index)}
onMouseLeave={() => setHoveredIndex(null)}
className="animations-list"
style={{
background:
hoveredIndex === index
? "var(--background-color-button)"
: "var(--background-color)",
color:
hoveredIndex === index ? "var(--text-button-color)" : "",
}}
>
{animation.charAt(0).toUpperCase() +
animation.slice(1).toLowerCase()}
</div>
</div>
));
})}
</section>
</div>
);

View File

@@ -0,0 +1,53 @@
import {
LayeringBottomIcon,
LayeringTopIcon,
} from "../../../icons/ExportCommonIcons";
import InputRange from "../../../ui/inputs/InputRange";
import RotationInput from "../customInput/RotationInput";
import Vector3Input from "../customInput/Vector3Input";
const DecalProperties = () => {
return (
<div className="decal-transformation-container">
<div className="header">Decal Propertis</div>
<section>
<RotationInput
onChange={() => {}}
value={10}
/>
<Vector3Input
onChange={(value) => console.log(value)}
header="Scale"
value={[0, 0, 0] as [number, number, number]}
/>
</section>
<section>
<InputRange
label="Opacity"
value={1}
min={0}
step={0.1}
max={1}
onChange={(value: number) => console.log(value)}
key={"6"}
/>
<div className="transformation-wrapper opacity">
<div className="transformation-header">Layering</div>
<div className="layers-list">
<button className="layer-move-btn">
<LayeringBottomIcon />
</button>
<button className="layer-move-btn">
<LayeringTopIcon />
</button>
</div>
</div>
</section>
</div>
);
};
export default DecalProperties;

View File

@@ -3,7 +3,7 @@ import InputRange from "../../../../../ui/inputs/InputRange";
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
import SwapAction from "./SwapAction";
interface AssemblyActionProps {
interface ManufactureActionProps {
processTime: {
value: number;
min: number;
@@ -11,7 +11,7 @@ interface AssemblyActionProps {
disabled?: boolean,
onChange: (value: number) => void;
};
assemblyCount: {
manufactureCount: {
value: number;
min: number;
max: number;
@@ -26,9 +26,9 @@ interface AssemblyActionProps {
clearPoints: () => void;
}
const AssemblyAction: React.FC<AssemblyActionProps> = ({
const ManufactureAction: React.FC<ManufactureActionProps> = ({
processTime,
assemblyCount,
manufactureCount,
swapOptions,
swapDefaultOption,
onSwapSelect,
@@ -46,18 +46,18 @@ const AssemblyAction: React.FC<AssemblyActionProps> = ({
onChange={processTime.onChange}
/>
{assemblyCount && (
{manufactureCount && (
<InputWithDropDown
label="Assembly Count"
value={assemblyCount.value.toString()}
min={assemblyCount.min}
max={assemblyCount.max}
disabled={assemblyCount.disabled}
defaultValue={assemblyCount.defaultValue}
step={assemblyCount.step}
label="Manufacture Count"
value={manufactureCount.value.toString()}
min={manufactureCount.min}
max={manufactureCount.max}
disabled={manufactureCount.disabled}
defaultValue={manufactureCount.defaultValue}
step={manufactureCount.step}
activeOption="unit"
onClick={() => { }}
onChange={(value) => assemblyCount.onChange(parseInt(value))}
onChange={(value) => manufactureCount.onChange(parseInt(value))}
/>
)}
<SwapAction
@@ -82,4 +82,4 @@ const AssemblyAction: React.FC<AssemblyActionProps> = ({
);
};
export default AssemblyAction;
export default ManufactureAction;

View File

@@ -7,7 +7,7 @@ import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import Trigger from "../trigger/Trigger";
import ActionsList from "../components/ActionsList";
import WorkerAction from "../actions/WorkerAction";
import AssemblyAction from "../actions/AssemblyAction";
import ManufactureAction from "../actions/ManufactureAction";
import { useSelectedEventData, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
@@ -17,10 +17,10 @@ import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
import { useParams } from "react-router-dom";
function HumanMechanics() {
const [activeOption, setActiveOption] = useState<"worker" | "assembly" | "operator">("worker");
const [activeOption, setActiveOption] = useState<"worker" | "manufacturer" | "operator" | "assembler">("worker");
const [speed, setSpeed] = useState("0.5");
const [loadCount, setLoadCount] = useState(0);
const [assemblyCount, setAssemblyCount] = useState(0);
const [manufactureCount, setManufactureCount] = useState(0);
const [loadCapacity, setLoadCapacity] = useState("1");
const [processTime, setProcessTime] = useState(10);
const [swappedMaterial, setSwappedMaterial] = useState("Default material");
@@ -58,7 +58,7 @@ function HumanMechanics() {
setLoadCapacity(firstAction.loadCapacity.toString());
setActiveOption(firstAction.actionType);
setLoadCount(firstAction.loadCount || 0);
setAssemblyCount(firstAction.assemblyCount || 0);
setManufactureCount(firstAction.manufactureCount || 0);
setProcessTime(firstAction.processTime || 10);
setSwappedMaterial(firstAction.swapMaterial || "Default material");
}
@@ -79,7 +79,7 @@ function HumanMechanics() {
const newCurrentAction = getActionByUuid(selectedProduct.productUuid, actionUuid);
if (newCurrentAction && (newCurrentAction.actionType === 'assembly' || newCurrentAction?.actionType === 'worker' || newCurrentAction?.actionType === "operator")) {
if (newCurrentAction && (newCurrentAction.actionType === 'manufacturer' || newCurrentAction?.actionType === 'worker' || newCurrentAction?.actionType === "operator")) {
if (!selectedAction.actionId) {
setSelectedAction(newCurrentAction.actionUuid, newCurrentAction.actionName);
}
@@ -87,9 +87,9 @@ function HumanMechanics() {
setActiveOption(newCurrentAction.actionType);
setLoadCapacity(newCurrentAction.loadCapacity.toString());
setLoadCount(newCurrentAction.loadCount || 0);
setAssemblyCount(newCurrentAction.assemblyCount || 0);
setManufactureCount(newCurrentAction.manufactureCount || 0);
if (newCurrentAction.actionType === 'assembly') {
if (newCurrentAction.actionType === 'manufacturer') {
setProcessTime(newCurrentAction.processTime || 10);
setSwappedMaterial(newCurrentAction.swapMaterial || "Default material");
}
@@ -118,7 +118,7 @@ function HumanMechanics() {
const handleSelectActionType = (actionType: string) => {
if (!selectedAction.actionId || !currentAction || !selectedPointData) return;
const updatedAction = { ...currentAction, actionType: actionType as "worker" | "assembly" | "operator" };
const updatedAction = { ...currentAction, actionType: actionType as "worker" | "manufacturer" | "operator" | "assembler" };
const updatedActions = selectedPointData.actions.map(action => action.actionUuid === updatedAction.actionUuid ? updatedAction : action);
const updatedPoint = { ...selectedPointData, actions: updatedActions };
@@ -203,10 +203,10 @@ function HumanMechanics() {
setLoadCount(value);
};
const handleAssemblyCountChange = (value: number) => {
const handleManufactureCountChange = (value: number) => {
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
const updatedAction = { ...currentAction, assemblyCount: value };
const updatedAction = { ...currentAction, manufactureCount: value };
const updatedActions = selectedPointData.actions.map(action => action.actionUuid === updatedAction.actionUuid ? updatedAction : action);
const updatedPoint = { ...selectedPointData, actions: updatedActions };
@@ -222,7 +222,7 @@ function HumanMechanics() {
setCurrentAction(updatedAction);
setSelectedPointData(updatedPoint);
setAssemblyCount(value);
setManufactureCount(value);
};
const handleProcessTimeChange = (value: number) => {
@@ -274,8 +274,8 @@ function HumanMechanics() {
const updatedAction: HumanAction = JSON.parse(JSON.stringify(currentAction));
if (updatedAction.actionType === 'assembly') {
updatedAction.assemblyPoint = { position: null, rotation: null, }
if (updatedAction.actionType === 'manufacturer') {
updatedAction.manufacturePoint = { position: null, rotation: null, }
} else {
updatedAction.pickUpPoint = { position: null, rotation: null, };
updatedAction.dropPoint = { position: null, rotation: null, }
@@ -307,6 +307,11 @@ function HumanMechanics() {
actionType: "worker",
loadCount: 1,
assemblyCount: 1,
assemblyCondition: {
conditionType: 'material',
materialType: "Default material"
},
manufactureCount: 1,
loadCapacity: 1,
processTime: 10,
triggers: [],
@@ -397,7 +402,7 @@ function HumanMechanics() {
<LabledDropdown
label="Action Type"
defaultOption={activeOption}
options={["worker", "assembly", "operator"]}
options={["worker", "manufacturer", "operator"]}
onSelect={handleSelectActionType}
disabled={false}
/>
@@ -425,22 +430,22 @@ function HumanMechanics() {
clearPoints={handleClearPoints}
/>
}
{currentAction.actionType === 'assembly' &&
<AssemblyAction
{currentAction.actionType === 'manufacturer' &&
<ManufactureAction
processTime={{
value: processTime,
min: 1,
max: 60,
onChange: handleProcessTimeChange,
}}
assemblyCount={{
value: assemblyCount,
manufactureCount={{
value: manufactureCount,
min: 1,
max: 20,
step: 1,
defaultValue: "1",
disabled: false,
onChange: handleAssemblyCountChange,
onChange: handleManufactureCountChange,
}}
swapOptions={["Default material", "Material 1", "Material 2", "Material 3"]}
swapDefaultOption={swappedMaterial}