feat: Enhance dashboard components with new properties and improve polygon generation logic
This commit is contained in:
parent
566fd87526
commit
fafe6ff794
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
|
||||
import Dashboard from "./pages/Dashboard";
|
||||
import Project from "./pages/Project";
|
||||
|
@ -7,6 +7,7 @@ import "./styles/main.scss";
|
|||
import { LoggerProvider } from "./components/ui/log/LoggerContext";
|
||||
|
||||
const App: React.FC = () => {
|
||||
|
||||
return (
|
||||
<LoggerProvider>
|
||||
<Router>
|
||||
|
|
|
@ -13,6 +13,7 @@ interface DashBoardCardProps {
|
|||
thumbnail: any;
|
||||
projectId: string;
|
||||
createdAt?: string;
|
||||
isViewed?: string;
|
||||
handleDeleteProject?: (projectId: string) => Promise<void>;
|
||||
handleTrashDeleteProject?: (projectId: string) => Promise<void>;
|
||||
handleRestoreProject?: (projectId: string) => Promise<void>;
|
||||
|
@ -215,6 +216,7 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
|
|||
<div className="project-data">
|
||||
{active && active == "trash" ? `Trashed by you` : `Edited `}{" "}
|
||||
{getRelativeTime(createdAt)}
|
||||
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -16,6 +16,7 @@ interface Project {
|
|||
createdBy: string;
|
||||
projectUuid?: string;
|
||||
createdAt: string;
|
||||
isViewed?: string
|
||||
}
|
||||
|
||||
interface RecentProjectsData {
|
||||
|
@ -115,6 +116,7 @@ const DashboardHome: React.FC = () => {
|
|||
const renderProjects = () => {
|
||||
const projectList = recentProjects[Object.keys(recentProjects)[0]];
|
||||
|
||||
console.log('projectList: ', projectList);
|
||||
if (!projectList?.length) {
|
||||
return <div className="empty-state">No recent projects found</div>;
|
||||
}
|
||||
|
@ -127,7 +129,7 @@ const DashboardHome: React.FC = () => {
|
|||
projectName={project.projectName}
|
||||
thumbnail={project.thumbnail}
|
||||
projectId={project._id}
|
||||
createdAt={project.createdAt}
|
||||
createdAt={project.isViewed}
|
||||
handleDeleteProject={handleDeleteProject}
|
||||
handleDuplicateRecentProject={handleDuplicateRecentProject}
|
||||
setRecentDuplicateData={setRecentDuplicateData}
|
||||
|
|
|
@ -12,6 +12,7 @@ interface Project {
|
|||
createdBy: string;
|
||||
projectUuid?: string;
|
||||
createdAt: string;
|
||||
isViewed?: string
|
||||
}
|
||||
|
||||
interface ProjectsData {
|
||||
|
|
|
@ -2,17 +2,18 @@ import React from "react";
|
|||
import { ToggleSidebarIcon } from "../../icons/HeaderIcons";
|
||||
import { LogoIcon } from "../../icons/Logo";
|
||||
import FileMenu from "../../ui/FileMenu";
|
||||
import {useToggleStore} from "../../../store/useUIToggleStore";
|
||||
import { useToggleStore } from "../../../store/useUIToggleStore";
|
||||
import useModuleStore from "../../../store/useModuleStore";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const Header: React.FC = () => {
|
||||
const { toggleUILeft, toggleUIRight, setToggleUI } = useToggleStore();
|
||||
const { activeModule } = useModuleStore();
|
||||
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<div className="header-container">
|
||||
<div className="header-content">
|
||||
<div className="logo-container">
|
||||
<div className="logo-container" onClick={() => navigate("/Dashboard")}>
|
||||
<LogoIcon />
|
||||
</div>
|
||||
<div className="header-title">
|
||||
|
@ -34,7 +35,7 @@ const Header: React.FC = () => {
|
|||
</div>
|
||||
<ToggleSidebarIcon />
|
||||
</button>
|
||||
</div>
|
||||
</div >
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -26,9 +26,7 @@ function AisleInstances() {
|
|||
return points;
|
||||
}, [aisles]);
|
||||
|
||||
useEffect(() => {
|
||||
// console.log('aisles: ', aisles);
|
||||
}, [aisles]);
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -73,6 +73,7 @@ function ArcAisle({ aisle }: { readonly aisle: Aisle }) {
|
|||
return (
|
||||
<group
|
||||
name='Arc-Aisle'
|
||||
uuid={aisle.aisleUuid}
|
||||
ref={aisleRef}
|
||||
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
|
||||
rotation={[Math.PI / 2, 0, 0]}
|
||||
|
|
|
@ -60,6 +60,7 @@ function ArrowAisle({ aisle }: { readonly aisle: Aisle }) {
|
|||
return (
|
||||
<group
|
||||
name='Arrow-Aisle'
|
||||
uuid={aisle.aisleUuid}
|
||||
ref={aisleRef}
|
||||
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
|
||||
rotation={[Math.PI / 2, 0, 0]}
|
||||
|
|
|
@ -63,6 +63,7 @@ function ArrowsAisle({ aisle }: { readonly aisle: Aisle }) {
|
|||
return (
|
||||
<group
|
||||
name='Arrows-Aisle'
|
||||
uuid={aisle.aisleUuid}
|
||||
ref={aisleRef}
|
||||
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
|
||||
rotation={[Math.PI / 2, 0, 0]}
|
||||
|
|
|
@ -23,17 +23,16 @@ function CircleAisle({ aisle }: { readonly aisle: Aisle }) {
|
|||
const outerRadius = middleRadius + width / 2;
|
||||
|
||||
const shape = new THREE.Shape();
|
||||
shape.absarc(0, 0, outerRadius, 0, Math.PI * 2, false);
|
||||
shape.absarc(center.x, center.z, outerRadius, 0, Math.PI * 2, false);
|
||||
|
||||
if (innerRadius > 0) {
|
||||
const hole = new THREE.Path();
|
||||
hole.absarc(0, 0, innerRadius, 0, Math.PI * 2, true);
|
||||
hole.absarc(center.x, center.z, innerRadius, 0, Math.PI * 2, true);
|
||||
shape.holes.push(hole);
|
||||
}
|
||||
|
||||
return {
|
||||
shape,
|
||||
position: center,
|
||||
rotationY: 0
|
||||
};
|
||||
}, [aisle]);
|
||||
|
@ -49,6 +48,7 @@ function CircleAisle({ aisle }: { readonly aisle: Aisle }) {
|
|||
return (
|
||||
<group
|
||||
name='Circle-Aisle'
|
||||
uuid={aisle.aisleUuid}
|
||||
ref={aisleRef}
|
||||
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
|
||||
rotation={[Math.PI / 2, 0, 0]}
|
||||
|
@ -58,23 +58,21 @@ function CircleAisle({ aisle }: { readonly aisle: Aisle }) {
|
|||
setSelectedAisle(null);
|
||||
}}
|
||||
>
|
||||
<group position={[circle.position.x, circle.position.z, 0]}>
|
||||
<Extrude
|
||||
args={[circle.shape, {
|
||||
depth: 0.01,
|
||||
bevelEnabled: false,
|
||||
steps: 1,
|
||||
curveSegments: 64
|
||||
}]}
|
||||
receiveShadow
|
||||
castShadow
|
||||
>
|
||||
<meshStandardMaterial
|
||||
color={aisle.type.aisleColor || '#ffffff'}
|
||||
side={THREE.DoubleSide}
|
||||
/>
|
||||
</Extrude>
|
||||
</group>
|
||||
<Extrude
|
||||
args={[circle.shape, {
|
||||
depth: 0.01,
|
||||
bevelEnabled: false,
|
||||
steps: 1,
|
||||
curveSegments: 64
|
||||
}]}
|
||||
receiveShadow
|
||||
castShadow
|
||||
>
|
||||
<meshStandardMaterial
|
||||
color={aisle.type.aisleColor || '#ffffff'}
|
||||
side={THREE.DoubleSide}
|
||||
/>
|
||||
</Extrude>
|
||||
</group>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ function DashedAisle({ aisle }: { readonly aisle: Aisle }) {
|
|||
return (
|
||||
<group
|
||||
name='Dashed-Aisle'
|
||||
uuid={aisle.aisleUuid}
|
||||
ref={aisleRef}
|
||||
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
|
||||
rotation={[Math.PI / 2, 0, 0]}
|
||||
|
|
|
@ -48,6 +48,7 @@ function DottedAisle({ aisle }: { readonly aisle: Aisle }) {
|
|||
return (
|
||||
<group
|
||||
name='Dotted-Aisle'
|
||||
uuid={aisle.aisleUuid}
|
||||
ref={aisleRef}
|
||||
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
|
||||
rotation={[Math.PI / 2, 0, 0]}
|
||||
|
|
|
@ -95,6 +95,7 @@ function JunctionAisle({ aisle }: { readonly aisle: Aisle }) {
|
|||
return (
|
||||
<group
|
||||
name='Junction-Aisle'
|
||||
uuid={aisle.aisleUuid}
|
||||
ref={aisleRef}
|
||||
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
|
||||
rotation={[Math.PI / 2, 0, 0]}
|
||||
|
|
|
@ -45,6 +45,7 @@ function SolidAisle({ aisle }: { readonly aisle: Aisle }) {
|
|||
return (
|
||||
<group
|
||||
name='Solid-Aisle'
|
||||
uuid={aisle.aisleUuid}
|
||||
ref={aisleRef}
|
||||
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
|
||||
rotation={[Math.PI / 2, 0, 0]}
|
||||
|
|
|
@ -550,17 +550,16 @@ function CircleAisle({ aisle }: { readonly aisle: Aisle }) {
|
|||
const outerRadius = middleRadius + width / 2;
|
||||
|
||||
const shape = new THREE.Shape();
|
||||
shape.absarc(0, 0, outerRadius, 0, Math.PI * 2, false);
|
||||
shape.absarc(center.x, center.z, outerRadius, 0, Math.PI * 2, false);
|
||||
|
||||
if (innerRadius > 0) {
|
||||
const hole = new THREE.Path();
|
||||
hole.absarc(0, 0, innerRadius, 0, Math.PI * 2, true);
|
||||
hole.absarc(center.x, center.z, innerRadius, 0, Math.PI * 2, true);
|
||||
shape.holes.push(hole);
|
||||
}
|
||||
|
||||
return {
|
||||
shape,
|
||||
position: center,
|
||||
rotationY: 0
|
||||
};
|
||||
}, [aisle]);
|
||||
|
@ -572,23 +571,21 @@ function CircleAisle({ aisle }: { readonly aisle: Aisle }) {
|
|||
position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
|
||||
rotation={[Math.PI / 2, 0, 0]}
|
||||
>
|
||||
<group position={[circle.position.x, circle.position.z, 0]}>
|
||||
<Extrude
|
||||
args={[circle.shape, {
|
||||
depth: 0.01,
|
||||
bevelEnabled: false,
|
||||
steps: 1,
|
||||
curveSegments: 64
|
||||
}]}
|
||||
receiveShadow
|
||||
castShadow
|
||||
>
|
||||
<meshStandardMaterial
|
||||
color={aisle.type.aisleColor || '#ffffff'}
|
||||
side={THREE.DoubleSide}
|
||||
/>
|
||||
</Extrude>
|
||||
</group>
|
||||
<Extrude
|
||||
args={[circle.shape, {
|
||||
depth: 0.01,
|
||||
bevelEnabled: false,
|
||||
steps: 1,
|
||||
curveSegments: 64
|
||||
}]}
|
||||
receiveShadow
|
||||
castShadow
|
||||
>
|
||||
<meshStandardMaterial
|
||||
color={aisle.type.aisleColor || '#ffffff'}
|
||||
side={THREE.DoubleSide}
|
||||
/>
|
||||
</Extrude>
|
||||
</group>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ function AislesGroup() {
|
|||
if (projectId) {
|
||||
const aisles = await getAisleApi(projectId);
|
||||
setAisles(aisles);
|
||||
// console.log('aisles: ', aisles);
|
||||
}
|
||||
}
|
||||
fetchAisle()
|
||||
|
|
|
@ -32,6 +32,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
|
|||
|
||||
useEffect(() => {
|
||||
if (currentPhase === 'stationed-pickup' && path.length > 0) {
|
||||
console.log('path: ', path);
|
||||
setCurrentPath(path);
|
||||
setObjectRotation(agvDetail.point.action?.pickUpPoint?.rotation)
|
||||
} else if (currentPhase === 'pickup-drop' && path.length > 0) {
|
||||
|
|
|
@ -29,12 +29,15 @@ export default function NavMeshDetails({
|
|||
}
|
||||
|
||||
const meshes = groupRef?.current?.children as THREE.Mesh[];
|
||||
|
||||
const [positions, indices] = getPositionsAndIndices(meshes);
|
||||
|
||||
const cellSize = 0.2;
|
||||
// const cellSize = 0.2;
|
||||
// const cellHeight = 0.7;
|
||||
// const walkableRadius = 0.5;
|
||||
|
||||
const cellSize = 0.3;
|
||||
const cellHeight = 0.7;
|
||||
const walkableRadius = 0.5;
|
||||
const walkableRadius = 0.7;
|
||||
const { success, navMesh } = generateSoloNavMesh(positions, indices, {
|
||||
cs: cellSize,
|
||||
ch: cellHeight,
|
||||
|
|
|
@ -4,6 +4,8 @@ import * as turf from "@turf/turf";
|
|||
import * as Types from "../../../../types/world/worldTypes";
|
||||
import arrayLinesToObject from "../../../builder/geomentries/lines/lineConvertions/arrayLinesToObject";
|
||||
import { useAisleStore } from "../../../../store/builder/useAisleStore";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { clone } from "chart.js/dist/helpers/helpers.core";
|
||||
|
||||
interface PolygonGeneratorProps {
|
||||
groupRef: React.MutableRefObject<THREE.Group | null>;
|
||||
|
@ -15,10 +17,11 @@ export default function PolygonGenerator({
|
|||
lines,
|
||||
}: PolygonGeneratorProps) {
|
||||
const { aisles } = useAisleStore();
|
||||
const { scene } = useThree();
|
||||
|
||||
useEffect(() => {
|
||||
let allLines = arrayLinesToObject(lines.current);
|
||||
const wallLines = allLines?.filter((line) => line?.type === "WallLine");
|
||||
const aisleLines = allLines?.filter((line) => line?.type === "AisleLine")
|
||||
const result = aisles
|
||||
.filter(
|
||||
(aisle) =>
|
||||
|
@ -33,6 +36,34 @@ export default function PolygonGenerator({
|
|||
uuid: point.pointUuid,
|
||||
}))
|
||||
);
|
||||
|
||||
const arcAndCircleResult = aisles
|
||||
.filter(
|
||||
(aisle) =>
|
||||
aisle.type.aisleType === "circle-aisle" ||
|
||||
aisle.type.aisleType === "arc-aisle"
|
||||
)
|
||||
|
||||
|
||||
arcAndCircleResult.forEach((arc) => {
|
||||
const arcGroup = scene.getObjectByProperty("uuid", arc.aisleUuid);
|
||||
if (!arcGroup) return;
|
||||
const cloned = arcGroup?.clone();
|
||||
cloned.position.set(cloned.position.x, cloned.position.y + 5, cloned.position.z);
|
||||
cloned?.traverse((child) => {
|
||||
if (child instanceof THREE.Mesh && child.geometry instanceof THREE.ExtrudeGeometry) {
|
||||
const extrudeGeometry = child.geometry as THREE.ExtrudeGeometry;
|
||||
extrudeGeometry.scale(1, 1, 500);
|
||||
child.geometry = extrudeGeometry;
|
||||
child.position.set(cloned.position.x, cloned.position.y + 0.1, cloned.position.z)
|
||||
child.rotateX(Math.PI / 2);
|
||||
child.name = "agv-arc-collider"
|
||||
groupRef.current?.add(child)
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
const wallPoints = wallLines
|
||||
.map((pair) => pair?.line.map((vals) => vals.position))
|
||||
.filter((wall): wall is THREE.Vector3[] => !!wall);
|
||||
|
@ -88,7 +119,7 @@ export default function PolygonGenerator({
|
|||
});
|
||||
}
|
||||
|
||||
}, [lines.current]);
|
||||
}, [lines.current, aisles, scene]);
|
||||
|
||||
const renderWallGeometry = (walls: THREE.Vector3[][]) => {
|
||||
walls.forEach((wall) => {
|
||||
|
|
|
@ -10,6 +10,8 @@ import {
|
|||
import { signInApi } from "../services/factoryBuilder/signInSignUp/signInApi";
|
||||
import { signUpApi } from "../services/factoryBuilder/signInSignUp/signUpApi";
|
||||
import FingerprintJS from "@fingerprintjs/fingerprintjs";
|
||||
import { recentlyViewed } from "../services/dashboard/recentlyViewed";
|
||||
import { getUserData } from "../components/Dashboard/functions/getUserData";
|
||||
|
||||
const UserAuth: React.FC = () => {
|
||||
const [email, setEmail] = useState("");
|
||||
|
@ -34,7 +36,28 @@ const UserAuth: React.FC = () => {
|
|||
initializeFingerprint();
|
||||
}, [])
|
||||
|
||||
const { userId, organization } = getUserData();
|
||||
const [navigateToProject, setNavigateToProject] = useState<any>();
|
||||
console.log('navigateToProject: ', navigateToProject);
|
||||
const fetchRecentProjects = async () => {
|
||||
try {
|
||||
const projects = await recentlyViewed(organization, userId);
|
||||
console.log("RecentlyViewed: ", Object.values(projects.RecentlyViewed)[0]
|
||||
);
|
||||
if (Object.values(projects.RecentlyViewed).length > 0) {
|
||||
const firstId = (Object.values(projects?.RecentlyViewed || {})[0] as any)?._id;
|
||||
setNavigateToProject(firstId)
|
||||
}
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error fetching recent projects:", error);
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
fetchRecentProjects();
|
||||
|
||||
}, [navigateToProject]);
|
||||
const handleLogin = async (e: FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
const organization = email.split("@")[1].split(".")[0];
|
||||
|
@ -51,11 +74,28 @@ const UserAuth: React.FC = () => {
|
|||
localStorage.setItem("token", res.message.token);
|
||||
localStorage.setItem("refreshToken", res.message.refreshToken);
|
||||
|
||||
if (res.message.isShare) {
|
||||
setLoadingProgress(1);
|
||||
// navigate("/Project");
|
||||
navigate("/Dashboard");
|
||||
try {
|
||||
const projects = await recentlyViewed(organization, res.message.userId);
|
||||
console.log("RecentlyViewed: ", Object.values(projects.RecentlyViewed)[0]
|
||||
);
|
||||
if (Object.values(projects.RecentlyViewed).length > 0) {
|
||||
const firstId = (Object.values(projects?.RecentlyViewed || {})[0] as any)?._id;
|
||||
setLoadingProgress(1)
|
||||
navigate(`/${firstId}`)
|
||||
} else {
|
||||
if (res.message.isShare) {
|
||||
setLoadingProgress(1);
|
||||
// navigate("/Project");
|
||||
navigate("/Dashboard");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error fetching recent projects:", error);
|
||||
}
|
||||
|
||||
|
||||
} else if (res.message === "User Not Found!!! Kindly signup...") {
|
||||
setError("Account not found");
|
||||
} else if (res.message === "Already LoggedIn on another browser....Please logout!!!") {
|
||||
|
|
Loading…
Reference in New Issue