diff --git a/app/src/components/icons/AssetTypeIcons.tsx b/app/src/components/icons/AssetTypeIcons.tsx index 2f32358..aa6a051 100644 --- a/app/src/components/icons/AssetTypeIcons.tsx +++ b/app/src/components/icons/AssetTypeIcons.tsx @@ -336,18 +336,35 @@ export const MachineIcon = () => { ); }; +export const CraneIcon = () => { + return ( + + + + ); +}; + type TypeBasedAssetIconsProps = { assetType: string; }; export function TypeBasedAssetIcons({ assetType }: TypeBasedAssetIconsProps) { - console.log("assetType: ", assetType); return (
- {assetType === "machine" && } - {assetType === "vehicle" && } - {assetType === "transfer" && } - {assetType === "roboticArm" && } + {assetType === "StaticMachine" && } + {assetType === "Vehicle" && } + {assetType === "Conveyor" && } + {assetType === "Crane" && } + {assetType === "ArmBot" && }
); } diff --git a/app/src/components/layout/sidebarRight/resourceManagement/hrm/Hrm.tsx b/app/src/components/layout/sidebarRight/resourceManagement/hrm/Hrm.tsx index 99828ae..efb5cf3 100644 --- a/app/src/components/layout/sidebarRight/resourceManagement/hrm/Hrm.tsx +++ b/app/src/components/layout/sidebarRight/resourceManagement/hrm/Hrm.tsx @@ -1,199 +1,200 @@ import { useEffect, useState } from 'react' import { ClockThreeIcon, LocationPinIcon, TargetIcon } from '../../../../icons/ExportCommonIcons' import { useSceneContext } from '../../../../../modules/scene/sceneContext'; -import { useProductContext } from '../../../../../modules/simulation/products/productContext'; import RenameInput from '../../../../ui/inputs/RenameInput'; import { useResourceManagementId } from '../../../../../store/builder/store'; -import { set } from 'immer/dist/internal'; +import { getAssetThumbnail } from '../../../../../services/factoryBuilder/asset/assets/getAssetThumbnail'; // import NavigateCatagory from '../NavigateCatagory' const Hrm = () => { const [selectedCard, setSelectedCard] = useState(0); const [workers, setWorkers] = useState([]); - - const { productStore } = useSceneContext(); - const { products, getProductById } = productStore(); - const { selectedProductStore } = useProductContext(); - const { selectedProduct } = selectedProductStore(); const { setResourceManagementId } = useResourceManagementId(); + const { assetStore } = useSceneContext(); + const { assets: allAssets } = assetStore(); - useEffect(() => { - if (selectedProduct) { - const productDetails = getProductById(selectedProduct.productUuid); - const workerDetails = productDetails?.eventDatas || []; + async function getAsset(assetId: string) { + let thumbnail = await getAssetThumbnail(assetId) + if (thumbnail.thumbnail) { + let assetImage = thumbnail.thumbnail + return assetImage; + } + } - const formattedWorkers = workerDetails - .filter((worker: any) => worker.type === "human") - .map((worker: any, index: number) => ({ - employee: { - image: "", - name: worker.modelName, - modelId: worker.modelUuid, - employee_id: `HR-${204 + index}`, - status: "Active", - }, - task: { - status: "Ongoing", - title: worker.taskTitle || "No Task Assigned", - location: { - floor: worker.floor || 0, - zone: worker.zone || "N/A" + useEffect(() => { + if (allAssets.length > 0) { + const fetchWorkers = async () => { + const humans = allAssets.filter((worker: any) => worker.eventData.type === "Human"); + + const formattedWorkers = await Promise.all( + humans.map(async (worker: any, index: number) => { + const assetImage = await getAsset(worker.assetId); + + return { + employee: { + image: assetImage, + name: worker.modelName, + modelId: worker.modelUuid, + employee_id: `HR-${204 + index}`, + status: "Active", }, - planned_time_hours: worker.plannedTime || 0, - time_spent_hours: worker.timeSpent || 0, - total_tasks: worker.totalTasks || 0, - completed_tasks: worker.completedTasks || 0 - }, - actions: [ - "Assign Task", - "Reassign Task", - "Pause", - "Emergency Stop" - ], - location: `Floor ${worker.floor || "-"} . Zone ${worker.zone || "-"}` - })); + task: { + status: "Ongoing", + title: worker.taskTitle ?? "No Task Assigned", + location: { + floor: worker.floor ?? 0, + zone: worker.zone ?? "N/A", + }, + planned_time_hours: worker.plannedTime ?? 0, + time_spent_hours: worker.timeSpent ?? 0, + total_tasks: worker.totalTasks ?? 0, + completed_tasks: worker.completedTasks ?? 0, + }, + actions: ["Assign Task", "Reassign Task", "Pause", "Emergency Stop"], + location: `Floor ${worker.floor || "-"} . Zone ${worker.zone || "-"}`, + }; + }) + ); setWorkers(formattedWorkers); - } - }, [selectedProduct, getProductById]); - - useEffect(() => { - // - }, [workers]); - - - - - // const employee_details = [ - // { - // "employee": { - // image: "", - // "name": "John Doe", - // "employee_id": "HR-204", - // "status": "Active", - - // }, - // "task": { - // "status": "Ongoing", - // "title": "Inspecting Machine X", - // "location": { - // "floor": 4, - // "zone": "B" - // }, - // "planned_time_hours": 6, - // "time_spent_hours": 2, - // "total_tasks": 12, - // "completed_tasks": 3 - // }, - // "actions": [ - // "Assign Task", - // "Reassign Task", - // "Pause", - // "Emergency Stop" - // ], - // "location": "Floor 4 . Zone B" - // }, - // { - // "employee": { - // image: "", - // "name": "Alice Smith", - // "employee_id": "HR-205", - // "status": "Active", - - // }, - // "task": { - // "status": "Ongoing", - // "title": "Calibrating Sensor Y", - // "location": { - // "floor": 2, - // "zone": "A" - // }, - // "planned_time_hours": 4, - // "time_spent_hours": 1.5, - // "total_tasks": 10, - // "completed_tasks": 2 - // }, - // "actions": [ - // "Assign Task", - // "Reassign Task", - // "Pause", - // "Emergency Stop" - // ], - // "location": "Floor 4 . Zone B" - // }, - // { - // "employee": { - // image: "", - // "name": "Michael Lee", - // "employee_id": "HR-206", - // "status": "Active", - - // }, - // "task": { - // "status": "Ongoing", - // "title": "Testing Conveyor Belt Z", - // "location": { - // "floor": 5, - // "zone": "C" - // }, - // "planned_time_hours": 5, - // "time_spent_hours": 3, - // "total_tasks": 8, - // "completed_tasks": 5 - // }, - // "actions": [ - // "Assign Task", - // "Reassign Task", - // "Pause", - // "Emergency Stop" - // ], - // "location": "Floor 4 . Zone B" - // }, - // ] - function handleRenameWorker(newName: string) { - // + }; + fetchWorkers(); } - function handleHumanClick(employee: any) { - if (employee.modelId) { - setResourceManagementId(employee.modelId); - } +}, [allAssets]); + + + +// const employee_details = [ +// { +// "employee": { +// image: "", +// "name": "John Doe", +// "employee_id": "HR-204", +// "status": "Active", + +// }, +// "task": { +// "status": "Ongoing", +// "title": "Inspecting Machine X", +// "location": { +// "floor": 4, +// "zone": "B" +// }, +// "planned_time_hours": 6, +// "time_spent_hours": 2, +// "total_tasks": 12, +// "completed_tasks": 3 +// }, +// "actions": [ +// "Assign Task", +// "Reassign Task", +// "Pause", +// "Emergency Stop" +// ], +// "location": "Floor 4 . Zone B" +// }, +// { +// "employee": { +// image: "", +// "name": "Alice Smith", +// "employee_id": "HR-205", +// "status": "Active", + +// }, +// "task": { +// "status": "Ongoing", +// "title": "Calibrating Sensor Y", +// "location": { +// "floor": 2, +// "zone": "A" +// }, +// "planned_time_hours": 4, +// "time_spent_hours": 1.5, +// "total_tasks": 10, +// "completed_tasks": 2 +// }, +// "actions": [ +// "Assign Task", +// "Reassign Task", +// "Pause", +// "Emergency Stop" +// ], +// "location": "Floor 4 . Zone B" +// }, +// { +// "employee": { +// image: "", +// "name": "Michael Lee", +// "employee_id": "HR-206", +// "status": "Active", + +// }, +// "task": { +// "status": "Ongoing", +// "title": "Testing Conveyor Belt Z", +// "location": { +// "floor": 5, +// "zone": "C" +// }, +// "planned_time_hours": 5, +// "time_spent_hours": 3, +// "total_tasks": 8, +// "completed_tasks": 5 +// }, +// "actions": [ +// "Assign Task", +// "Reassign Task", +// "Pause", +// "Emergency Stop" +// ], +// "location": "Floor 4 . Zone B" +// }, +// ] +function handleRenameWorker(newName: string) { + + +} +function handleHumanClick(employee: any) { + if (employee.modelId) { + setResourceManagementId(employee.modelId); } +} - return ( - <> - {/* + {/* */} -
- {workers.map((employee, index) => ( -
setSelectedCard(index)} - key={index} - > -
-
-
- -
-
-
- {/*
{employee.employee.name}
*/} - -
{employee.employee.employee_id}
-
+
+ {workers.map((employee, index) => ( +
setSelectedCard(index)} + key={index} + > +
+
+
+ +
+
+ {/*
{employee.employee.name}
*/} + +
{employee.employee.employee_id}
+
+
-
{ handleHumanClick(employee.employee) }}>View in Scene
-
+
{ handleHumanClick(employee.employee) }}>View in Scene
+
-
- {/*
+
+ {/*
@@ -214,17 +215,17 @@ const Hrm = () => {
*/} -
-
+
+
-
- - Planned time: -
- - {employee.task.planned_time_hours} hr +
+ + Planned time:
- {/*
+ + {employee.task.planned_time_hours} hr +
+ {/*
@@ -242,39 +243,39 @@ const Hrm = () => { {employee.task.time_spent_hours} hr
*/} -
+
-
- - Cost per hr: -
- - {employee.task.completed_tasks} +
+ + Cost per hr:
-
-
-
-
- -
-
Location:
-
-
{employee.location}
-
-
- {/* - */} - - + {employee.task.completed_tasks}
+
+
+
+ +
+
Location:
+
+
{employee.location}
+
+
+ {/* + */} + + +
- ))} -
- - ) + +
+ ))} +
+ +) } export default Hrm diff --git a/app/src/components/layout/sidebarRight/resourceManagement/hrm/assetManagement/AssetManagement.tsx b/app/src/components/layout/sidebarRight/resourceManagement/hrm/assetManagement/AssetManagement.tsx index 718915c..eddec0b 100644 --- a/app/src/components/layout/sidebarRight/resourceManagement/hrm/assetManagement/AssetManagement.tsx +++ b/app/src/components/layout/sidebarRight/resourceManagement/hrm/assetManagement/AssetManagement.tsx @@ -1,65 +1,70 @@ import { useEffect, useState } from 'react' // import NavigateCatagory from '../../NavigateCatagory' import { EyeIcon, KebabIcon, LocationPinIcon, RightHalfFillCircleIcon } from '../../../../../icons/ExportCommonIcons'; -import assetImage from "../../../../../../assets/image/asset-image.png" +import assetImageFallback from "../../../../../../assets/image/asset-image.png" import { useSceneContext } from '../../../../../../modules/scene/sceneContext'; -import { useProductContext } from '../../../../../../modules/simulation/products/productContext'; import RenameInput from '../../../../../ui/inputs/RenameInput'; import { useResourceManagementId } from '../../../../../../store/builder/store'; +import { getAssetThumbnail } from '../../../../../../services/factoryBuilder/asset/assets/getAssetThumbnail'; import { TypeBasedAssetIcons } from '../../../../../icons/AssetTypeIcons'; + const AssetManagement = () => { // const [selectedCategory, setSelectedCategory] = useState("All Assets"); const [expandedAssetId, setExpandedAssetId] = useState(null); const [assets, setAssets] = useState([]); - - const { productStore } = useSceneContext(); - const { getProductById } = productStore(); - const { selectedProductStore } = useProductContext(); - const { selectedProduct } = selectedProductStore(); const { setResourceManagementId } = useResourceManagementId(); + const { assetStore } = useSceneContext(); + const { assets: allAssets } = assetStore(); - + async function getAsset(assetId: string) { + let thumbnail = await getAssetThumbnail(assetId) + if (thumbnail.thumbnail) { + let assetImage = thumbnail.thumbnail ?? assetImageFallback; + return assetImage; + } + } useEffect(() => { - if (selectedProduct) { - const productDetails = getProductById(selectedProduct.productUuid); - const productAssets = productDetails?.eventDatas || []; - const grouped: Record = {}; - productAssets.forEach((asset: any) => { - if (asset.type === "storageUnit" || asset.type === "human") return; - if (!grouped[asset.modelName]) { - grouped[asset.modelName] = { - id: asset.modelUuid, - name: asset.modelName, - type: asset.type, - model: asset.modelCode || "N/A", - status: asset.status || "Online", - usageRate: asset.usageRate || 15, - level: asset.level || "Level 1", - image: assetImage, - description: asset.description || "No description", - cost: asset.cost || 0, - count: 1, - }; - } else { - grouped[asset.modelName].count += 1; - } - }); + if (allAssets.length > 0) { + const fetchAssets = async () => { + const grouped: Record = {}; - setAssets(Object.values(grouped)); + // Use Promise.all to handle all async operations + await Promise.all(allAssets.map(async (asset: any) => { + + if (asset.eventData.type === "Storage" || asset.eventData.type === "Human") return; + + const assetImage = await getAsset(asset.assetId); + + if (!grouped[asset.assetId]) { + // + grouped[asset.assetId] = { + id: asset.modelUuid, + assetId: asset.assetId, + name: asset.modelName, + type: asset.eventData.type, + model: asset.modelCode ?? "N/A", + status: asset.status ?? "Online", + usageRate: asset.usageRate ?? 15, + level: asset.level ?? "Level 1", + image: assetImage, + description: asset.description ?? "No description", + cost: asset.cost ?? 0, + count: 1, + }; + } else { + grouped[asset.assetId].count += 1; + } + })); + + setAssets(Object.values(grouped)); + } + fetchAssets(); } - // eslint-disable-next-line - }, [selectedProduct]); + }, [allAssets]); function handleRenameAsset(newName: string) { - // - // if (expandedAssetId) { - // setAssets(prevAssets => - // prevAssets.map(asset => - // asset.id === expandedAssetId ? { ...asset, name: newName } : asset - // ) - // ); - // } + } useEffect(() => { @@ -68,8 +73,6 @@ const AssetManagement = () => { }, [assets]); function handleAssetClick(id: string) { - - setResourceManagementId(id); } @@ -126,7 +129,6 @@ const AssetManagement = () => {
- {expandedAssetId === asset.id ? <>
setExpandedAssetId(null)}>▾
@@ -173,9 +175,9 @@ const AssetManagement = () => {
-
+
handleAssetClick(asset.id)}> -
handleAssetClick(asset.id)}>View in Scene
+
View in Scene
diff --git a/app/src/services/factoryBuilder/asset/assets/getAssetThumbnail.ts b/app/src/services/factoryBuilder/asset/assets/getAssetThumbnail.ts new file mode 100644 index 0000000..77469a0 --- /dev/null +++ b/app/src/services/factoryBuilder/asset/assets/getAssetThumbnail.ts @@ -0,0 +1,33 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`; + +export const getAssetThumbnail = async (assetId: String) => { + + try { + const response = await fetch( + `${url_Backend_dwinzo}/api/v2/getAssetThumbnail/${assetId}`, + { + method: "GET", + headers: { + Authorization: "Bearer ", + "Content-Type": "application/json", + token: localStorage.getItem("token") || "", + refresh_token: localStorage.getItem("refreshToken") || "", + }, + } + ); + const newAccessToken = response.headers.get("x-access-token"); + if (newAccessToken) { + localStorage.setItem("token", newAccessToken); + } + + if (!response.ok) { + throw new Error("Failed to fetch assets"); + } + + // + return await response.json(); + } catch (error: any) { + echo.error("Failed to get asset image"); + + } +}; diff --git a/app/src/styles/layout/_resourceManagement.scss b/app/src/styles/layout/_resourceManagement.scss index 131220f..9582a24 100644 --- a/app/src/styles/layout/_resourceManagement.scss +++ b/app/src/styles/layout/_resourceManagement.scss @@ -117,6 +117,12 @@ border-radius: 50%; background-color: #fff; position: relative; + overflow: hidden; + .user-image{ + height: 300%; + width: 300%; + transform: translate(-26px, -12px); + } .status { border-radius: 50%;