realTimeVisulization #34

Merged
Vishnu merged 12 commits from realTimeVisulization into main 2025-04-02 12:57:21 +00:00
48 changed files with 3270 additions and 416 deletions

View File

@@ -1,5 +1,5 @@
import { Html } from "@react-three/drei"; import { Html } from "@react-three/drei";
import React from "react"; import React, { useEffect, useMemo, useState } from "react";
import { Bar } from "react-chartjs-2"; import { Bar } from "react-chartjs-2";
import { import {
Chart as ChartJS, Chart as ChartJS,
@@ -11,6 +11,11 @@ import {
Legend, Legend,
TooltipItem, // Import TooltipItem for typing TooltipItem, // Import TooltipItem for typing
} from "chart.js"; } from "chart.js";
import { ThroughputIcon } from "../../../icons/3dChartIcons";
import { useWidgetStore } from "../../../../store/useWidgetStore";
import useChartStore from "../../../../store/useChartStore";
import axios from "axios";
import io from "socket.io-client";
// Register ChartJS components // Register ChartJS components
ChartJS.register( ChartJS.register(
@@ -22,12 +27,28 @@ ChartJS.register(
Legend Legend
); );
interface ProductionCapacityProps { interface ProductionCapacityProps {
id: string;
type: string;
position: [number, number, number]; position: [number, number, number];
} }
const ProductionCapacity: React.FC<ProductionCapacityProps> = ({ position }) => { const ProductionCapacity : React.FC<ProductionCapacityProps> = ({ id, type, position }) => {
const { selectedChartId,setSelectedChartId } = useWidgetStore();
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
const [measurements, setmeasurements] = useState<any>({});
const [duration, setDuration] = useState("1h")
const [name, setName] = useState("Widget")
const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[] }>({
labels: [],
datasets: [],
});
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
// Chart data for a week // Chart data for a week
const chartData = { const defaultChartData = {
labels: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], // Days of the week labels: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], // Days of the week
datasets: [ datasets: [
{ {
@@ -78,13 +99,94 @@ const ProductionCapacity: React.FC<ProductionCapacityProps> = ({ position }) =>
}, },
}; };
useEffect(() => {
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
const socket = io(`http://${iotApiUrl}`);
const inputData = {
measurements,
duration,
interval: 1000,
};
const startStream = () => {
socket.emit("lineInput", inputData);
};
socket.on("connect", startStream);
socket.on("lineOutput", (response) => {
const responseData = response.data;
// Extract timestamps and values
const labels = responseData.time;
const datasets = Object.keys(measurements).map((key) => {
const measurement = measurements[key];
const datasetKey = `${measurement.name}.${measurement.fields}`;
return {
label: datasetKey,
data: responseData[datasetKey]?.values ?? [],
backgroundColor: "#6f42c1", // Theme color
borderColor: "#6f42c1",
borderWidth: 1,
borderRadius: 8, // Rounded corners for the bars
borderSkipped: false, // Ensure all corners are rounded
};
});
setChartData({ labels, datasets });
});
return () => {
socket.off("lineOutput");
socket.emit("stop_stream"); // Stop streaming when component unmounts
socket.disconnect();
};
}, [measurements, duration, iotApiUrl]);
const fetchSavedInputes = async() => {
if (id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget3D/${id}/${organization}`);
if (response.status === 200) {
setmeasurements(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setName(response.data.widgetName)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
useEffect(() => {
fetchSavedInputes();
}, []);
useEffect(() => {
if (selectedChartId?.id === id) {
fetchSavedInputes();
}
}
,[chartMeasurements, chartDuration, widgetName])
return ( return (
<Html position={[position[0], position[1], position[2]] } <Html position={[position[0], position[1], position[2]]}
scale={[0.5, 0.5, 0.5]} scale={[0.5, 0.5, 0.5]}
transform transform
zIndexRange={[1,0]} sprite>
sprite> <div className="productionCapacity-wrapper card"
<div className="productionCapacity-wrapper card"> onClick={
() => setSelectedChartId({
id: id,
type: type
})
}>
<div className="headeproductionCapacityr-wrapper"> <div className="headeproductionCapacityr-wrapper">
<div className="header">Production Capacity</div> <div className="header">Production Capacity</div>
<div className="production-capacity"> <div className="production-capacity">
@@ -105,7 +207,7 @@ const ProductionCapacity: React.FC<ProductionCapacityProps> = ({ position }) =>
</div>{" "} </div>{" "}
<div className="bar-chart charts"> <div className="bar-chart charts">
{/* Bar Chart */} {/* Bar Chart */}
<Bar data={chartData} options={chartOptions} /> <Bar data={Object.keys(measurements).length > 0 ? chartData : defaultChartData } options={chartOptions} />
</div> </div>
</div> </div>
</Html> </Html>

View File

@@ -1,5 +1,5 @@
import { Html } from "@react-three/drei"; import { Html } from "@react-three/drei";
import React from "react"; import React, { useEffect, useMemo, useState } from "react";
import { Line } from "react-chartjs-2"; import { Line } from "react-chartjs-2";
import { import {
Chart as ChartJS, Chart as ChartJS,
@@ -12,6 +12,10 @@ import {
ChartOptions, ChartOptions,
} from "chart.js"; } from "chart.js";
import { WavyIcon } from "../../../icons/3dChartIcons"; import { WavyIcon } from "../../../icons/3dChartIcons";
import { useWidgetStore } from "../../../../store/useWidgetStore";
import useChartStore from "../../../../store/useChartStore";
import axios from "axios";
import io from "socket.io-client";
// Register Chart.js components // Register Chart.js components
ChartJS.register( ChartJS.register(
@@ -36,9 +40,24 @@ const SmoothLineGraphComponent: React.FC<SmoothLineGraphProps> = ({
return <Line data={data} options={options} />; return <Line data={data} options={options} />;
}; };
interface ReturnOfInvestmentProps { interface ReturnOfInvestmentProps {
id: string;
type: string;
position: [number, number, number]; position: [number, number, number];
} }
const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ position }) => { const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, position }) => {
const { selectedChartId,setSelectedChartId } = useWidgetStore();
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
const [measurements, setmeasurements] = useState<any>({});
const [duration, setDuration] = useState("1h")
const [name, setName] = useState("Widget")
const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[] }>({
labels: [],
datasets: [],
});
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
// Improved sample data for the smooth curve graph (single day) // Improved sample data for the smooth curve graph (single day)
const graphData: ChartData<"line"> = { const graphData: ChartData<"line"> = {
labels: [ labels: [
@@ -107,17 +126,100 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ position }) =>
}, },
}; };
useEffect(() => {
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
const socket = io(`http://${iotApiUrl}`);
const inputData = {
measurements,
duration,
interval: 1000,
};
const startStream = () => {
socket.emit("lineInput", inputData);
};
socket.on("connect", startStream);
socket.on("lineOutput", (response) => {
const responseData = response.data;
// Extract timestamps and values
const labels = responseData.time;
const datasets = Object.keys(measurements).map((key, index) => {
const measurement = measurements[key];
const datasetKey = `${measurement.name}.${measurement.fields}`;
return {
label: datasetKey,
data: responseData[datasetKey]?.values ?? [],
borderColor: index === 0 ? "rgba(75, 192, 192, 1)": "rgba(255, 99, 132, 1)", // Light blue color
backgroundColor: index === 0 ? "rgba(75, 192, 192, 0.2)": "rgba(255, 99, 132, 0.2)",
fill: true,
tension: 0.4, // Smooth curve effect
pointRadius: 0, // Hide dots
pointHoverRadius: 0, // Hide hover dots
};
});
setChartData({ labels, datasets });
});
return () => {
socket.off("lineOutput");
socket.emit("stop_stream"); // Stop streaming when component unmounts
socket.disconnect();
};
}, [measurements, duration, iotApiUrl]);
const fetchSavedInputes = async() => {
if (id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget3D/${id}/${organization}`);
if (response.status === 200) {
setmeasurements(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setName(response.data.widgetName)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
useEffect(() => {
fetchSavedInputes();
}, []);
useEffect(() => {
if (selectedChartId?.id === id) {
fetchSavedInputes();
}
}
,[chartMeasurements, chartDuration, widgetName])
return ( return (
<Html position={[position[0], position[1], position[2]]} <Html position={[position[0], position[1], position[2]]}
scale={[0.5, 0.5, 0.5]} scale={[0.5, 0.5, 0.5]}
transform transform
zIndexRange={[1,0]} zIndexRange={[1,0]}
sprite> sprite>
<div className="returnOfInvestment card"> <div className="returnOfInvestment card"
onClick={
() => setSelectedChartId({
id: id,
type: type
})
}>
<div className="header">Return of Investment</div> <div className="header">Return of Investment</div>
<div className="lineGraph charts"> <div className="lineGraph charts">
{/* Smooth curve graph with two datasets */} {/* Smooth curve graph with two datasets */}
<SmoothLineGraphComponent data={graphData} options={graphOptions} /> <SmoothLineGraphComponent data={Object.keys(measurements).length > 0 ? chartData : graphData} options={graphOptions} />
</div> </div>
<div className="returns-wrapper"> <div className="returns-wrapper">
<div className="icon"> <div className="icon">

View File

@@ -1,29 +1,112 @@
import { Html } from "@react-three/drei"; import { Html } from "@react-three/drei";
import React, { useEffect, useMemo, useState } from "react";
import { useWidgetStore } from "../../../../store/useWidgetStore";
import useChartStore from "../../../../store/useChartStore";
import axios from "axios";
import io from "socket.io-client";
// import image from "../../../../assets/image/temp/image.png"; // import image from "../../../../assets/image/temp/image.png";
interface StateWorkingProps { interface StateWorkingProps {
id:string;
type: string;
position: [number, number, number]; position: [number, number, number];
} }
const StateWorking: React.FC<StateWorkingProps> = ({ position }) => { const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position }) => {
const datas = [ const { selectedChartId, setSelectedChartId } = useWidgetStore();
{ key: "Oil Tank:", value: "24/341" }, const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
{ key: "Oil Refin:", value: 36.023 }, const [measurements, setmeasurements] = useState<any>({});
{ key: "Transmission:", value: 36.023 }, const [duration, setDuration] = useState("1h")
{ key: "Fuel:", value: 36732 }, const [name, setName] = useState("Widget")
{ key: "Power:", value: 1300 }, const [datas, setDatas] = useState<any>({});
{ key: "Time:", value: 13 - 9 - 2023 }, const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
]; const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
// const datas = [
// { key: "Oil Tank:", value: "24/341" },
// { key: "Oil Refin:", value: 36.023 },
// { key: "Transmission:", value: 36.023 },
// { key: "Fuel:", value: 36732 },
// { key: "Power:", value: 1300 },
// { key: "Time:", value: 13 - 9 - 2023 },
// ];
useEffect(() => {
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
const socket = io(`http://${iotApiUrl}`);
const inputData = {
measurements,
duration,
interval: 1000,
};
const startStream = () => {
socket.emit("lastInput", inputData);
};
socket.on("connect", startStream);
socket.on("lastOutput", (response) => {
const responseData = response;
console.log("responceeeeeeeeeee",response);
setDatas(responseData);
});
return () => {
socket.off("lastOutput");
socket.emit("stop_stream"); // Stop streaming when component unmounts
socket.disconnect();
};
}, [measurements, duration, iotApiUrl]);
const fetchSavedInputes = async() => {
if (id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget3D/${id}/${organization}`);
if (response.status === 200) {
setmeasurements(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setName(response.data.widgetName)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
console.log("dataaaaa",datas);
useEffect(() => {
fetchSavedInputes();
}, []);
useEffect(() => {
if (selectedChartId?.id === id) {
fetchSavedInputes();
}
}
,[chartMeasurements, chartDuration, widgetName])
return ( return (
<Html position={[position[0], position[1], position[2]]} <Html position={[position[0], position[1], position[2]]}
scale={[0.5, 0.5, 0.5]} scale={[0.5, 0.5, 0.5]}
transform transform
zIndexRange={[1,0]} zIndexRange={[1,0]}
sprite> sprite>
<div className="stateWorking-wrapper card"> <div className="stateWorking-wrapper card"
onClick={
() => setSelectedChartId({
id: id,
type: type
})
}>
<div className="header-wrapper"> <div className="header-wrapper">
<div className="header"> <div className="header">
<span>State</span> <span>State</span>
<span> <span>
Working <span>.</span> {datas?.input1 ? datas.input1 : 'input1'} <span>.</span>
</span> </span>
</div> </div>
<div className="img"> <div className="img">
@@ -32,12 +115,36 @@ const StateWorking: React.FC<StateWorkingProps> = ({ position }) => {
</div> </div>
{/* Data */} {/* Data */}
<div className="data-wrapper"> <div className="data-wrapper">
{datas.map((data, index) => ( {/* {datas.map((data, index) => (
<div className="data-table" key={index}> <div className="data-table" key={index}>
<div className="data">{data.key}</div> <div className="data">{data.key}</div>
<div className="key">{data.value}</div> <div className="key">{data.value}</div>
</div> </div>
))} ))} */}
<div className="data-table">
<div className="data">{measurements?.input2?.fields ? measurements.input2.fields : 'input2'}</div>
<div className="key">{datas?.input2 ? datas.input2 : 'data'}</div>
</div>
<div className="data-table">
<div className="data">{measurements?.input3?.fields ? measurements.input3.fields : 'input3'}</div>
<div className="key">{datas?.input3 ? datas.input3 : 'data'}</div>
</div>
<div className="data-table">
<div className="data">{measurements?.input4?.fields ? measurements.input4.fields : 'input4'}</div>
<div className="key">{datas?.input4 ? datas.input4 : 'data'}</div>
</div>
<div className="data-table">
<div className="data">{measurements?.input5?.fields ? measurements.input5.fields : 'input5'}</div>
<div className="key">{datas?.input5 ? datas.input5 : 'data'}</div>
</div>
<div className="data-table">
<div className="data">{measurements?.input6?.fields ? measurements.input6.fields : 'input6'}</div>
<div className="key">{datas?.input6 ? datas.input6 : 'data'}</div>
</div>
<div className="data-table">
<div className="data">{measurements?.input7?.fields ? measurements.input7.fields : 'input7'}</div>
<div className="key">{datas?.input7 ? datas.input7 : 'data'}</div>
</div>
</div> </div>
</div> </div>
</Html> </Html>

View File

@@ -1,5 +1,5 @@
import { Html } from "@react-three/drei"; import { Html } from "@react-three/drei";
import React from "react"; import React, { useEffect, useMemo, useState } from "react";
import { Line } from "react-chartjs-2"; import { Line } from "react-chartjs-2";
import { import {
Chart as ChartJS, Chart as ChartJS,
@@ -14,6 +14,10 @@ import {
ChartOptions, ChartOptions,
} from "chart.js"; } from "chart.js";
import { ThroughputIcon } from "../../../icons/3dChartIcons"; import { ThroughputIcon } from "../../../icons/3dChartIcons";
import { useWidgetStore } from "../../../../store/useWidgetStore";
import useChartStore from "../../../../store/useChartStore";
import axios from "axios";
import io from "socket.io-client";
// Register Chart.js components // Register Chart.js components
ChartJS.register( ChartJS.register(
@@ -38,10 +42,25 @@ const LineGraphComponent: React.FC<LineGraphProps> = ({ data, options }) => {
}; };
interface ThroughputProps { interface ThroughputProps {
id: string;
type: string;
position: [number, number, number]; position: [number, number, number];
} }
const Throughput: React.FC<ThroughputProps> = ({ position }) => { const Throughput: React.FC<ThroughputProps> = ({ id, type, position }) => {
const { selectedChartId,setSelectedChartId } = useWidgetStore();
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
const [measurements, setmeasurements] = useState<any>({});
const [duration, setDuration] = useState("1h")
const [name, setName] = useState("Widget")
const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[] }>({
labels: [],
datasets: [],
});
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
// Sample data for the line graph // Sample data for the line graph
const graphData: ChartData<"line"> = { const graphData: ChartData<"line"> = {
@@ -90,14 +109,94 @@ const Throughput: React.FC<ThroughputProps> = ({ position }) => {
}, },
}; };
useEffect(() => {
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
const socket = io(`http://${iotApiUrl}`);
const inputData = {
measurements,
duration,
interval: 1000,
};
const startStream = () => {
socket.emit("lineInput", inputData);
};
socket.on("connect", startStream);
socket.on("lineOutput", (response) => {
const responseData = response.data;
// Extract timestamps and values
const labels = responseData.time;
const datasets = Object.keys(measurements).map((key) => {
const measurement = measurements[key];
const datasetKey = `${measurement.name}.${measurement.fields}`;
return {
label: datasetKey,
data: responseData[datasetKey]?.values ?? [],
borderColor: "rgba(75, 192, 192, 1)",
backgroundColor: "rgba(75, 192, 192, 0.2)",
fill: true,
};
});
setChartData({ labels, datasets });
});
return () => {
socket.off("lineOutput");
socket.emit("stop_stream"); // Stop streaming when component unmounts
socket.disconnect();
};
}, [measurements, duration, iotApiUrl]);
const fetchSavedInputes = async() => {
if (id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget3D/${id}/${organization}`);
if (response.status === 200) {
setmeasurements(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setName(response.data.widgetName)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
useEffect(() => {
fetchSavedInputes();
}, []);
useEffect(() => {
if (selectedChartId?.id === id) {
fetchSavedInputes();
}
}
,[chartMeasurements, chartDuration, widgetName])
return ( return (
<Html position={[position[0], position[1], position[2]]} <Html position={[position[0], position[1], position[2]]}
scale={[0.5, 0.5, 0.5]} scale={[0.5, 0.5, 0.5]}
transform transform
zIndexRange={[1, 0]} zIndexRange={[1, 0]}
sprite> sprite>
<div className="throughput-wrapper"> <div className="throughput-wrapper"
<div className="header">Throughput</div> onClick={
() => setSelectedChartId({
id: id,
type: type
})
}>
<div className="header">{name}</div>
<div className="display-value"> <div className="display-value">
<div className="left"> <div className="left">
<div className="icon"> <div className="icon">
@@ -120,7 +219,7 @@ const Throughput: React.FC<ThroughputProps> = ({ position }) => {
</div> </div>
<div className="line-graph"> <div className="line-graph">
{/* Line graph using react-chartjs-2 */} {/* Line graph using react-chartjs-2 */}
<LineGraphComponent data={graphData} options={graphOptions} /> <LineGraphComponent data={Object.keys(measurements).length > 0 ? chartData : graphData} options={graphOptions} />
</div> </div>
<div className="footer"> <div className="footer">
You made an extra <span className="value">$1256.13</span> this month You made an extra <span className="value">$1256.13</span> this month

View File

@@ -9,13 +9,14 @@ import { getCategoryAsset } from "../../../services/factoryBuilder/assest/assets
import arch from "../../../assets/gltf-glb/arch.glb"; import arch from "../../../assets/gltf-glb/arch.glb";
import door from "../../../assets/gltf-glb/door.glb"; import door from "../../../assets/gltf-glb/door.glb";
import window from "../../../assets/gltf-glb/window.glb"; import window from "../../../assets/gltf-glb/window.glb";
import { fetchAssets } from "../../../services/marketplace/fetchAssets";
import { useSelectedItem } from "../../../store/store"; import { useSelectedItem } from "../../../store/store";
interface AssetProp { interface AssetProp {
filename: string; filename: string;
thumbnail?: string; thumbnail?: string;
category: string; category: string;
description?: string; description?: string;
tags?: string; tags: string;
url?: String; url?: String;
uploadDate?: number; uploadDate?: number;
isArchieve?: boolean; isArchieve?: boolean;
@@ -23,19 +24,58 @@ interface AssetProp {
price?: number; price?: number;
CreatedBy?: String; CreatedBy?: String;
} }
interface CategoryListProp {
assetImage?: string;
assetName?: string;
categoryImage: string;
category: string;
}
const Assets: React.FC = () => { const Assets: React.FC = () => {
const { setSelectedItem } = useSelectedItem(); const { setSelectedItem } = useSelectedItem();
const [searchValue, setSearchValue] = useState<string>(""); const [searchValue, setSearchValue] = useState<string>("");
const [selectedCategory, setSelectedCategory] = useState<string | null>(null); const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
const [filteredAsset, setFilteredAsset] = useState<AssetProp[]>([]); const [categoryAssets, setCategoryAssets] = useState<AssetProp[]>([]);
const [filtereredAssets, setFiltereredAssets] = useState<AssetProp[]>([]);
const [categoryList, setCategoryList] = useState<CategoryListProp[]>([]);
const handleSearchChange = (value: string) => { const handleSearchChange = (value: string) => {
const searchTerm = value.toLowerCase();
setSearchValue(value); setSearchValue(value);
setSelectedCategory(null); // Reset selected category when search changes 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 categoryList = useMemo( setCategoryAssets(filteredModels);
() => [ };
useEffect(() => {
const filteredAssets = async () => {
try {
const filt = await fetchAssets();
setFiltereredAssets(filt);
} catch {}
};
filteredAssets();
}, [categoryAssets]);
useEffect(() => {
setCategoryList([
{ {
assetName: "Doors", assetName: "Doors",
assetImage: "", assetImage: "",
@@ -58,10 +98,8 @@ const Assets: React.FC = () => {
{ category: "Workstation", categoryImage: workStation }, { category: "Workstation", categoryImage: workStation },
{ category: "Machines", categoryImage: machines }, { category: "Machines", categoryImage: machines },
{ category: "Workers", categoryImage: worker }, { category: "Workers", categoryImage: worker },
], ]);
[] }, []);
);
const fetchCategoryAssets = async (asset: any) => { const fetchCategoryAssets = async (asset: any) => {
setSelectedCategory(asset); setSelectedCategory(asset);
if (asset === "Feneration") { if (asset === "Feneration") {
@@ -70,60 +108,93 @@ const Assets: React.FC = () => {
filename: "arch", filename: "arch",
category: "Feneration", category: "Feneration",
url: arch, url: arch,
tags: "arch",
}, },
{ {
filename: "door", filename: "door",
category: "Feneration", category: "Feneration",
url: door, url: door,
thumbnail: feneration,
tags: "door",
}, },
{ {
filename: "window", filename: "window",
category: "Feneration", category: "Feneration",
url: window, url: window,
tags: "window",
}, },
]; ];
setFilteredAsset(localAssets); setCategoryAssets(localAssets);
setFiltereredAssets(localAssets);
} else { } else {
try { try {
const res = await getCategoryAsset(asset); const res = await getCategoryAsset(asset);
setFilteredAsset(res || []); // Ensure it's always an array setCategoryAssets(res);
} catch (error) { } setFiltereredAssets(res);
} catch (error) {}
} }
}; };
useEffect(() => { }, [filteredAsset]);
return ( return (
<div className="assets-container"> <div className="assets-container">
<Search onChange={handleSearchChange} /> <Search onChange={handleSearchChange} />
{searchValue ? ( {searchValue ? (
<div className="searched-content"> <div className="assets-result">
<p>Results for "{searchValue}"</p> <div className="assets-wrapper">
<div className="searched-content">
<p>Results for {searchValue}</p>
</div>
</div>
<div className="assets-container">
{categoryAssets &&
categoryAssets?.map((asset: any, index: number) => (
<div key={index} className="assets">
<img
src={asset?.thumbnail}
alt={asset.filename}
className="asset-image"
/>
<div className="asset-name">
{asset.filename
.split("_")
.map(
(word: any) =>
word.charAt(0).toUpperCase() + word.slice(1)
)
.join(" ")}
</div>
</div>
))}
</div>
</div> </div>
) : selectedCategory ? ( ) : selectedCategory ? (
<div className="assets-wrapper"> <div className="assets-wrapper">
{/* Back Button */}
<div <div
className="back-button" className="back-button"
onClick={() => { onClick={() => {
setSelectedCategory(null); setSelectedCategory(null);
setFilteredAsset([]); setCategoryAssets([]);
}} }}
> >
Back Back
</div> </div>
<h2>{selectedCategory}</h2> <h2>{selectedCategory}</h2>
<div className="assets-container"> <div className="assets-container">
{filteredAsset && {categoryAssets &&
filteredAsset?.map((asset: any, index: number) => ( categoryAssets?.map((asset: any, index: number) => (
<div key={index} className="assets"> <div key={index} className="assets">
{asset?.thumbnail && ( <img
<img src={asset?.thumbnail}
src={asset?.thumbnail} alt={asset.filename}
alt={asset.filename} className="asset-image"
className="asset-image" onPointerDown={() =>
onPointerDown={() => setSelectedItem({ name: asset.filename, id: asset.modelfileID })} setSelectedItem({
/> name: asset.filename,
)} id: asset.modelfileID,
})
}
/>
<div className="asset-name"> <div className="asset-name">
{asset.filename {asset.filename
.split("_") .split("_")

View File

@@ -59,9 +59,11 @@ const ProgressBarWidget = ({
id, id,
title, title,
data, data,
type
}: { }: {
id: string; id: string;
title: string; title: string;
type: string;
data: any; data: any;
}) => { }) => {
const { setDraggedAsset } = useWidgetStore((state) => state); const { setDraggedAsset } = useWidgetStore((state) => state);
@@ -72,7 +74,7 @@ const ProgressBarWidget = ({
draggable draggable
onDragStart={() => { onDragStart={() => {
setDraggedAsset({ setDraggedAsset({
type: "progress", type: type,
id, id,
title, title,
panel: "top", panel: "top",
@@ -99,6 +101,7 @@ const ProgressBarWidget = ({
</div> </div>
); );
}; };
console.log(chartTypes, "chartTypes");
const Widgets2D = () => { const Widgets2D = () => {
return ( return (
@@ -123,6 +126,7 @@ const Widgets2D = () => {
{ key: "units", value: 1000, description: "Initial stock" }, { key: "units", value: 1000, description: "Initial stock" },
], ],
}} }}
type={"progress 1"}
/> />
<ProgressBarWidget <ProgressBarWidget
id="widget-8" id="widget-8"
@@ -133,6 +137,7 @@ const Widgets2D = () => {
{ key: "units", value: 500, description: "Additional stock" }, { key: "units", value: 500, description: "Additional stock" },
], ],
}} }}
type={"progress 2"}
/> />
</div> </div>
</div> </div>

View File

@@ -33,6 +33,7 @@ const RenderAnalysisInputs: React.FC<InputRendererProps> = ({
label={preset.inputs.label} label={preset.inputs.label}
min={0} min={0}
max={0} max={0}
value={5}
/> />
); );
} }

View File

@@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useEffect, useState } from "react";
import InputRange from "../../../ui/inputs/InputRange"; import InputRange from "../../../ui/inputs/InputRange";
import InputToggle from "../../../ui/inputs/InputToggle"; import InputToggle from "../../../ui/inputs/InputToggle";
import { AI_Icon } from "../../../icons/ExportCommonIcons"; import { AI_Icon } from "../../../icons/ExportCommonIcons";
@@ -6,17 +6,20 @@ import LabeledButton from "../../../ui/inputs/LabledButton";
import { import {
useAzimuth, useAzimuth,
useElevation, useElevation,
useLimitDistance,
useRenderDistance, useRenderDistance,
useResetCamera, useResetCamera,
useRoofVisibility, useRoofVisibility,
useSelectedWallItem, useSelectedWallItem,
useShadows, useShadows,
useSocketStore, useSocketStore,
useTileDistance,
useToggleView, useToggleView,
useWallVisibility, useWallVisibility,
} from "../../../../store/store"; } from "../../../../store/store";
import { setEnvironment } from "../../../../services/factoryBuilder/environment/setEnvironment"; import { setEnvironment } from "../../../../services/factoryBuilder/environment/setEnvironment";
import * as CONSTANTS from "../../../../types/world/worldConstants"; import * as CONSTANTS from "../../../../types/world/worldConstants";
import { validateBBox } from "@turf/helpers";
const GlobalProperties: React.FC = () => { const GlobalProperties: React.FC = () => {
const { toggleView, setToggleView } = useToggleView(); const { toggleView, setToggleView } = useToggleView();
const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem(); const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
@@ -27,26 +30,95 @@ const GlobalProperties: React.FC = () => {
const { elevation, setElevation } = useElevation(); const { elevation, setElevation } = useElevation();
const { azimuth, setAzimuth } = useAzimuth(); const { azimuth, setAzimuth } = useAzimuth();
const { renderDistance, setRenderDistance } = useRenderDistance(); const { renderDistance, setRenderDistance } = useRenderDistance();
const { setPlaneValue, setGridValue, planeValue, gridValue } =
useTileDistance();
useEffect(() => {
console.log(gridValue, planeValue, "values");
}, [gridValue, planeValue]);
const { socket } = useSocketStore(); const { socket } = useSocketStore();
const [limitDistance, setLimitDistance] = useState(false); const { limitDistance, setLimitDistance } = useLimitDistance();
const [distance, setDistance] = useState<number>(30); const [distance, setDistance] = useState<number>(40);
useEffect(() => {}, [limitDistance]);
const [limitGridDistance, setLimitGridDistance] = useState(false); const [limitGridDistance, setLimitGridDistance] = useState(false);
const [gridDistance, setGridDistance] = useState<number>(5); const [gridDistance, setGridDistance] = useState<number>(3);
function optimizeScene() { const optimizeScene = async (value: any) => {
const email = localStorage.getItem("email");
const organization = email?.split("@")[1]?.split(".")[0] || "defaultOrg";
const data = await setEnvironment(
organization,
localStorage.getItem("userId")!,
wallVisibility,
roofVisibility,
shadows,
30,
true
);
setRenderDistance(30);
setLimitDistance(true); setLimitDistance(true);
setDistance(30); };
} const limitRenderDistance = async () => {
const email = localStorage.getItem("email");
const organization = email?.split("@")[1]?.split(".")[0] || "defaultOrg";
if (limitDistance) {
let data = await setEnvironment(
organization,
localStorage.getItem("userId")!,
wallVisibility,
roofVisibility,
shadows,
75,
!limitDistance
);
setRenderDistance(75);
} else {
let data = await setEnvironment(
organization,
localStorage.getItem("userId")!,
wallVisibility,
roofVisibility,
shadows,
renderDistance,
!limitDistance
);
}
setLimitDistance(!limitDistance);
};
function updateDistance(value: number) { function updateDistance(value: number) {
setDistance(value); setDistance(value);
setRenderDistance(value); setRenderDistance(value);
} }
function updateGridDistance(value: number) { function updateGridDistance(value: number) {
setGridDistance(value); setGridDistance(value);
// setGridValue({ size: value * 100, divisions: (value * 100) / 4 });
// setPlaneValue({ height: value * 100, width: value * 100 });
} }
function updatedGrid(value: number) {
console.log(" (value * 100) / 4 : ", (value * 100) / 4);
setGridValue({ size: value * 100, divisions: (value * 100) / 4 });
setPlaneValue({ height: value * 100, width: value * 100 });
}
const updatedDist = async (value: number) => {
const email = localStorage.getItem("email");
const organization = email?.split("@")[1]?.split(".")[0] || "defaultOrg";
setRenderDistance(value);
// setDistance(value);
const data = await setEnvironment(
organization,
localStorage.getItem("userId")!,
wallVisibility,
roofVisibility,
shadows,
value,
limitDistance
);
};
// Function to toggle roof visibility // Function to toggle roof visibility
const changeRoofVisibility = async () => { const changeRoofVisibility = async () => {
const email = localStorage.getItem("email"); const email = localStorage.getItem("email");
@@ -58,7 +130,9 @@ const GlobalProperties: React.FC = () => {
localStorage.getItem("userId")!, localStorage.getItem("userId")!,
wallVisibility, wallVisibility,
!roofVisibility, !roofVisibility,
shadows shadows,
renderDistance,
limitDistance
); );
// //
@@ -85,7 +159,9 @@ const GlobalProperties: React.FC = () => {
localStorage.getItem("userId")!, localStorage.getItem("userId")!,
!wallVisibility, !wallVisibility,
roofVisibility, roofVisibility,
shadows shadows,
renderDistance,
limitDistance
); );
// //
@@ -112,7 +188,9 @@ const GlobalProperties: React.FC = () => {
localStorage.getItem("userId")!, localStorage.getItem("userId")!,
wallVisibility, wallVisibility,
roofVisibility, roofVisibility,
!shadows !shadows,
renderDistance,
limitDistance
); );
// //
@@ -184,18 +262,24 @@ const GlobalProperties: React.FC = () => {
inputKey="4" inputKey="4"
label="Limit Render Distance" label="Limit Render Distance"
value={limitDistance} value={limitDistance}
onClick={() => { // onClick={() => {
setLimitDistance(!limitDistance); // setLimitDistance(!limitDistance);
// // setDistance(75);
// // setRenderDistance(75);
// }}
onClick={async () => {
await limitRenderDistance(); // Call the function here
}} }}
/> />
<InputRange <InputRange
label="Distance" label="Distance"
disabled={!limitDistance} disabled={!limitDistance}
value={distance} value={renderDistance}
key={"5"}
min={CONSTANTS.distanceConfig.minDistance} min={CONSTANTS.distanceConfig.minDistance}
max={CONSTANTS.distanceConfig.maxDistance} max={CONSTANTS.distanceConfig.maxDistance}
onChange={(value: number) => updateDistance(value)} onChange={(value: number) => updateDistance(value)}
onPointerUp={updatedDist}
key={"6"}
/> />
<div className="split"></div> <div className="split"></div>
@@ -213,7 +297,10 @@ const GlobalProperties: React.FC = () => {
disabled={!limitGridDistance} disabled={!limitGridDistance}
value={gridDistance} value={gridDistance}
key={"7"} key={"7"}
min={1}
max={5}
onChange={(value: number) => updateGridDistance(value)} onChange={(value: number) => updateGridDistance(value)}
onPointerUp={updatedGrid}
/> />
</div> </div>
); );

View File

@@ -0,0 +1,177 @@
import React, { useEffect, useState } from "react";
import MultiLevelDropdown from "../../../../ui/inputs/MultiLevelDropDown";
import { AddIcon } from "../../../../icons/ExportCommonIcons";
import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
import useChartStore from "../../../../../store/useChartStore";
import { useSelectedZoneStore } from "../../../../../store/useZoneStore";
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
type Props = {};
const BarChartInput = (props: Props) => {
const [widgetName, setWidgetName] = useState('Widget');
const { setMeasurements, updateDuration, updateName } = useChartStore();
const [duration, setDuration] = useState('1h')
const [dropDowndata, setDropDownData] = useState({});
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({});
const { selectedZone } = useSelectedZoneStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
useEffect(() => {
const fetchZoneData = async () => {
try {
const response = await axios.get(`http://${iotApiUrl}/getinput`);
if (response.status === 200) {
// console.log("dropdown data:", response.data);
setDropDownData(response.data);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
};
fetchZoneData();
}, []);
useEffect(() => {
const fetchSavedInputes = async () => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${selectedChartId.id}/${organization}`);
if (response.status === 200) {
setSelections(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setWidgetName(response.data.widgetName)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
fetchSavedInputes();
}, [selectedChartId.id]);
// Sync Zustand state when component mounts
useEffect(() => {
setMeasurements(selections);
updateDuration(duration);
updateName(widgetName);
}, [selections, duration, widgetName]);
const sendInputes = async (inputMeasurement: any, inputDuration: any, inputName: any) => {
try {
const response = await axios.post(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget/save`, {
organization: organization,
zoneId: selectedZone.zoneId,
widget: {
id: selectedChartId.id,
panel: selectedChartId.panel,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration
}
}
} as any);
if (response.status === 200) {
return true
} else {
console.log("Unexpected response:", response);
return false
}
} catch (error) {
console.error("There was an error!", error);
return false
}
}
const handleSelect = async (inputKey: string, selectedData: { name: string; fields: string } | null) => {
// async() => {
const newSelections = { ...selections };
if (selectedData === null) {
delete newSelections[inputKey];
} else {
newSelections[inputKey] = selectedData;
}
// setMeasurements(newSelections); // Update Zustand store
console.log(newSelections);
if (await sendInputes(newSelections, duration, widgetName)) {
setSelections(newSelections);
}
// sendInputes(newSelections, duration); // Send data to server
// return newSelections;
// };
};
const handleSelectDuration = async (option: string) => {
if (await sendInputes(selections, option, widgetName)) {
setDuration(option);
}
// setDuration(option);
};
const handleNameChange = async (name:any) => {
console.log('name change requested',name);
if (await sendInputes(selections, duration, name)) {
setWidgetName(name);
}
}
return (
<>
<div className="inputs-wrapper">
<div className="datas">
<div className="datas__label">Title</div>
<RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/>
</div>
{[...Array(3)].map((_, index) => {
const inputKey = `input${index + 1}`;
return (
<div key={index} className="datas">
<div className="datas__label">Input {index + 1}</div>
<div className="datas__class">
<MultiLevelDropdown
data={dropDowndata}
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
onUnselect={() => handleSelect(inputKey, null)}
selectedValue={selections[inputKey]} // Load from Zustand
/>
<div className="icon">
<AddIcon />
</div>
</div>
</div>
);
})}
</div>
<div>
<div className="datas">
<div className="datas__label">Duration</div>
<div className="datas__class">
<RegularDropDown
header={duration}
options={["1h", "2h", "12h"]}
onSelect={handleSelectDuration}
search={false}
/>
</div>
</div>
</div>
</>
);
};
export default BarChartInput;

View File

@@ -0,0 +1,178 @@
import React, { useEffect, useState } from "react";
import MultiLevelDropdown from "../../../../ui/inputs/MultiLevelDropDown";
import { AddIcon } from "../../../../icons/ExportCommonIcons";
import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
import useChartStore from "../../../../../store/useChartStore";
import { useSelectedZoneStore } from "../../../../../store/useZoneStore";
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
type Props = {};
const FleetEfficiencyInputComponent = (props: Props) => {
const [widgetName, setWidgetName] = useState('Widget');
const { setFlotingMeasurements, updateFlotingDuration, updateHeader } = useChartStore();
const [duration, setDuration] = useState('1h')
const [dropDowndata, setDropDownData] = useState({});
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({});
const { selectedZone } = useSelectedZoneStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
useEffect(() => {
const fetchZoneData = async () => {
try {
const response = await axios.get(`http://${iotApiUrl}/getinput`);
if (response.status === 200) {
// console.log("dropdown data:", response.data);
setDropDownData(response.data);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
};
fetchZoneData();
}, []);
useEffect(() => {
const fetchSavedInputes = async () => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${selectedChartId.id}/${organization}`);
if (response.status === 200) {
console.log(response.data);
setSelections(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setWidgetName(response.data.header)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
fetchSavedInputes();
}, [selectedChartId.id]);
// Sync Zustand state when component mounts
useEffect(() => {
setFlotingMeasurements(selections);
updateFlotingDuration(duration);
updateHeader(widgetName);
}, [selections, duration, widgetName]);
const sendInputes = async (inputMeasurement: any, inputDuration: any, inputName: any) => {
try {
const response = await axios.post(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/floatwidget/save`, {
organization: organization,
zoneId: selectedZone.zoneId,
widget: {
id: selectedChartId.id,
header: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration
}
}
} as any);
if (response.status === 200) {
return true
} else {
console.log("Unexpected response:", response);
return false
}
} catch (error) {
console.error("There was an error!", error);
return false
}
}
const handleSelect = async (inputKey: string, selectedData: { name: string; fields: string } | null) => {
// async() => {
const newSelections = { ...selections };
if (selectedData === null) {
delete newSelections[inputKey];
} else {
newSelections[inputKey] = selectedData;
}
// setMeasurements(newSelections); // Update Zustand store
console.log(newSelections);
if (await sendInputes(newSelections, duration, widgetName)) {
setSelections(newSelections);
}
// sendInputes(newSelections, duration); // Send data to server
// return newSelections;
// };
};
const handleSelectDuration = async (option: string) => {
if (await sendInputes(selections, option, widgetName)) {
setDuration(option);
}
// setDuration(option);
};
const handleNameChange = async (name:any) => {
console.log('name change requested',name);
if (await sendInputes(selections, duration, name)) {
setWidgetName(name);
}
}
return (
<>
<div className="inputs-wrapper">
<div className="datas">
<div className="datas__label">Title</div>
<RenameInput value={selectedChartId?.header || "untited"} onRename={handleNameChange}/>
</div>
{[...Array(1)].map((_, index) => {
const inputKey = `input${index + 1}`;
return (
<div key={index} className="datas">
<div className="datas__label">Input {index + 1}</div>
<div className="datas__class">
<MultiLevelDropdown
data={dropDowndata}
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
onUnselect={() => handleSelect(inputKey, null)}
selectedValue={selections[inputKey]} // Load from Zustand
/>
<div className="icon">
<AddIcon />
</div>
</div>
</div>
);
})}
</div>
<div>
{/* <div className="datas">
<div className="datas__label">Duration</div>
<div className="datas__class">
<RegularDropDown
header={duration}
options={["1h", "2h", "12h"]}
onSelect={handleSelectDuration}
search={false}
/>
</div>
</div> */}
</div>
</>
);
};
export default FleetEfficiencyInputComponent;

View File

@@ -12,7 +12,7 @@ type Props = {};
const FlotingWidgetInput = (props: Props) => { const FlotingWidgetInput = (props: Props) => {
const [widgetName, setWidgetName] = useState('Widget'); const [widgetName, setWidgetName] = useState('Widget');
const { setMeasurements, updateDuration, updateName } = useChartStore(); const { setFlotingMeasurements, updateFlotingDuration, updateHeader } = useChartStore();
const [duration, setDuration] = useState('1h') const [duration, setDuration] = useState('1h')
const [dropDowndata, setDropDownData] = useState({}); const [dropDowndata, setDropDownData] = useState({});
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({}); const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({});
@@ -43,11 +43,13 @@ const FlotingWidgetInput = (props: Props) => {
const fetchSavedInputes = async () => { const fetchSavedInputes = async () => {
if (selectedChartId.id !== "") { if (selectedChartId.id !== "") {
try { try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${selectedChartId.id}/${organization}`); const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${selectedChartId.id}/${organization}`);
if (response.status === 200) { if (response.status === 200) {
console.log(response.data);
setSelections(response.data.Data.measurements) setSelections(response.data.Data.measurements)
setDuration(response.data.Data.duration) setDuration(response.data.Data.duration)
setWidgetName(response.data.widgetName) setWidgetName(response.data.header)
} else { } else {
console.log("Unexpected response:", response); console.log("Unexpected response:", response);
} }
@@ -63,9 +65,9 @@ const FlotingWidgetInput = (props: Props) => {
// Sync Zustand state when component mounts // Sync Zustand state when component mounts
useEffect(() => { useEffect(() => {
setMeasurements(selections); setFlotingMeasurements(selections);
updateDuration(duration); updateFlotingDuration(duration);
updateName(widgetName); updateHeader(widgetName);
}, [selections, duration, widgetName]); }, [selections, duration, widgetName]);
@@ -76,8 +78,7 @@ const FlotingWidgetInput = (props: Props) => {
zoneId: selectedZone.zoneId, zoneId: selectedZone.zoneId,
widget: { widget: {
id: selectedChartId.id, id: selectedChartId.id,
panel: selectedChartId.panel, header: inputName,
widgetName: inputName,
Data: { Data: {
measurements: inputMeasurement, measurements: inputMeasurement,
duration: inputDuration duration: inputDuration
@@ -135,7 +136,7 @@ const FlotingWidgetInput = (props: Props) => {
<div className="inputs-wrapper"> <div className="inputs-wrapper">
<div className="datas"> <div className="datas">
<div className="datas__label">Title</div> <div className="datas__label">Title</div>
<RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/> <RenameInput value={selectedChartId?.header || "untited"} onRename={handleNameChange}/>
</div> </div>
{[...Array(6)].map((_, index) => { {[...Array(6)].map((_, index) => {
const inputKey = `input${index + 1}`; const inputKey = `input${index + 1}`;

View File

@@ -0,0 +1,153 @@
import React from 'react'
import LineGrapInput from './LineGrapInput'
import BarChartInput from './BarChartInput'
import PieChartInput from './PieChartInput'
import FlotingWidgetInput from './FlotingWidgetInput'
import FleetEfficiencyInputComponent from './FleetEfficiencyInputComponent'
import Progress1Input from './Progress1Input'
import Progress2Input from './Progress2Input'
import Widget2InputCard3D from './Widget2InputCard3D'
import Widget3InputCard3D from './Widget3InputCard3D'
import Widget4InputCard3D from './Widget4InputCard3D'
import WarehouseThroughputInputComponent from './WarehouseThroughputInputComponent'
import { useWidgetStore } from '../../../../../store/useWidgetStore'
const InputSelecterComponent = () => {
const { selectedChartId } = useWidgetStore();
console.log('selectedChartId:',selectedChartId);
if (selectedChartId && selectedChartId.type && selectedChartId.type === 'bar' ) {
return (
<>
<div className="sideBarHeader">2D Widget Input</div>
<BarChartInput />
</>
)
}
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'line' ) {
return (
<>
<div className="sideBarHeader">2D Widget Input</div>
<LineGrapInput />
</>
)
}
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'pie' ) {
return (
<>
<div className="sideBarHeader">2D Widget Input</div>
<PieChartInput />
</>
)
}
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'doughnut' ) {
return (
<>
<div className="sideBarHeader">2D Widget Input</div>
<PieChartInput />
</>
)
}
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'polarArea' ) {
return (
<>
<div className="sideBarHeader">2D Widget Input</div>
<PieChartInput />
</>
)
}
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'progress 1' ) {
return (
<>
<div className="sideBarHeader">2D Widget Input</div>
<Progress1Input />
</>
)
}
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'progress 2' ) {
return (
<>
<div className="sideBarHeader">2D Widget Input</div>
<Progress2Input />
</>
)
}
else if (selectedChartId && selectedChartId.className && selectedChartId.className === 'warehouseThroughput floating' ) {
return (
<>
<div className="sideBarHeader">Floting Widget Input</div>
<WarehouseThroughputInputComponent />
</>
)
}
else if (selectedChartId && selectedChartId.className && selectedChartId.className === 'fleetEfficiency floating' ) {
return (
<>
<div className="sideBarHeader">Floting Widget Input</div>
<FleetEfficiencyInputComponent />
</>
)
}
else if (selectedChartId && selectedChartId.className && selectedChartId.className === 'floating total-card' ) {
return (
<>
<div className="sideBarHeader">Floting Widget Input</div>
<FleetEfficiencyInputComponent />
</>
)
}
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'ui-Widget 1' ) {
return (
<>
<div className="sideBarHeader">3D Widget Input</div>
<Widget4InputCard3D />
</>
)
}
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'ui-Widget 2' ) {
return (
<>
<div className="sideBarHeader">3D Widget Input</div>
<Widget2InputCard3D />
</>
)
}
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'ui-Widget 3' ) {
return (
<>
<div className="sideBarHeader">3D Widget Input</div>
<Widget3InputCard3D />
</>
)
}
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'ui-Widget 4' ) {
return (
<>
<div className="sideBarHeader">3D Widget Input</div>
<Widget4InputCard3D />
</>
)
}
else {
return (
<div>No chart selected</div>
)
}
}
export default InputSelecterComponent

View File

@@ -256,7 +256,7 @@ const LineGrapInput = (props: Props) => {
<div className="datas__label">Title</div> <div className="datas__label">Title</div>
<RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/> <RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/>
</div> </div>
{[...Array(6)].map((_, index) => { {[...Array(4)].map((_, index) => {
const inputKey = `input${index + 1}`; const inputKey = `input${index + 1}`;
return ( return (
<div key={index} className="datas"> <div key={index} className="datas">

View File

@@ -1,78 +1,177 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from "react";
import MultiLevelDropdown from '../../../../ui/inputs/MultiLevelDropDown' import MultiLevelDropdown from "../../../../ui/inputs/MultiLevelDropDown";
import { AddIcon } from '../../../../icons/ExportCommonIcons' import { AddIcon } from "../../../../icons/ExportCommonIcons";
import axios from 'axios' import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
import useChartStore from "../../../../../store/useChartStore";
import { useSelectedZoneStore } from "../../../../../store/useZoneStore";
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
type Props = {} type Props = {};
const PieChartInput = (props: Props) => { const PieChartInput = (props: Props) => {
const [dropDowndata, setDropDownData] = useState({}) const [widgetName, setWidgetName] = useState('Widget');
const [selections, setSelections] = useState<Record<string, {name: string, fields: string}>>({}) const { setMeasurements, updateDuration, updateName } = useChartStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL; const [duration, setDuration] = useState('1h')
const [dropDowndata, setDropDownData] = useState({});
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({});
const { selectedZone } = useSelectedZoneStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
useEffect(() => { useEffect(() => {
const fetchZoneData = async () => { const fetchZoneData = async () => {
try { try {
const response = await axios.get(`http://${iotApiUrl}/getinput`); const response = await axios.get(`http://${iotApiUrl}/getinput`);
if (response.status === 200) { if (response.status === 200) {
console.log('dropdown data:', response.data); // console.log("dropdown data:", response.data);
setDropDownData(response.data) setDropDownData(response.data);
} else { } else {
console.log('Unexpected response:', response); console.log("Unexpected response:", response);
} }
} catch (error) { } catch (error) {
console.error('There was an error!', error); console.error("There was an error!", error);
} }
};
fetchZoneData();
}, []);
useEffect(() => {console.log(selections);
},[selections])
const handleSelect = (inputKey: string, selectedData: {name: string, fields: string} | null) => {
setSelections(prev => {
if (selectedData === null) {
const newSelections = {...prev};
delete newSelections[inputKey];
return newSelections;
} else {
return {
...prev,
[inputKey]: selectedData
};
}
});
}; };
fetchZoneData();
}, []);
return ( useEffect(() => {
<> const fetchSavedInputes = async () => {
<div className="inputs-wrapper"> if (selectedChartId.id !== "") {
{[...Array(3)].map((_, index) => { try {
const inputKey = `input${index+1}`; const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${selectedChartId.id}/${organization}`);
return ( if (response.status === 200) {
<div key={index} className="datas"> setSelections(response.data.Data.measurements)
<div className="datas__label">Input {index+1}</div> setDuration(response.data.Data.duration)
<div className="datas__class"> setWidgetName(response.data.widgetName)
<MultiLevelDropdown } else {
data={dropDowndata} console.log("Unexpected response:", response);
onSelect={(selectedData) => handleSelect(inputKey, selectedData)} }
onUnselect={() => handleSelect(inputKey, null)} } catch (error) {
selectedValue={selections[inputKey]} console.error("There was an error!", error);
/> }
<div className="icon"> }
<AddIcon /> }
</div>
</div>
</div>
);
})}
</div>
<div>
</div>
</>
)
}
export default PieChartInput fetchSavedInputes();
}, [selectedChartId.id]);
// Sync Zustand state when component mounts
useEffect(() => {
setMeasurements(selections);
updateDuration(duration);
updateName(widgetName);
}, [selections, duration, widgetName]);
const sendInputes = async (inputMeasurement: any, inputDuration: any, inputName: any) => {
try {
const response = await axios.post(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget/save`, {
organization: organization,
zoneId: selectedZone.zoneId,
widget: {
id: selectedChartId.id,
panel: selectedChartId.panel,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration
}
}
} as any);
if (response.status === 200) {
return true
} else {
console.log("Unexpected response:", response);
return false
}
} catch (error) {
console.error("There was an error!", error);
return false
}
}
const handleSelect = async (inputKey: string, selectedData: { name: string; fields: string } | null) => {
// async() => {
const newSelections = { ...selections };
if (selectedData === null) {
delete newSelections[inputKey];
} else {
newSelections[inputKey] = selectedData;
}
// setMeasurements(newSelections); // Update Zustand store
console.log(newSelections);
if (await sendInputes(newSelections, duration, widgetName)) {
setSelections(newSelections);
}
// sendInputes(newSelections, duration); // Send data to server
// return newSelections;
// };
};
const handleSelectDuration = async (option: string) => {
if (await sendInputes(selections, option, widgetName)) {
setDuration(option);
}
// setDuration(option);
};
const handleNameChange = async (name:any) => {
console.log('name change requested',name);
if (await sendInputes(selections, duration, name)) {
setWidgetName(name);
}
}
return (
<>
<div className="inputs-wrapper">
<div className="datas">
<div className="datas__label">Title</div>
<RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/>
</div>
{[...Array(2)].map((_, index) => {
const inputKey = `input${index + 1}`;
return (
<div key={index} className="datas">
<div className="datas__label">Input {index + 1}</div>
<div className="datas__class">
<MultiLevelDropdown
data={dropDowndata}
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
onUnselect={() => handleSelect(inputKey, null)}
selectedValue={selections[inputKey]} // Load from Zustand
/>
<div className="icon">
<AddIcon />
</div>
</div>
</div>
);
})}
</div>
<div>
<div className="datas">
<div className="datas__label">Duration</div>
<div className="datas__class">
<RegularDropDown
header={duration}
options={["1h", "2h", "12h"]}
onSelect={handleSelectDuration}
search={false}
/>
</div>
</div>
</div>
</>
);
};
export default PieChartInput;

View File

@@ -0,0 +1,171 @@
import React, { useEffect, useState } from "react";
import MultiLevelDropdown from "../../../../ui/inputs/MultiLevelDropDown";
import { AddIcon } from "../../../../icons/ExportCommonIcons";
import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
import useChartStore from "../../../../../store/useChartStore";
import { useSelectedZoneStore } from "../../../../../store/useZoneStore";
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
type Props = {};
const Progress1Input = (props: Props) => {
const [widgetName, setWidgetName] = useState('Widget');
const { setMeasurements, updateDuration, updateName } = useChartStore();
const [duration, setDuration] = useState('1h')
const [dropDowndata, setDropDownData] = useState({});
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({});
const { selectedZone } = useSelectedZoneStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
useEffect(() => {
const fetchZoneData = async () => {
try {
const response = await axios.get(`http://${iotApiUrl}/getinput`);
if (response.status === 200) {
// console.log("dropdown data:", response.data);
setDropDownData(response.data);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
};
fetchZoneData();
}, []);
useEffect(() => {
const fetchSavedInputes = async () => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${selectedChartId.id}/${organization}`);
if (response.status === 200) {
setSelections(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setWidgetName(response.data.widgetName)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
fetchSavedInputes();
}, [selectedChartId.id]);
// Sync Zustand state when component mounts
useEffect(() => {
setMeasurements(selections);
updateDuration(duration);
updateName(widgetName);
}, [selections, duration, widgetName]);
const sendInputes = async (inputMeasurement: any, inputDuration: any, inputName: any) => {
try {
const response = await axios.post(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget/save`, {
organization: organization,
zoneId: selectedZone.zoneId,
widget: {
id: selectedChartId.id,
panel: selectedChartId.panel,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration
}
}
} as any);
if (response.status === 200) {
return true
} else {
console.log("Unexpected response:", response);
return false
}
} catch (error) {
console.error("There was an error!", error);
return false
}
}
const handleSelect = async (inputKey: string, selectedData: { name: string; fields: string } | null) => {
// async() => {
const newSelections = { ...selections };
if (selectedData === null) {
delete newSelections[inputKey];
} else {
newSelections[inputKey] = selectedData;
}
// setMeasurements(newSelections); // Update Zustand store
console.log(newSelections);
if (await sendInputes(newSelections, duration, widgetName)) {
setSelections(newSelections);
}
};
const handleSelectDuration = async (option: string) => {
if (await sendInputes(selections, option, widgetName)) {
setDuration(option);
}
};
const handleNameChange = async (name:any) => {
if (await sendInputes(selections, duration, name)) {
setWidgetName(name);
}
}
return (
<>
<div className="inputs-wrapper">
<div className="datas">
<div className="datas__label">Title</div>
<RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/>
</div>
{[...Array(1)].map((_, index) => {
const inputKey = `input${index + 1}`;
return (
<div key={index} className="datas">
<div className="datas__label">Input {index + 1}</div>
<div className="datas__class">
<MultiLevelDropdown
data={dropDowndata}
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
onUnselect={() => handleSelect(inputKey, null)}
selectedValue={selections[inputKey]} // Load from Zustand
/>
<div className="icon">
<AddIcon />
</div>
</div>
</div>
);
})}
</div>
{/* <div>
<div className="datas">
<div className="datas__label">Duration</div>
<div className="datas__class">
<RegularDropDown
header={duration}
options={["1h", "2h", "12h"]}
onSelect={handleSelectDuration}
search={false}
/>
</div>
</div>
</div> */}
</>
);
};
export default Progress1Input;

View File

@@ -0,0 +1,171 @@
import React, { useEffect, useState } from "react";
import MultiLevelDropdown from "../../../../ui/inputs/MultiLevelDropDown";
import { AddIcon } from "../../../../icons/ExportCommonIcons";
import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
import useChartStore from "../../../../../store/useChartStore";
import { useSelectedZoneStore } from "../../../../../store/useZoneStore";
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
type Props = {};
const Progress2Input = (props: Props) => {
const [widgetName, setWidgetName] = useState('Widget');
const { setMeasurements, updateDuration, updateName } = useChartStore();
const [duration, setDuration] = useState('1h')
const [dropDowndata, setDropDownData] = useState({});
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({});
const { selectedZone } = useSelectedZoneStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
useEffect(() => {
const fetchZoneData = async () => {
try {
const response = await axios.get(`http://${iotApiUrl}/getinput`);
if (response.status === 200) {
// console.log("dropdown data:", response.data);
setDropDownData(response.data);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
};
fetchZoneData();
}, []);
useEffect(() => {
const fetchSavedInputes = async () => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${selectedChartId.id}/${organization}`);
if (response.status === 200) {
setSelections(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setWidgetName(response.data.widgetName)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
fetchSavedInputes();
}, [selectedChartId.id]);
// Sync Zustand state when component mounts
useEffect(() => {
setMeasurements(selections);
updateDuration(duration);
updateName(widgetName);
}, [selections, duration, widgetName]);
const sendInputes = async (inputMeasurement: any, inputDuration: any, inputName: any) => {
try {
const response = await axios.post(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget/save`, {
organization: organization,
zoneId: selectedZone.zoneId,
widget: {
id: selectedChartId.id,
panel: selectedChartId.panel,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration
}
}
} as any);
if (response.status === 200) {
return true
} else {
console.log("Unexpected response:", response);
return false
}
} catch (error) {
console.error("There was an error!", error);
return false
}
}
const handleSelect = async (inputKey: string, selectedData: { name: string; fields: string } | null) => {
// async() => {
const newSelections = { ...selections };
if (selectedData === null) {
delete newSelections[inputKey];
} else {
newSelections[inputKey] = selectedData;
}
// setMeasurements(newSelections); // Update Zustand store
console.log(newSelections);
if (await sendInputes(newSelections, duration, widgetName)) {
setSelections(newSelections);
}
};
const handleSelectDuration = async (option: string) => {
if (await sendInputes(selections, option, widgetName)) {
setDuration(option);
}
};
const handleNameChange = async (name:any) => {
if (await sendInputes(selections, duration, name)) {
setWidgetName(name);
}
}
return (
<>
<div className="inputs-wrapper">
<div className="datas">
<div className="datas__label">Title</div>
<RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/>
</div>
{[...Array(2)].map((_, index) => {
const inputKey = `input${index + 1}`;
return (
<div key={index} className="datas">
<div className="datas__label">Input {index + 1}</div>
<div className="datas__class">
<MultiLevelDropdown
data={dropDowndata}
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
onUnselect={() => handleSelect(inputKey, null)}
selectedValue={selections[inputKey]} // Load from Zustand
/>
<div className="icon">
<AddIcon />
</div>
</div>
</div>
);
})}
</div>
{/* <div>
<div className="datas">
<div className="datas__label">Duration</div>
<div className="datas__class">
<RegularDropDown
header={duration}
options={["1h", "2h", "12h"]}
onSelect={handleSelectDuration}
search={false}
/>
</div>
</div>
</div> */}
</>
);
};
export default Progress2Input;

View File

@@ -0,0 +1,178 @@
import React, { useEffect, useState } from "react";
import MultiLevelDropdown from "../../../../ui/inputs/MultiLevelDropDown";
import { AddIcon } from "../../../../icons/ExportCommonIcons";
import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
import useChartStore from "../../../../../store/useChartStore";
import { useSelectedZoneStore } from "../../../../../store/useZoneStore";
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
type Props = {};
const WarehouseThroughputInputComponent = (props: Props) => {
const [widgetName, setWidgetName] = useState('Widget');
const { setFlotingMeasurements, updateFlotingDuration, updateHeader } = useChartStore();
const [duration, setDuration] = useState('1h')
const [dropDowndata, setDropDownData] = useState({});
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({});
const { selectedZone } = useSelectedZoneStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
useEffect(() => {
const fetchZoneData = async () => {
try {
const response = await axios.get(`http://${iotApiUrl}/getinput`);
if (response.status === 200) {
// console.log("dropdown data:", response.data);
setDropDownData(response.data);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
};
fetchZoneData();
}, []);
useEffect(() => {
const fetchSavedInputes = async () => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${selectedChartId.id}/${organization}`);
if (response.status === 200) {
console.log(response.data);
setSelections(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setWidgetName(response.data.header)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
fetchSavedInputes();
}, [selectedChartId.id]);
// Sync Zustand state when component mounts
useEffect(() => {
setFlotingMeasurements(selections);
updateFlotingDuration(duration);
updateHeader(widgetName);
}, [selections, duration, widgetName]);
const sendInputes = async (inputMeasurement: any, inputDuration: any, inputName: any) => {
try {
const response = await axios.post(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/floatwidget/save`, {
organization: organization,
zoneId: selectedZone.zoneId,
widget: {
id: selectedChartId.id,
header: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration
}
}
} as any);
if (response.status === 200) {
return true
} else {
console.log("Unexpected response:", response);
return false
}
} catch (error) {
console.error("There was an error!", error);
return false
}
}
const handleSelect = async (inputKey: string, selectedData: { name: string; fields: string } | null) => {
// async() => {
const newSelections = { ...selections };
if (selectedData === null) {
delete newSelections[inputKey];
} else {
newSelections[inputKey] = selectedData;
}
// setMeasurements(newSelections); // Update Zustand store
console.log(newSelections);
if (await sendInputes(newSelections, duration, widgetName)) {
setSelections(newSelections);
}
// sendInputes(newSelections, duration); // Send data to server
// return newSelections;
// };
};
const handleSelectDuration = async (option: string) => {
if (await sendInputes(selections, option, widgetName)) {
setDuration(option);
}
// setDuration(option);
};
const handleNameChange = async (name:any) => {
console.log('name change requested',name);
if (await sendInputes(selections, duration, name)) {
setWidgetName(name);
}
}
return (
<>
<div className="inputs-wrapper">
<div className="datas">
<div className="datas__label">Title</div>
<RenameInput value={selectedChartId?.header || "untited"} onRename={handleNameChange}/>
</div>
{[...Array(1)].map((_, index) => {
const inputKey = `input${index + 1}`;
return (
<div key={index} className="datas">
<div className="datas__label">Input {index + 1}</div>
<div className="datas__class">
<MultiLevelDropdown
data={dropDowndata}
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
onUnselect={() => handleSelect(inputKey, null)}
selectedValue={selections[inputKey]} // Load from Zustand
/>
<div className="icon">
<AddIcon />
</div>
</div>
</div>
);
})}
</div>
<div>
<div className="datas">
<div className="datas__label">Duration</div>
<div className="datas__class">
<RegularDropDown
header={duration}
options={["1h", "2h", "12h"]}
onSelect={handleSelectDuration}
search={false}
/>
</div>
</div>
</div>
</>
);
};
export default WarehouseThroughputInputComponent;

View File

@@ -0,0 +1,165 @@
import React, { useEffect, useState } from "react";
import MultiLevelDropdown from "../../../../ui/inputs/MultiLevelDropDown";
import { AddIcon } from "../../../../icons/ExportCommonIcons";
import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
import useChartStore from "../../../../../store/useChartStore";
import { useSelectedZoneStore } from "../../../../../store/useZoneStore";
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
type Props = {};
const Widget2InputCard3D = (props: Props) => {
const { selectedChartId } = useWidgetStore();
const [widgetName, setWidgetName] = useState("untited");
const { setMeasurements, updateDuration, updateName } = useChartStore();
const [duration, setDuration] = useState('1h')
const [dropDowndata, setDropDownData] = useState({});
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({});
const { selectedZone } = useSelectedZoneStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
console.log(selectedChartId);
useEffect(() => {
const fetchZoneData = async () => {
try {
const response = await axios.get(`http://${iotApiUrl}/getinput`);
if (response.status === 200) {
// console.log("dropdown data:", response.data);
setDropDownData(response.data);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
};
fetchZoneData();
}, []);
useEffect(() => {
const fetchSavedInputes = async () => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget3D/${selectedChartId.id}/${organization}`);
if (response.status === 200) {
setSelections(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setWidgetName(response.data.widgetName)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
fetchSavedInputes();
}, [selectedChartId.id]);
// Sync Zustand state when component mounts
useEffect(() => {
setMeasurements(selections);
updateDuration(duration);
updateName(widgetName);
}, [selections, duration, widgetName]);
const sendInputes = async (inputMeasurement: any, inputDuration: any, inputName: any) => {
try {
const response = await axios.post(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/3dwidget/save`, {
organization: organization,
zoneId: selectedZone.zoneId,
widget: {
id: selectedChartId.id,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration
}
}
} as any);
if (response.status === 200) {
return true
} else {
console.log("Unexpected response:", response);
return false
}
} catch (error) {
console.error("There was an error!", error);
return false
}
}
const handleSelect = async (inputKey: string, selectedData: { name: string; fields: string } | null) => {
// async() => {
const newSelections = { ...selections };
if (selectedData === null) {
delete newSelections[inputKey];
} else {
newSelections[inputKey] = selectedData;
}
// setMeasurements(newSelections); // Update Zustand store
console.log(newSelections);
if (await sendInputes(newSelections, duration, widgetName)) {
setSelections(newSelections);
}
// sendInputes(newSelections, duration); // Send data to server
// return newSelections;
// };
};
const handleSelectDuration = async (option: string) => {
if (await sendInputes(selections, option, widgetName)) {
setDuration(option);
}
// setDuration(option);
};
const handleNameChange = async (name:any) => {
console.log('name change requested',name);
if (await sendInputes(selections, duration, name)) {
setWidgetName(name);
}
}
return (
<>
<div className="inputs-wrapper">
<div className="datas">
<div className="datas__label">Title</div>
<RenameInput value={widgetName} onRename={handleNameChange}/>
</div>
{[...Array(2)].map((_, index) => {
const inputKey = `input${index + 1}`;
return (
<div key={index} className="datas">
<div className="datas__label">Input {index + 1}</div>
<div className="datas__class">
<MultiLevelDropdown
data={dropDowndata}
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
onUnselect={() => handleSelect(inputKey, null)}
selectedValue={selections[inputKey]} // Load from Zustand
/>
<div className="icon">
<AddIcon />
</div>
</div>
</div>
);
})}
</div>
</>
);
};
export default Widget2InputCard3D;

View File

@@ -0,0 +1,158 @@
import React, { useEffect, useState } from "react";
import MultiLevelDropdown from "../../../../ui/inputs/MultiLevelDropDown";
import { AddIcon } from "../../../../icons/ExportCommonIcons";
import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
import useChartStore from "../../../../../store/useChartStore";
import { useSelectedZoneStore } from "../../../../../store/useZoneStore";
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
const Widget3InputCard3D = () => {
const { selectedChartId } = useWidgetStore();
const [widgetName, setWidgetName] = useState("untited");
const { setMeasurements, updateDuration, updateName } = useChartStore();
const [duration, setDuration] = useState('1h')
const [dropDowndata, setDropDownData] = useState({});
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({});
const { selectedZone } = useSelectedZoneStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
console.log(selectedChartId);
useEffect(() => {
const fetchZoneData = async () => {
try {
const response = await axios.get(`http://${iotApiUrl}/getinput`);
if (response.status === 200) {
// console.log("dropdown data:", response.data);
setDropDownData(response.data);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
};
fetchZoneData();
}, []);
useEffect(() => {
const fetchSavedInputes = async () => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget3D/${selectedChartId.id}/${organization}`);
if (response.status === 200) {
setSelections(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setWidgetName(response.data.widgetName)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
fetchSavedInputes();
}, [selectedChartId.id]);
useEffect(() => {
setMeasurements(selections);
updateDuration(duration);
updateName(widgetName);
}, [selections, duration, widgetName]);
const sendInputes = async (inputMeasurement: any, inputDuration: any, inputName: any) => {
try {
const response = await axios.post(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/3dwidget/save`, {
organization: organization,
zoneId: selectedZone.zoneId,
widget: {
id: selectedChartId.id,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration
}
}
} as any);
if (response.status === 200) {
return true
} else {
console.log("Unexpected response:", response);
return false
}
} catch (error) {
console.error("There was an error!", error);
return false
}
}
const handleSelect = async (inputKey: string, selectedData: { name: string; fields: string } | null) => {
// async() => {
const newSelections = { ...selections };
if (selectedData === null) {
delete newSelections[inputKey];
} else {
newSelections[inputKey] = selectedData;
}
// setMeasurements(newSelections); // Update Zustand store
console.log(newSelections);
if (await sendInputes(newSelections, duration, widgetName)) {
setSelections(newSelections);
}
};
const handleSelectDuration = async (option: string) => {
if (await sendInputes(selections, option, widgetName)) {
setDuration(option);
}
};
const handleNameChange = async (name:any) => {
console.log('name change requested',name);
if (await sendInputes(selections, duration, name)) {
setWidgetName(name);
}
}
return (
<>
<div className="inputs-wrapper">
<div className="datas">
<div className="datas__label">Title</div>
<RenameInput value={widgetName} onRename={handleNameChange}/>
</div>
{[...Array(7)].map((_, index) => {
const inputKey = `input${index + 1}`;
return (
<div key={index} className="datas">
<div className="datas__label">Input {index + 1}</div>
<div className="datas__class">
<MultiLevelDropdown
data={dropDowndata}
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
onUnselect={() => handleSelect(inputKey, null)}
selectedValue={selections[inputKey]} // Load from Zustand
/>
<div className="icon">
<AddIcon />
</div>
</div>
</div>
);
})}
</div>
</>
);
};
export default Widget3InputCard3D;

View File

@@ -0,0 +1,178 @@
import React, { useEffect, useState } from "react";
import MultiLevelDropdown from "../../../../ui/inputs/MultiLevelDropDown";
import { AddIcon } from "../../../../icons/ExportCommonIcons";
import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
import useChartStore from "../../../../../store/useChartStore";
import { useSelectedZoneStore } from "../../../../../store/useZoneStore";
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import axios from "axios";
import RenameInput from "../../../../ui/inputs/RenameInput";
type Props = {};
const Widget4InputCard3D = (props: Props) => {
const { selectedChartId } = useWidgetStore();
const [widgetName, setWidgetName] = useState("untited");
const { setMeasurements, updateDuration, updateName } = useChartStore();
const [duration, setDuration] = useState('1h')
const [dropDowndata, setDropDownData] = useState({});
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({});
const { selectedZone } = useSelectedZoneStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
console.log(selectedChartId);
useEffect(() => {
const fetchZoneData = async () => {
try {
const response = await axios.get(`http://${iotApiUrl}/getinput`);
if (response.status === 200) {
// console.log("dropdown data:", response.data);
setDropDownData(response.data);
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
};
fetchZoneData();
}, []);
useEffect(() => {
const fetchSavedInputes = async () => {
if (selectedChartId.id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget3D/${selectedChartId.id}/${organization}`);
if (response.status === 200) {
setSelections(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setWidgetName(response.data.widgetName)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
fetchSavedInputes();
}, [selectedChartId.id]);
// Sync Zustand state when component mounts
useEffect(() => {
setMeasurements(selections);
updateDuration(duration);
updateName(widgetName);
}, [selections, duration, widgetName]);
const sendInputes = async (inputMeasurement: any, inputDuration: any, inputName: any) => {
try {
const response = await axios.post(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/3dwidget/save`, {
organization: organization,
zoneId: selectedZone.zoneId,
widget: {
id: selectedChartId.id,
widgetName: inputName,
Data: {
measurements: inputMeasurement,
duration: inputDuration
}
}
} as any);
if (response.status === 200) {
return true
} else {
console.log("Unexpected response:", response);
return false
}
} catch (error) {
console.error("There was an error!", error);
return false
}
}
const handleSelect = async (inputKey: string, selectedData: { name: string; fields: string } | null) => {
// async() => {
const newSelections = { ...selections };
if (selectedData === null) {
delete newSelections[inputKey];
} else {
newSelections[inputKey] = selectedData;
}
// setMeasurements(newSelections); // Update Zustand store
console.log(newSelections);
if (await sendInputes(newSelections, duration, widgetName)) {
setSelections(newSelections);
}
// sendInputes(newSelections, duration); // Send data to server
// return newSelections;
// };
};
const handleSelectDuration = async (option: string) => {
if (await sendInputes(selections, option, widgetName)) {
setDuration(option);
}
// setDuration(option);
};
const handleNameChange = async (name:any) => {
console.log('name change requested',name);
if (await sendInputes(selections, duration, name)) {
setWidgetName(name);
}
}
return (
<>
<div className="inputs-wrapper">
<div className="datas">
<div className="datas__label">Title</div>
<RenameInput value={widgetName} onRename={handleNameChange}/>
</div>
{[...Array(1)].map((_, index) => {
const inputKey = `input${index + 1}`;
return (
<div key={index} className="datas">
<div className="datas__label">Input {index + 1}</div>
<div className="datas__class">
<MultiLevelDropdown
data={dropDowndata}
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
onUnselect={() => handleSelect(inputKey, null)}
selectedValue={selections[inputKey]} // Load from Zustand
/>
<div className="icon">
<AddIcon />
</div>
</div>
</div>
);
})}
</div>
<div>
<div className="datas">
<div className="datas__label">Duration</div>
<div className="datas__class">
<RegularDropDown
header={duration}
options={["1h", "2h", "12h"]}
onSelect={handleSelectDuration}
search={false}
/>
</div>
</div>
</div>
</>
);
};
export default Widget4InputCard3D;

View File

@@ -4,6 +4,7 @@ import { AddIcon, RemoveIcon } from "../../../../icons/ExportCommonIcons";
import MultiLevelDropDown from "../../../../ui/inputs/MultiLevelDropDown"; import MultiLevelDropDown from "../../../../ui/inputs/MultiLevelDropDown";
import LineGrapInput from "../IotInputCards/LineGrapInput"; import LineGrapInput from "../IotInputCards/LineGrapInput";
import RenameInput from "../../../../ui/inputs/RenameInput"; import RenameInput from "../../../../ui/inputs/RenameInput";
import InputSelecterComponent from "../IotInputCards/InputSelecterComponent";
// Define the data structure for demonstration purposes // Define the data structure for demonstration purposes
const DATA_STRUCTURE = { const DATA_STRUCTURE = {
@@ -133,8 +134,7 @@ const Data = () => {
{ {
chartDataGroups[selectedChartId?.id] && chartDataGroups[selectedChartId?.id] &&
<> <>
<div className="sideBarHeader">2D Widget Input</div> <InputSelecterComponent />
<LineGrapInput />
</> </>
} }

View File

@@ -1,10 +1,11 @@
import React, { useState } from "react"; import React, { useEffect, useState } from "react";
import RenderOverlay from "./Overlay"; import RenderOverlay from "./Overlay";
import { ArrowIcon, CloseIcon } from "../icons/ExportCommonIcons"; import { ArrowIcon, CloseIcon } from "../icons/ExportCommonIcons";
import { AccessOption, User } from "../../types/users"; import { AccessOption, User } from "../../types/users";
import RegularDropDown from "../ui/inputs/RegularDropDown"; import RegularDropDown from "../ui/inputs/RegularDropDown";
import { access } from "fs"; import { access } from "fs";
import MultiEmailInvite from "../ui/inputs/MultiEmailInvite"; import MultiEmailInvite from "../ui/inputs/MultiEmailInvite";
import { useActiveUsers } from "../../store/store";
interface UserListTemplateProps { interface UserListTemplateProps {
user: User; user: User;
@@ -57,6 +58,10 @@ interface CollaborateProps {
const CollaborationPopup: React.FC<CollaborateProps> = ({ const CollaborationPopup: React.FC<CollaborateProps> = ({
setUserManagement, setUserManagement,
}) => { }) => {
const { activeUsers } = useActiveUsers();
useEffect(() => {
console.log("activeUsers: ", activeUsers);
}, [activeUsers]);
const userName = localStorage.getItem("userName") || "Anonymous"; const userName = localStorage.getItem("userName") || "Anonymous";
const users = [ const users = [
{ {

View File

@@ -1,5 +1,5 @@
import React, { useEffect, useRef, useState, useCallback } from "react"; import React, { useEffect, useRef, useState, useCallback } from "react";
import { Widget } from "../../../store/useWidgetStore"; import { useWidgetStore, Widget } from "../../../store/useWidgetStore";
import { MoveArrowLeft, MoveArrowRight } from "../../icons/SimulationIcons"; import { MoveArrowLeft, MoveArrowRight } from "../../icons/SimulationIcons";
import { InfoIcon } from "../../icons/ExportCommonIcons"; import { InfoIcon } from "../../icons/ExportCommonIcons";
import { import {
@@ -73,7 +73,8 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
// State to track overflow visibility // State to track overflow visibility
const [showLeftArrow, setShowLeftArrow] = useState(false); const [showLeftArrow, setShowLeftArrow] = useState(false);
const [showRightArrow, setShowRightArrow] = useState(false); const [showRightArrow, setShowRightArrow] = useState(false);
const { floatingWidget, setFloatingWidget } = useFloatingWidget(); const { floatingWidget, setFloatingWidget } = useFloatingWidget()
const{setSelectedChartId}=useWidgetStore()
// Function to calculate overflow state // Function to calculate overflow state
const updateOverflowState = useCallback(() => { const updateOverflowState = useCallback(() => {
@@ -150,6 +151,7 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
if (selectedZone?.zoneId === zoneId) { if (selectedZone?.zoneId === zoneId) {
return; return;
} }
setSelectedChartId(null)
const email = localStorage.getItem("email") || ""; const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]; const organization = email?.split("@")[1]?.split(".")[0];
let response = await getSelect2dZoneData(zoneId, organization); let response = await getSelect2dZoneData(zoneId, organization);

View File

@@ -5,6 +5,8 @@ import BarGraphComponent from "../realTimeVis/charts/BarGraphComponent";
import LineGraphComponent from "../realTimeVis/charts/LineGraphComponent"; import LineGraphComponent from "../realTimeVis/charts/LineGraphComponent";
import DoughnutGraphComponent from "../realTimeVis/charts/DoughnutGraphComponent"; import DoughnutGraphComponent from "../realTimeVis/charts/DoughnutGraphComponent";
import PolarAreaGraphComponent from "../realTimeVis/charts/PolarAreaGraphComponent"; import PolarAreaGraphComponent from "../realTimeVis/charts/PolarAreaGraphComponent";
import ProgressCard1 from "../realTimeVis/charts/ProgressCard1";
import ProgressCard2 from "../realTimeVis/charts/ProgressCard2";
import { import {
DeleteIcon, DeleteIcon,
DublicateIcon, DublicateIcon,
@@ -223,6 +225,7 @@ export const DraggableWidget = ({
onReorder(fromIndex, toIndex); // Call the reorder function passed as a prop onReorder(fromIndex, toIndex); // Call the reorder function passed as a prop
} }
}; };
console.log("widget.type", widget.type);
return ( return (
<> <>
@@ -270,8 +273,11 @@ export const DraggableWidget = ({
{/* Render charts based on widget type */} {/* Render charts based on widget type */}
{widget.type === "progress" && ( {widget.type === "progress 1" && (
<ProgressCard title={widget.title} data={widget.data} /> <ProgressCard1 title={widget.title} id={widget.id} />
)}
{widget.type === "progress 2" && (
<ProgressCard2 title={widget.title} id={widget.id} />
)} )}
{widget.type === "line" && ( {widget.type === "line" && (
<LineGraphComponent <LineGraphComponent
@@ -280,14 +286,6 @@ export const DraggableWidget = ({
title={widget.title} title={widget.title}
fontSize={widget.fontSize} fontSize={widget.fontSize}
fontWeight={widget.fontWeight} fontWeight={widget.fontWeight}
// data={{
// measurements: [
// { name: "testDevice", fields: "powerConsumption" },
// { name: "furnace", fields: "powerConsumption" },
// ],
// interval: 1000,
// duration: "1h",
// }}
/> />
)} )}
{widget.type === "bar" && ( {widget.type === "bar" && (
@@ -297,14 +295,6 @@ export const DraggableWidget = ({
title={widget.title} title={widget.title}
fontSize={widget.fontSize} fontSize={widget.fontSize}
fontWeight={widget.fontWeight} fontWeight={widget.fontWeight}
// data={{
// measurements: [
// { name: "testDevice", fields: "powerConsumption" },
// { name: "furnace", fields: "powerConsumption" },
// ],
// interval: 1000,
// duration: "1h",
// }}
/> />
)} )}
{widget.type === "pie" && ( {widget.type === "pie" && (
@@ -314,14 +304,6 @@ export const DraggableWidget = ({
title={widget.title} title={widget.title}
fontSize={widget.fontSize} fontSize={widget.fontSize}
fontWeight={widget.fontWeight} fontWeight={widget.fontWeight}
// data={{
// measurements: [
// { name: "testDevice", fields: "powerConsumption" },
// { name: "furnace", fields: "powerConsumption" },
// ],
// interval: 1000,
// duration: "1h",
// }}
/> />
)} )}
{widget.type === "doughnut" && ( {widget.type === "doughnut" && (

View File

@@ -113,15 +113,16 @@ export default function Dropped3dWidgets() {
return ( return (
<> <>
{activeZoneWidgets.map(({ id, type, position }) => { {activeZoneWidgets.map(({ id, type, position }) => {
console.log('Typeeeeeeeeeeee',type);
switch (type) { switch (type) {
case "ui-Widget 1": case "ui-Widget 1":
return <ProductionCapacity key={id} position={position} />; return <ProductionCapacity key={id} id={id} type={type} position={position} />;
case "ui-Widget 2": case "ui-Widget 2":
return <ReturnOfInvestment key={id} position={position} />; return <ReturnOfInvestment key={id} id={id} type={type} position={position} />;
case "ui-Widget 3": case "ui-Widget 3":
return <StateWorking key={id} position={position} />; return <StateWorking key={id} id={id} type={type} position={position} />;
case "ui-Widget 4": case "ui-Widget 4":
return <Throughput key={id} position={position} />; return <Throughput key={id} id={id} type={type} position={position} />;
default: default:
return null; return null;
} }

View File

@@ -359,7 +359,7 @@ const DroppedObjects: React.FC = () => {
</> </>
) : obj.className === "warehouseThroughput floating" ? ( ) : obj.className === "warehouseThroughput floating" ? (
<> <>
<WarehouseThroughputComponent /> <WarehouseThroughputComponent object={obj}/>
</> </>
) : obj.className === "fleetEfficiency floating" ? ( ) : obj.className === "fleetEfficiency floating" ? (
<> <>

View File

@@ -8,6 +8,7 @@ interface InputToggleProps {
onChange?: (value: number) => void; // Function to handle toggle clicks onChange?: (value: number) => void; // Function to handle toggle clicks
disabled?: boolean; disabled?: boolean;
value?: number; value?: number;
onPointerUp?: (value: number) => void;
} }
const InputRange: React.FC<InputToggleProps> = ({ const InputRange: React.FC<InputToggleProps> = ({
@@ -17,9 +18,10 @@ const InputRange: React.FC<InputToggleProps> = ({
min, min,
max, max,
disabled, disabled,
value = 5, value,
onPointerUp,
}) => { }) => {
const [rangeValue, setRangeValue] = useState<number>(value); const [rangeValue, setRangeValue] = useState<number>(value ? value : 5);
function handleChange(e: React.ChangeEvent<HTMLInputElement>) { function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
const newValue = parseInt(e.target.value); // Parse the value to an integer const newValue = parseInt(e.target.value); // Parse the value to an integer
@@ -31,8 +33,22 @@ const InputRange: React.FC<InputToggleProps> = ({
} }
} }
useEffect(() => { useEffect(() => {
setRangeValue(value); value && setRangeValue(value);
}, [value]); }, [value]);
function handlePointerUp(e: React.PointerEvent<HTMLInputElement>) {
const newValue = parseInt(e.currentTarget.value, 10); // Parse value correctly
if (onPointerUp) {
onPointerUp(newValue); // Call the callback function if it exists
}
}
function handlekey(e: React.KeyboardEvent<HTMLInputElement>) {
const newValue = parseInt(e.currentTarget.value, 10); // Parse value correctly
if (onPointerUp) {
onPointerUp(newValue); // Call the callback function if it exists
}
}
return ( return (
<div className="input-range-container"> <div className="input-range-container">
@@ -52,6 +68,7 @@ const InputRange: React.FC<InputToggleProps> = ({
onChange={handleChange} onChange={handleChange}
disabled={disabled} disabled={disabled}
value={rangeValue} value={rangeValue}
onPointerUp={handlePointerUp}
/> />
<input <input
type="number" type="number"
@@ -61,6 +78,12 @@ const InputRange: React.FC<InputToggleProps> = ({
value={rangeValue} value={rangeValue}
onChange={handleChange} onChange={handleChange}
disabled={disabled} disabled={disabled}
onKeyUp={(e) => {
if (e.key === "ArrowUp" || e.key === "ArrowDown") {
console.log("e.key: ", e.key);
handlekey(e);
}
}}
/> />
</div> </div>
</div> </div>

View File

@@ -0,0 +1,105 @@
import { StockIncreseIcon } from "../../../icons/RealTimeVisulationIcons";
import React, { useEffect, useMemo, useState } from "react";
import { Line } from "react-chartjs-2";
import io from "socket.io-client";
import useChartStore from "../../../../store/useChartStore";
import { useWidgetStore } from "../../../../store/useWidgetStore";
import axios from "axios";
const ProgressCard1 = ({ id,title,}: {
id: string,
title: string;
}) => {
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
const [measurements, setmeasurements] = useState<any>({});
const [duration, setDuration] = useState("1h")
const [name, setName] = useState(title)
const [value, setValue] = useState<any>('')
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
useEffect(() => {
const socket = io(`http://${iotApiUrl}`);
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
const inputData = {
measurements,
duration,
interval: 1000,
};
const startStream = () => {
socket.emit("lastInput", inputData);
};
socket.on("connect", startStream);
socket.on("lastOutput", (response) => {
const responseData = response.input1;
setValue(responseData);
});
return () => {
socket.off("lastOutput");
socket.emit("stop_stream"); // Stop streaming when component unmounts
socket.disconnect();
};
}, [measurements, duration]);
const fetchSavedInputes = async() => {
if (id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${id}/${organization}`);
if (response.status === 200) {
setmeasurements(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setName(response.data.widgetName)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
useEffect(() => {
fetchSavedInputes();
}, []);
useEffect(() => {
if (selectedChartId?.id === id) {
fetchSavedInputes();
}
}
,[chartMeasurements, chartDuration, widgetName])
return(
<div className="chart progressBar">
<div className="header">{name}</div>
<div className="stock">
<span className="stock-item">
<span className="stockValues">
<div className="value">{value}</div>
<div className="key">Units</div>
</span>
<div className="stock-description">{
measurements ? `${measurements?.input1?.fields}` : 'description'}</div>
</span>
<div className="icon">
<StockIncreseIcon />
</div>
</div>
</div>
)
};
export default ProgressCard1;

View File

@@ -0,0 +1,125 @@
import { StockIncreseIcon } from "../../../icons/RealTimeVisulationIcons";
import React, { useEffect, useMemo, useState } from "react";
import { Line } from "react-chartjs-2";
import io from "socket.io-client";
import useChartStore from "../../../../store/useChartStore";
import { useWidgetStore } from "../../../../store/useWidgetStore";
import axios from "axios";
const ProgressCard2 = ({ id,title,}: {
id: string,
title: string;
}) => {
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
const [measurements, setmeasurements] = useState<any>({});
const [duration, setDuration] = useState("1h")
const [name, setName] = useState(title)
const [value1, setValue1] = useState<any>('')
const [value2, setValue2] = useState<any>('')
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
useEffect(() => {
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
const socket = io(`http://${iotApiUrl}`);
const inputData = {
measurements,
duration,
interval: 1000,
};
const startStream = () => {
socket.emit("lastInput", inputData);
};
socket.on("connect", startStream);
socket.on("lastOutput", (response) => {
const responseData1 = response.input1;
const responseData2 = response.input2;
setValue1(responseData1);
setValue2(responseData2);
});
return () => {
socket.off("lastOutput");
socket.emit("stop_stream"); // Stop streaming when component unmounts
socket.disconnect();
};
}, [measurements, duration]);
const fetchSavedInputes = async() => {
if (id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${id}/${organization}`);
if (response.status === 200) {
setmeasurements(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setName(response.data.widgetName)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
useEffect(() => {
fetchSavedInputes();
}, []);
useEffect(() => {
if (selectedChartId?.id === id) {
fetchSavedInputes();
}
}
,[chartMeasurements, chartDuration, widgetName])
return(
<div className="chart progressBar">
<div className="header">{name}</div>
<div className="stock">
<span className="stock-item">
<span className="stockValues">
<div className="value">{value1}</div>
<div className="key">Units</div>
</span>
<div className="stock-description">{
measurements ? `${measurements?.input1?.fields}` : 'description'}</div>
</span>
<div className="icon">
<StockIncreseIcon />
</div>
</div>
<div className="stock">
<span className="stock-item">
<span className="stockValues">
<div className="value">{value2}</div>
<div className="key">Units</div>
</span>
<div className="stock-description">{
measurements ? `${measurements?.input2?.fields}` : 'description'}</div>
</span>
<div className="icon">
<StockIncreseIcon />
</div>
</div>
</div>
)
};
export default ProgressCard2;

View File

@@ -1,8 +1,8 @@
const FleetEfficiency = () => { const FleetEfficiency = () => {
const progress = 75; // Example progress value (0-100) const progress = 50; // Example progress value (0-100)
// Calculate the rotation angle for the progress bar // Calculate the rotation angle for the progress bar
const rotationAngle = -90 + progress * 3.6; // Progress starts from the left (-90°) const rotationAngle = 45 + progress * 1.8;
const handleDragStart = (event: React.DragEvent<HTMLDivElement>) => { const handleDragStart = (event: React.DragEvent<HTMLDivElement>) => {
const rect = event.currentTarget.getBoundingClientRect(); // Get position const rect = event.currentTarget.getBoundingClientRect(); // Get position

View File

@@ -1,19 +1,99 @@
import React from 'react' import React, { useState, useEffect } from 'react'
import { Line } from 'react-chartjs-2'
import useChartStore from '../../../../store/useChartStore';
import { useWidgetStore } from '../../../../store/useWidgetStore';
import axios from 'axios';
import io from "socket.io-client";
type Props = {} const FleetEfficiencyComponent = ({object}: any) => {
const [ progress, setProgress ] = useState<any>(0)
const [measurements, setmeasurements] = useState<any>({});
const [duration, setDuration] = useState("1h")
const [name, setName] = useState(object.header ? object.header : '')
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
const { header, flotingDuration, flotingMeasurements } = useChartStore();
const { selectedChartId } = useWidgetStore();
const FleetEfficiencyComponent = ({ const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
object
}: any) => { // Calculate the rotation angle for the progress bar
const rotationAngle = 45 + progress * 1.8;
useEffect(() => {
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
const socket = io(`http://${iotApiUrl}`);
const inputData = {
measurements,
duration,
interval: 1000,
};
const startStream = () => {
socket.emit("lastInput", inputData);
};
socket.on("connect", startStream);
socket.on("lastOutput", (response) => {
const responseData = response.input1;
console.log(responseData);
if (typeof responseData === "number") {
console.log("It's a number!");
setProgress(responseData);
}
});
return () => {
socket.off("lastOutput");
socket.emit("stop_stream"); // Stop streaming when component unmounts
socket.disconnect();
};
}, [measurements, duration, iotApiUrl]);
const fetchSavedInputes = async() => {
if (object?.id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${object?.id}/${organization}`);
if (response.status === 200) {
setmeasurements(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setName(response.data.header)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
useEffect(() => {
fetchSavedInputes();
}, []);
useEffect(() => {
if (selectedChartId?.id === object?.id) {
fetchSavedInputes();
}
}
,[header, flotingDuration, flotingMeasurements])
return ( return (
<> <>
<h2 className="header">Fleet Efficiency</h2> <h2 className="header">{name}</h2>
<div className="progressContainer"> <div className="progressContainer">
<div className="progress"> <div className="progress">
<div className="barOverflow"> <div className="barOverflow">
<div <div
className="bar" className="bar"
style={{ transform: `rotate(${object.value}deg)` }} style={{ transform: `rotate(${rotationAngle}deg)` }}
></div> ></div>
</div> </div>
</div> </div>
@@ -21,7 +101,7 @@ const FleetEfficiencyComponent = ({
<div className="scaleLabels"> <div className="scaleLabels">
<span>0%</span> <span>0%</span>
<div className="centerText"> <div className="centerText">
<div className="percentage">{object.per}%</div> <div className="percentage">{progress}%</div>
<div className="status">Optimal</div> <div className="status">Optimal</div>
</div> </div>
<span>100%</span> <span>100%</span>

View File

@@ -1,21 +1,95 @@
import React from 'react' import React, { useState, useEffect } from 'react'
import { WalletIcon } from '../../../icons/3dChartIcons' import { Line } from 'react-chartjs-2'
import useChartStore from '../../../../store/useChartStore';
import { useWidgetStore } from '../../../../store/useWidgetStore'; import { useWidgetStore } from '../../../../store/useWidgetStore';
import axios from 'axios';
import io from "socket.io-client";
import { WalletIcon } from '../../../icons/3dChartIcons';
const TotalCardComponent = ({ const TotalCardComponent = ({
object object
}: any) => { }: any) => {
const { setSelectedChartId } = const [ progress, setProgress ] = useState<any>(0)
useWidgetStore(); const [measurements, setmeasurements] = useState<any>({});
const [duration, setDuration] = useState("1h")
const [name, setName] = useState(object.header ? object.header : '')
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
const { header, flotingDuration, flotingMeasurements } = useChartStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
useEffect(() => {
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
const socket = io(`http://${iotApiUrl}`);
const inputData = {
measurements,
duration,
interval: 1000,
};
const startStream = () => {
socket.emit("lastInput", inputData);
};
socket.on("connect", startStream);
socket.on("lastOutput", (response) => {
const responseData = response.input1;
if (typeof responseData === "number") {
setProgress(responseData);
}
});
return () => {
socket.off("lastOutput");
socket.emit("stop_stream"); // Stop streaming when component unmounts
socket.disconnect();
};
}, [measurements, duration, iotApiUrl]);
const fetchSavedInputes = async() => {
if (object?.id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${object?.id}/${organization}`);
if (response.status === 200) {
setmeasurements(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setName(response.data.header)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
useEffect(() => {
fetchSavedInputes();
}, []);
useEffect(() => {
if (selectedChartId?.id === object?.id) {
fetchSavedInputes();
}
}
,[header, flotingDuration, flotingMeasurements])
return ( return (
<> <>
<div className="header-wrapper" onClick={() => { <div className="header-wrapper" >
setSelectedChartId(object.id) <div className="header">{name}</div>
}}>
<div className="header">{object.header}</div>
<div className="data-values"> <div className="data-values">
<div className="value">{object.value}</div> <div className="value">{progress}</div>
<div className="per">{object.per}</div> <div className="per">{object.per}</div>
</div> </div>
</div> </div>

View File

@@ -1,6 +1,9 @@
import React, { useState } from 'react' import React, { useState, useEffect } from 'react'
import { Line } from 'react-chartjs-2' import { Line } from 'react-chartjs-2'
import useChartStore from '../../../../store/useChartStore';
import { useWidgetStore } from '../../../../store/useWidgetStore';
import axios from 'axios'; import axios from 'axios';
import io from "socket.io-client";
const WarehouseThroughputComponent = ({ const WarehouseThroughputComponent = ({
object object
@@ -8,6 +11,17 @@ const WarehouseThroughputComponent = ({
const [measurements, setmeasurements] = useState<any>({}); const [measurements, setmeasurements] = useState<any>({});
const [duration, setDuration] = useState("1h") const [duration, setDuration] = useState("1h")
const [name, setName] = useState(object.header ? object.header : '')
const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[] }>({
labels: [],
datasets: [],
});
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
const { header, flotingDuration, flotingMeasurements } = useChartStore();
const { selectedChartId } = useWidgetStore();
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const lineGraphData = { const lineGraphData = {
labels: [ labels: [
@@ -95,35 +109,94 @@ const WarehouseThroughputComponent = ({
}; };
// const fetchSavedInputes = async() => { useEffect(() => {
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
const socket = io(`http://${iotApiUrl}`);
const inputData = {
measurements,
duration,
interval: 1000,
};
const startStream = () => {
socket.emit("lineInput", inputData);
};
socket.on("connect", startStream);
socket.on("lineOutput", (response) => {
const responseData = response.data;
// Extract timestamps and values
const labels = responseData.time;
const datasets = Object.keys(measurements).map((key) => {
const measurement = measurements[key];
const datasetKey = `${measurement.name}.${measurement.fields}`;
return {
label: datasetKey,
data: responseData[datasetKey]?.values ?? [],
borderColor: "#6f42c1", // Use the desired color for the line (purple)
backgroundColor: "rgba(111, 66, 193, 0.2)", // Use a semi-transparent purple for the fill
borderWidth: 2, // Line thickness
fill: true, // Enable fill for this dataset
pointRadius: 0, // Remove dots at each data point
tension: 0.5, // Smooth interpolation for the line
};
});
setChartData({ labels, datasets });
});
return () => {
socket.off("lineOutput");
socket.emit("stop_stream"); // Stop streaming when component unmounts
socket.disconnect();
};
}, [measurements, duration, iotApiUrl]);
const fetchSavedInputes = async() => {
if (object?.id !== "") {
try {
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${object?.id}/${organization}`);
if (response.status === 200) {
setmeasurements(response.data.Data.measurements)
setDuration(response.data.Data.duration)
setName(response.data.header)
} else {
console.log("Unexpected response:", response);
}
} catch (error) {
console.error("There was an error!", error);
}
}
}
useEffect(() => {
fetchSavedInputes();
}, []);
useEffect(() => {
if (selectedChartId?.id === object?.id) {
fetchSavedInputes();
}
}
,[header, flotingDuration, flotingMeasurements])
// if (object.id !== "") {
// try {
// const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_LOCAL_BASE_URL}/api/v2/WidgetData/${id}/${organization}`);
// if (response.status === 200) {
// setmeasurements(response.data.Data.measurements)
// setDuration(response.data.Data.duration)
// setName(response.data.widgetName)
// } else {
// console.log("Unexpected response:", response);
// }
// } catch (error) {
// console.error("There was an error!", error);
// }
// }
// }
return ( return (
<> <>
<div className="header"> <div className="header">
<h2>Warehouse Throughput</h2> <h2>{name}</h2>
<p> {/* <p>
<span>(+5) more</span> in 2025 <span>(+5) more</span> in 2025
</p> </p> */}
</div> </div>
<div className="lineGraph" style={{ height: "100%" }}> <div className="lineGraph" style={{ height: "100%" }}>
<Line data={lineGraphData} options={lineGraphOptions} /> <Line data={ Object.keys(measurements).length > 0 ? chartData : lineGraphData} options={lineGraphOptions} />
</div> </div>
</> </>
) )

View File

@@ -57,7 +57,6 @@ const FilterSearch: React.FC<ModelsProps> = ({
const filteredModel = filteredModels?.filter((model) => const filteredModel = filteredModels?.filter((model) =>
model.filename.toLowerCase().includes(val.toLowerCase()) model.filename.toLowerCase().includes(val.toLowerCase())
); );
setModels(filteredModel); setModels(filteredModel);
}; };

View File

@@ -25,7 +25,6 @@ const MarketPlace = () => {
const filteredAssets = async () => { const filteredAssets = async () => {
try { try {
const filt = await getAssetImages("67d934ad0f42a1fdadb19aa6"); const filt = await getAssetImages("67d934ad0f42a1fdadb19aa6");
setModels(filt.items); setModels(filt.items);
setFilteredModels(filt.items); setFilteredModels(filt.items);
} catch {} } catch {}

View File

@@ -1,22 +1,52 @@
import { useToggleView } from '../../../store/store'; import { useTileDistance, useToggleView } from "../../../store/store";
import * as CONSTANTS from '../../../types/world/worldConstants'; import * as CONSTANTS from "../../../types/world/worldConstants";
const Ground = ({ grid, plane }: any) => { const Ground = ({ grid, plane }: any) => {
const { toggleView } = useToggleView(); const { toggleView } = useToggleView();
const savedTheme: string | null = localStorage.getItem('theme'); const savedTheme: string | null = localStorage.getItem("theme");
const { planeValue, gridValue } = useTileDistance();
return ( return (
<mesh name="Ground">
<mesh name="Ground"> <mesh
<mesh ref={grid} name="Grid" position={!toggleView ? CONSTANTS.gridConfig.position3D : CONSTANTS.gridConfig.position2D}> ref={grid}
<gridHelper args={[CONSTANTS.gridConfig.size, CONSTANTS.gridConfig.divisions, CONSTANTS.gridConfig.primaryColor, CONSTANTS.gridConfig.secondaryColor]} /> name="Grid"
</mesh> position={
<mesh ref={plane} rotation-x={CONSTANTS.planeConfig.rotation} position={!toggleView ? CONSTANTS.planeConfig.position3D : CONSTANTS.planeConfig.position2D} name="Plane" receiveShadow> !toggleView
<planeGeometry args={[CONSTANTS.planeConfig.width, CONSTANTS.planeConfig.height]} /> ? CONSTANTS.gridConfig.position3D
<meshBasicMaterial color={CONSTANTS.planeConfig.color} /> : CONSTANTS.gridConfig.position2D
</mesh> }
</mesh> >
) <gridHelper
} args={[
gridValue.size,
gridValue.divisions,
// CONSTANTS.gridConfig.size,
// CONSTANTS.gridConfig.divisions,
CONSTANTS.gridConfig.primaryColor,
CONSTANTS.gridConfig.secondaryColor,
]}
/>
</mesh>
<mesh
ref={plane}
rotation-x={CONSTANTS.planeConfig.rotation}
position={
!toggleView
? CONSTANTS.planeConfig.position3D
: CONSTANTS.planeConfig.position2D
}
name="Plane"
receiveShadow
>
<planeGeometry
args={[planeValue.width, planeValue.height]}
// args={[CONSTANTS.planeConfig.width, CONSTANTS.planeConfig.height]}
/>
<meshBasicMaterial color={CONSTANTS.planeConfig.color} />
</mesh>
</mesh>
);
};
export default Ground; export default Ground;

View File

@@ -1,9 +1,22 @@
import { useRef, useEffect} from 'react'; import { useRef, useEffect } from "react";
import { useThree } from '@react-three/fiber'; import { useThree } from "@react-three/fiber";
import * as THREE from 'three'; import * as THREE from "three";
import { useAzimuth, useElevation, useShadows, useSunPosition, useFloorItems, useWallItems } from '../../../store/store'; import {
import * as CONSTANTS from '../../../types/world/worldConstants'; useAzimuth,
const shadowWorker = new Worker(new URL('../../../services/factoryBuilder/webWorkers/shadowWorker', import.meta.url)); useElevation,
useShadows,
useSunPosition,
useFloorItems,
useWallItems,
useTileDistance,
} from "../../../store/store";
import * as CONSTANTS from "../../../types/world/worldConstants";
const shadowWorker = new Worker(
new URL(
"../../../services/factoryBuilder/webWorkers/shadowWorker",
import.meta.url
)
);
export default function Shadows() { export default function Shadows() {
const { shadows, setShadows } = useShadows(); const { shadows, setShadows } = useShadows();
@@ -15,6 +28,7 @@ export default function Shadows() {
const { azimuth, setAzimuth } = useAzimuth(); const { azimuth, setAzimuth } = useAzimuth();
const { floorItems } = useFloorItems(); const { floorItems } = useFloorItems();
const { wallItems } = useWallItems(); const { wallItems } = useWallItems();
const { planeValue } = useTileDistance();
useEffect(() => { useEffect(() => {
gl.shadowMap.enabled = true; gl.shadowMap.enabled = true;
@@ -48,9 +62,9 @@ export default function Shadows() {
useEffect(() => { useEffect(() => {
if (controls && shadows) { if (controls && shadows) {
updateShadows(); updateShadows();
(controls as any).addEventListener('update', updateShadows); (controls as any).addEventListener("update", updateShadows);
return () => { return () => {
(controls as any).removeEventListener('update', updateShadows); (controls as any).removeEventListener("update", updateShadows);
}; };
} }
}, [controls, elevation, azimuth, shadows]); }, [controls, elevation, azimuth, shadows]);
@@ -75,10 +89,24 @@ export default function Shadows() {
shadow-normalBias={CONSTANTS.shadowConfig.shadownormalBias} shadow-normalBias={CONSTANTS.shadowConfig.shadownormalBias}
/> />
<object3D ref={targetRef} /> <object3D ref={targetRef} />
<mesh position={CONSTANTS.shadowConfig.shadowMaterialPosition} rotation={CONSTANTS.shadowConfig.shadowMaterialRotation} receiveShadow> <mesh
<planeGeometry args={[CONSTANTS.planeConfig.width, CONSTANTS.planeConfig.height]} /> position={CONSTANTS.shadowConfig.shadowMaterialPosition}
<shadowMaterial opacity={CONSTANTS.shadowConfig.shadowMaterialOpacity} transparent /> rotation={CONSTANTS.shadowConfig.shadowMaterialRotation}
receiveShadow
>
{/* <planeGeometry
args={[CONSTANTS.planeConfig.width, CONSTANTS.planeConfig.height]}
/>
<shadowMaterial
opacity={CONSTANTS.shadowConfig.shadowMaterialOpacity}
transparent
/> */}
<planeGeometry args={[planeValue.width, planeValue.height]} />
<shadowMaterial
opacity={CONSTANTS.shadowConfig.shadowMaterialOpacity}
transparent
/>
</mesh> </mesh>
</> </>
); );
} }

View File

@@ -30,6 +30,8 @@ import {
useWalls, useWalls,
useToolMode, useToolMode,
useRefTextUpdate, useRefTextUpdate,
useRenderDistance,
useLimitDistance,
} from "../../../store/store"; } from "../../../store/store";
////////// 3D Function Imports ////////// ////////// 3D Function Imports //////////
@@ -117,6 +119,8 @@ export default function World() {
const { roofVisibility, setRoofVisibility } = useRoofVisibility(); const { roofVisibility, setRoofVisibility } = useRoofVisibility();
const { wallVisibility, setWallVisibility } = useWallVisibility(); const { wallVisibility, setWallVisibility } = useWallVisibility();
const { shadows, setShadows } = useShadows(); const { shadows, setShadows } = useShadows();
const { renderDistance, setRenderDistance } = useRenderDistance();
const { limitDistance, setLimitDistance } = useLimitDistance();
const { updateScene, setUpdateScene } = useUpdateScene(); const { updateScene, setUpdateScene } = useUpdateScene();
const { walls, setWalls } = useWalls(); const { walls, setWalls } = useWalls();
const { refTextupdate, setRefTextUpdate } = useRefTextUpdate(); const { refTextupdate, setRefTextUpdate } = useRefTextUpdate();
@@ -200,6 +204,8 @@ export default function World() {
setRoofVisibility(visibility.roofVisibility); setRoofVisibility(visibility.roofVisibility);
setWallVisibility(visibility.wallVisibility); setWallVisibility(visibility.wallVisibility);
setShadows(visibility.shadowVisibility); setShadows(visibility.shadowVisibility);
setRenderDistance(visibility.renderDistance);
setLimitDistance(visibility.limitDistance);
} }
} }
fetchVisibility(); fetchVisibility();

View File

@@ -1,32 +1,43 @@
import { setEnvironment } from './setEnvironment'; import { setEnvironment } from "./setEnvironment";
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const findEnvironment = async (organization: string, userId: string) => { export const findEnvironment = async (organization: string, userId: string) => {
try { try {
const response = await fetch(`${url_Backend_dwinzo}/api/v1/findEnvironments/${organization}/${userId}`, { const response = await fetch(
method: "GET", `${url_Backend_dwinzo}/api/v1/findEnvironments/${organization}/${userId}`,
headers: { {
"Content-Type": "application/json", method: "GET",
}, headers: {
}); "Content-Type": "application/json",
},
}
);
if (!response.ok) { if (!response.ok) {
throw new Error("Failed to get wall and roof visibility"); throw new Error("Failed to get wall and roof visibility");
}
const result = await response.json();
if (result === "user not found") {
const userpos = setEnvironment(organization, userId, false, false, false);
return userpos;
} else {
return result;
}
} catch (error) {
if (error instanceof Error) {
throw new Error(error.message);
} else {
throw new Error("An unknown error occurred");
}
} }
};
const result = await response.json();
if (result === "user not found") {
const userpos = setEnvironment(
organization,
userId,
false,
false,
false,
0,
true
);
return userpos;
} else {
return result;
}
} catch (error) {
if (error instanceof Error) {
throw new Error(error.message);
} else {
throw new Error("An unknown error occurred");
}
}
};

View File

@@ -1,26 +1,45 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const setEnvironment = async (organization: string, userId: string, wallVisibility: Boolean, roofVisibility: Boolean, shadowVisibility: Boolean) => { export const setEnvironment = async (
try { organization: string,
const response = await fetch(`${url_Backend_dwinzo}/api/v1/setEvironments`, { userId: string,
method: "POST", wallVisibility: Boolean,
headers: { roofVisibility: Boolean,
"Content-Type": "application/json", shadowVisibility: Boolean,
}, renderDistance: number,
body: JSON.stringify({ organization, userId, wallVisibility, roofVisibility, shadowVisibility }), limitDistance: boolean
}); ) => {
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/v1/setEvironments`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
organization,
userId,
wallVisibility,
roofVisibility,
shadowVisibility,
renderDistance,
limitDistance,
}),
}
);
if (!response.ok) { if (!response.ok) {
throw new Error("Failed to set wall and roof visibility"); throw new Error("Failed to set wall and roof visibility");
}
const result = await response.json();
return result;
} catch (error) {
if (error instanceof Error) {
throw new Error(error.message);
} else {
throw new Error("An unknown error occurred");
}
} }
};
const result = await response.json();
return result;
} catch (error) {
if (error instanceof Error) {
throw new Error(error.message);
} else {
throw new Error("An unknown error occurred");
}
}
};

View File

@@ -6,8 +6,8 @@ export const fetchAssets = async () => {
throw new Error("Network response was not ok"); throw new Error("Network response was not ok");
} }
const result = await response.json(); const result = await response.json();
const last10Assets = result.slice(-10); // const last10Assets = result.slice(-10);
console.log('last10Assets: ', last10Assets); // console.log('last10Assets: ', last10Assets);
return result; return result;
} catch (error) { } catch (error) {
console.log("error: ", error); console.log("error: ", error);

View File

@@ -264,7 +264,7 @@ export const useAzimuth = create<any>((set: any) => ({
})); }));
export const useRenderDistance = create<any>((set: any) => ({ export const useRenderDistance = create<any>((set: any) => ({
renderDistance: 50, renderDistance: 40,
setRenderDistance: (x: any) => set({ renderDistance: x }), setRenderDistance: (x: any) => set({ renderDistance: x }),
})); }));
@@ -409,3 +409,22 @@ export const useWidgetSubOption = create<any>((set: any) => ({
widgetSubOption: "2D", widgetSubOption: "2D",
setWidgetSubOption: (x: any) => set({ widgetSubOption: x }), setWidgetSubOption: (x: any) => set({ widgetSubOption: x }),
})); }));
export const useLimitDistance = create<any>((set: any) => ({
limitDistance: true,
setLimitDistance: (x: any) => set({ limitDistance: x }),
}));
export const useTileDistance = create<any>((set: any) => ({
gridValue: { size: 300, divisions: 75 },
planeValue: { height: 300, width: 300 },
setGridValue: (value: any) =>
set((state: any) => ({
gridValue: { ...state.gridValue, ...value },
})),
setPlaneValue: (value: any) =>
set((state: any) => ({
planeValue: { ...state.planeValue, ...value },
})),
}));

View File

@@ -10,9 +10,15 @@ interface MeasurementStore {
interval: number; interval: number;
duration: string; duration: string;
name: string; name: string;
header: string;
flotingDuration: string;
flotingMeasurements: Record<string, Measurement>; // Change array to Record<string, Measurement>
setMeasurements: (newMeasurements: Record<string, Measurement>) => void; setMeasurements: (newMeasurements: Record<string, Measurement>) => void;
updateDuration: (newDuration: string) => void; updateDuration: (newDuration: string) => void;
updateName: (newName: string) => void; updateName: (newName: string) => void;
updateHeader: (newHeader: string) => void;
updateFlotingDuration: (newFlotingDuration: string) => void;
setFlotingMeasurements: (newFlotingMeasurements: Record<string, Measurement>) => void;
} }
const useChartStore = create<MeasurementStore>((set) => ({ const useChartStore = create<MeasurementStore>((set) => ({
@@ -20,6 +26,9 @@ const useChartStore = create<MeasurementStore>((set) => ({
interval: 1000, interval: 1000,
duration: "1h", duration: "1h",
name:'', name:'',
header:'',
flotingDuration: "1h",
flotingMeasurements: {},
setMeasurements: (newMeasurements) => setMeasurements: (newMeasurements) =>
set(() => ({ measurements: newMeasurements })), set(() => ({ measurements: newMeasurements })),
@@ -28,7 +37,16 @@ const useChartStore = create<MeasurementStore>((set) => ({
set(() => ({ duration: newDuration })), set(() => ({ duration: newDuration })),
updateName: (newName) => updateName: (newName) =>
set(() => ({ duration: newName })), set(() => ({ name: newName })),
updateHeader: (newHeader) =>
set(() => ({ header: newHeader })),
updateFlotingDuration: (newFlotingDuration) =>
set(() => ({ flotingDuration: newFlotingDuration })),
setFlotingMeasurements: (newFlotingMeasurements) =>
set(() => ({ flotingMeasurements: newFlotingMeasurements })),
})); }));
export default useChartStore; export default useChartStore;

View File

@@ -551,7 +551,7 @@ input {
} }
.input-value { .input-value {
width: 40px; width: 42px;
text-align: center; text-align: center;
&::-webkit-inner-spin-button, &::-webkit-inner-spin-button,
&::-webkit-outer-spin-button { &::-webkit-outer-spin-button {

View File

@@ -113,7 +113,9 @@
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
gap: 6px; gap: 6px;
.assets-container {
height: auto;
}
.icon { .icon {
position: absolute; position: absolute;
top: 12px; top: 12px;

View File

@@ -253,7 +253,7 @@
.user-profile-container { .user-profile-container {
display: flex; display: flex;
.user-profile{ .user-profile {
background: var(--accent-color); background: var(--accent-color);
color: var(--primary-color); color: var(--primary-color);
} }
@@ -320,9 +320,7 @@
.dataSideBar { .dataSideBar {
.inputs-wrapper { .inputs-wrapper {
.datas { .datas {
.input-value { .input-value {
padding: 5px 10px; padding: 5px 10px;
} }
@@ -688,7 +686,7 @@
font-weight: var(--font-weight-regular); font-weight: var(--font-weight-regular);
padding: 8px 0; padding: 8px 0;
} }
.input-toggle-container{ .input-toggle-container {
padding: 0; padding: 0;
margin-bottom: 6px; margin-bottom: 6px;
} }
@@ -963,6 +961,7 @@
padding: 0 6px; padding: 0 6px;
.assets-wrapper { .assets-wrapper {
width: 100%;
position: relative; position: relative;
margin: 8px 10px; margin: 8px 10px;
@@ -1010,9 +1009,11 @@
top: 50%; top: 50%;
right: -10px; right: -10px;
transform: translate(0, -50%); transform: translate(0, -50%);
background: linear-gradient(144.19deg, background: linear-gradient(
#f1e7cd 16.62%, 144.19deg,
#fffaef 85.81%); #f1e7cd 16.62%,
#fffaef 85.81%
);
} }
.category-image { .category-image {
@@ -1075,4 +1076,52 @@
cursor: pointer; cursor: pointer;
} }
} }
} }
.assets-container {
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
height: 100%;
gap: 3px;
padding: 10px 0;
.assets {
width: 117px;
height: 95px;
border-radius: 3.59px;
background-color: var(--background-color-gray);
padding: 8px;
padding-top: 12px;
font-weight: $medium-weight;
position: relative;
overflow: hidden;
.asset-name {
position: relative;
z-index: 3;
font-size: var(--font-size-regular);
}
.asset-image {
height: 100%;
width: 100%;
position: absolute;
// top: 50%;
// right: 5px;
// transform: translate(0, -50%);
top: 0;
left: 0;
z-index: 2;
}
}
}
.assets-result {
width: 100%;
height: 100%;
margin: 8px 10px;
.assets-wrapper {
margin: 0;
}
}

View File

@@ -545,9 +545,9 @@
.floating-wrapper { .floating-wrapper {
.icon { .icon {
width: 25px !important; // width: 25px !important;
height: 25px !important; // height: 25px !important;
background-color: transparent; // background-color: transparent;
} }
.kebab { .kebab {
@@ -559,6 +559,7 @@
z-index: 10; z-index: 10;
cursor: pointer; cursor: pointer;
@include flex-center; @include flex-center;
background-color: transparent !important;
} }
.kebab-options { .kebab-options {

View File

@@ -59,39 +59,39 @@ export type ThreeDimension = {
}; };
export type GridConfig = { export type GridConfig = {
size: number; size: number;
divisions: number; divisions: number;
primaryColor: string; primaryColor: string;
secondaryColor: string; secondaryColor: string;
position2D: [x: number, y: number, z: number]; position2D: [x: number, y: number, z: number];
position3D: [x: number, y: number, z: number]; position3D: [x: number, y: number, z: number];
} };
export type PlaneConfig = { export type PlaneConfig = {
position2D: [x: number, y: number, z: number]; position2D: [x: number, y: number, z: number];
position3D: [x: number, y: number, z: number]; position3D: [x: number, y: number, z: number];
rotation: number; rotation: number;
width: number; width: number;
height: number; height: number;
color: string; color: string;
} };
export type ShadowConfig = { export type ShadowConfig = {
shadowOffset: number, shadowOffset: number;
shadowmapSizewidth: number, shadowmapSizewidth: number;
shadowmapSizeheight: number, shadowmapSizeheight: number;
shadowcamerafar: number, shadowcamerafar: number;
shadowcameranear: number, shadowcameranear: number;
shadowcameratop: number, shadowcameratop: number;
shadowcamerabottom: number, shadowcamerabottom: number;
shadowcameraleft: number, shadowcameraleft: number;
shadowcameraright: number, shadowcameraright: number;
shadowbias: number, shadowbias: number;
shadownormalBias: number, shadownormalBias: number;
shadowMaterialPosition: [x: number, y: number, z: number], shadowMaterialPosition: [x: number, y: number, z: number];
shadowMaterialRotation: [x: number, y: number, z: number], shadowMaterialRotation: [x: number, y: number, z: number];
shadowMaterialOpacity: number, shadowMaterialOpacity: number;
} };
export type SkyConfig = { export type SkyConfig = {
defaultTurbidity: number; defaultTurbidity: number;
@@ -109,34 +109,34 @@ export type AssetConfig = {
}; };
export type PointConfig = { export type PointConfig = {
defaultInnerColor: string; defaultInnerColor: string;
defaultOuterColor: string; defaultOuterColor: string;
deleteColor: string; deleteColor: string;
boxScale: [number, number, number]; boxScale: [number, number, number];
wallOuterColor: string; wallOuterColor: string;
floorOuterColor: string; floorOuterColor: string;
aisleOuterColor: string; aisleOuterColor: string;
zoneOuterColor: string; zoneOuterColor: string;
snappingThreshold: number; snappingThreshold: number;
} };
export type LineConfig = { export type LineConfig = {
tubularSegments: number; tubularSegments: number;
radius: number; radius: number;
radialSegments: number; radialSegments: number;
wallName: string; wallName: string;
floorName: string; floorName: string;
aisleName: string; aisleName: string;
zoneName: string; zoneName: string;
referenceName: string; referenceName: string;
lineIntersectionPoints: number; lineIntersectionPoints: number;
defaultColor: string; defaultColor: string;
wallColor: string; wallColor: string;
floorColor: string; floorColor: string;
aisleColor: string; aisleColor: string;
zoneColor: string; zoneColor: string;
helperColor: string; helperColor: string;
} };
export type WallConfig = { export type WallConfig = {
defaultColor: string; defaultColor: string;
@@ -145,10 +145,10 @@ export type WallConfig = {
}; };
export type FloorConfig = { export type FloorConfig = {
defaultColor: string; defaultColor: string;
height: number; height: number;
textureScale: number; textureScale: number;
} };
export type RoofConfig = { export type RoofConfig = {
defaultColor: string; defaultColor: string;
@@ -156,16 +156,16 @@ export type RoofConfig = {
}; };
export type AisleConfig = { export type AisleConfig = {
width: number; width: number;
height: number; height: number;
defaultColor: number; defaultColor: number;
} };
export type ZoneConfig = { export type ZoneConfig = {
defaultColor: string; defaultColor: string;
height: number; height: number;
color: string; color: string;
} };
export type ColumnConfig = { export type ColumnConfig = {
defaultColor: string; defaultColor: string;
@@ -242,24 +242,24 @@ export const threeDimension: ThreeDimension = {
export const camPositionUpdateInterval: number = 200; // Interval for updating the camera position export const camPositionUpdateInterval: number = 200; // Interval for updating the camera position
export const gridConfig: GridConfig = { export const gridConfig: GridConfig = {
size: 300, // Size of the grid size: 300, // Size of the grid
divisions: 75, // Number of divisions in the grid divisions: 75, // Number of divisions in the grid
primaryColor: savedTheme === "dark" ? "#131313" : "#d5d5d5", // Primary color of the grid primaryColor: savedTheme === "dark" ? "#131313" : "#d5d5d5", // Primary color of the grid
secondaryColor: savedTheme === "dark" ? "#434343" : "#e3e3e3", // Secondary color of the grid secondaryColor: savedTheme === "dark" ? "#434343" : "#e3e3e3", // Secondary color of the grid
position2D: [0, 0.1, 0], // Position of the grid in 2D view position2D: [0, 0.1, 0], // Position of the grid in 2D view
position3D: [0, -0.5, 0], // Position of the grid in 3D view position3D: [0, -0.5, 0], // Position of the grid in 3D view
} };
export const planeConfig: PlaneConfig = { export const planeConfig: PlaneConfig = {
position2D: [0, -0.5, 0], // Position of the plane position2D: [0, -0.5, 0], // Position of the plane
position3D: [0, -0.65, 0], // Position of the plane position3D: [0, -0.65, 0], // Position of the plane
rotation: -Math.PI / 2, // Rotation of the plane rotation: -Math.PI / 2, // Rotation of the plane
width: 300, // Width of the plane width: 300, // Width of the plane
height: 300, // Height of the plane height: 300, // Height of the plane
color: savedTheme === "dark" ? "#323232" : "#f3f3f3" // Color of the plane color: savedTheme === "dark" ? "#323232" : "#f3f3f3", // Color of the plane
} };
export const shadowConfig: ShadowConfig = { export const shadowConfig: ShadowConfig = {
shadowOffset: 50, // Offset of the shadow shadowOffset: 50, // Offset of the shadow
@@ -349,10 +349,10 @@ export const aisleConfig: AisleConfig = {
}; };
export const zoneConfig: ZoneConfig = { export const zoneConfig: ZoneConfig = {
defaultColor: "black", // Default color of the zones defaultColor: "black", // Default color of the zones
height: 3, height: 3,
color: "#8656DF" // Color of the zones color: "#8656DF", // Color of the zones
} };
export const columnConfig: ColumnConfig = { export const columnConfig: ColumnConfig = {
defaultColor: "White", // Default color of the columns defaultColor: "White", // Default color of the columns