Hidden panel zone based template Sc shot

This commit is contained in:
Nalvazhuthi
2025-04-09 18:06:08 +05:30
46 changed files with 2378 additions and 1128 deletions

View File

@@ -35,19 +35,32 @@ interface ProductionCapacityProps {
// onPointerDown:any
}
const ProductionCapacity: React.FC<ProductionCapacityProps> = ({ id, type, position, rotation, onContextMenu }) => {
const ProductionCapacity: React.FC<ProductionCapacityProps> = ({
id,
type,
position,
rotation,
onContextMenu,
}) => {
const { selectedChartId, setSelectedChartId } = useWidgetStore();
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
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[] }>({
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]
const organization = email?.split("@")[1]?.split(".")[0];
// Chart data for a week
const defaultChartData = {
labels: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], // Days of the week
@@ -101,7 +114,8 @@ const ProductionCapacity: React.FC<ProductionCapacityProps> = ({ id, type, posit
};
useEffect(() => {
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0)
return;
const socket = io(`http://${iotApiUrl}`);
@@ -111,7 +125,6 @@ const ProductionCapacity: React.FC<ProductionCapacityProps> = ({ id, type, posit
interval: 1000,
};
const startStream = () => {
socket.emit("lineInput", inputData);
};
@@ -148,22 +161,20 @@ const ProductionCapacity: React.FC<ProductionCapacityProps> = ({ id, type, posit
}, [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}`);
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)
setmeasurements(response.data.Data.measurements);
setDuration(response.data.Data.duration);
setName(response.data.widgetName);
} else {
}
} catch (error) {
}
} catch (error) { }
}
}
};
useEffect(() => {
fetchSavedInputes();
@@ -173,13 +184,9 @@ const ProductionCapacity: React.FC<ProductionCapacityProps> = ({ id, type, posit
if (selectedChartId?.id === id) {
fetchSavedInputes();
}
}
, [chartMeasurements, chartDuration, widgetName])
}, [chartMeasurements, chartDuration, widgetName]);
useEffect(() => {
}, [rotation])
useEffect(() => { }, [rotation]);
const rotationDegrees = {
x: (rotation[0] * 180) / Math.PI,
y: (rotation[1] * 180) / Math.PI,
@@ -187,30 +194,44 @@ const ProductionCapacity: React.FC<ProductionCapacityProps> = ({ id, type, posit
};
const transformStyle = {
transform: `rotateX(${rotationDegrees.x}deg) rotateY(${rotationDegrees.y}deg) rotateZ(${rotationDegrees.z}deg)`,
transform: `rotateX(${rotationDegrees.x}deg) rotateY(${rotationDegrees.y}deg) rotateZ(${rotationDegrees.z}deg) translate(-50%, -50%)`,
};
return (
<Html position={position}
<Html
position={position}
scale={[0.5, 0.5, 0.5]}
transform
sprite
zIndexRange={[1,0]}
// center
// distanceFactor={10} // Adjusted for visual balance
zIndexRange={[1, 0]}
style={{
transform: transformStyle.transform,
transformStyle: 'preserve-3d',
transition: 'transform 0.1s ease-out'
}}>
<div className="productionCapacity-wrapper card"
transformStyle: "preserve-3d",
transition: "transform 0.1s ease-out",
}}
onDragOver={(e) => {
e.preventDefault();
e.stopPropagation();
}}
onDrop={(e) => {
e.preventDefault();
// e.stopPropagation();
}}
wrapperClass="pointer-none"
>
<div
className={`productionCapacity-wrapper card ${selectedChartId?.id === id ? "activeChart" : ""}`}
onClick={() => setSelectedChartId({ id: id, type: type })}
onContextMenu={onContextMenu}
style={{
width: '300px', // Original width
height: '300px', // Original height
width: "300px", // Original width
height: "300px", // Original height
transform: transformStyle.transform,
transformStyle: 'preserve-3d'
transformStyle: "preserve-3d",
position: "absolute",
}}
>
<div className="headeproductionCapacityr-wrapper">
@@ -233,10 +254,18 @@ const ProductionCapacity: React.FC<ProductionCapacityProps> = ({ id, type, posit
</div>{" "}
<div className="bar-chart charts">
{/* Bar Chart */}
<Bar data={Object.keys(measurements).length > 0 ? chartData : defaultChartData} options={chartOptions} />
<Bar
data={
Object.keys(measurements).length > 0
? chartData
: defaultChartData
}
options={chartOptions}
/>
</div>
</div>
</Html>
);
};

View File

@@ -46,20 +46,32 @@ interface ReturnOfInvestmentProps {
rotation: [number, number, number];
onContextMenu?: (event: React.MouseEvent) => void;
}
const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, position, rotation, onContextMenu }) => {
const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({
id,
type,
position,
rotation,
onContextMenu,
}) => {
const { selectedChartId, setSelectedChartId } = useWidgetStore();
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
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[] }>({
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]
const organization = email?.split("@")[1]?.split(".")[0];
// Improved sample data for the smooth curve graph (single day)
const graphData: ChartData<"line"> = {
labels: [
@@ -129,7 +141,8 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, posit
};
useEffect(() => {
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0)
return;
const socket = io(`http://${iotApiUrl}`);
@@ -139,7 +152,6 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, posit
interval: 1000,
};
const startStream = () => {
socket.emit("lineInput", inputData);
};
@@ -157,8 +169,10 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, posit
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)",
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
@@ -177,14 +191,15 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, posit
}, [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}`);
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)
setmeasurements(response.data.Data.measurements);
setDuration(response.data.Data.duration);
setName(response.data.widgetName);
} else {
console.log("Unexpected response:", response);
}
@@ -192,7 +207,7 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, posit
console.error("There was an error!", error);
}
}
}
};
useEffect(() => {
fetchSavedInputes();
@@ -202,8 +217,7 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, posit
if (selectedChartId?.id === id) {
fetchSavedInputes();
}
}
, [chartMeasurements, chartDuration, widgetName])
}, [chartMeasurements, chartDuration, widgetName]);
const rotationDegrees = {
x: (rotation[0] * 180) / Math.PI,
y: (rotation[1] * 180) / Math.PI,
@@ -215,26 +229,32 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, posit
};
return (
<Html position={[position[0], position[1], position[2]]}
<Html
position={[position[0], position[1], position[2]]}
scale={[0.5, 0.5, 0.5]}
transform
zIndexRange={[1, 0]}
sprite
style={{
transform: transformStyle.transform,
transformStyle: 'preserve-3d',
transition: 'transform 0.1s ease-out'
transformStyle: "preserve-3d",
transition: "transform 0.1s ease-out",
}}
>
<div className="returnOfInvestment card"
<div
className={`returnOfInvestment card ${
selectedChartId?.id === id ? "activeChart" : ""
}`}
onClick={() => setSelectedChartId({ id: id, type: type })}
onContextMenu={onContextMenu}
>
<div className="header">Return of Investment</div>
<div className="lineGraph charts">
{/* Smooth curve graph with two datasets */}
<SmoothLineGraphComponent data={Object.keys(measurements).length > 0 ? chartData : graphData} options={graphOptions} />
<SmoothLineGraphComponent
data={Object.keys(measurements).length > 0 ? chartData : graphData}
options={graphOptions}
/>
</div>
<div className="returns-wrapper">
<div className="icon">

View File

@@ -13,16 +13,26 @@ interface StateWorkingProps {
rotation: [number, number, number];
onContextMenu?: (event: React.MouseEvent) => void;
}
const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotation, onContextMenu }) => {
const StateWorking: React.FC<StateWorkingProps> = ({
id,
type,
position,
rotation,
onContextMenu,
}) => {
const { selectedChartId, setSelectedChartId } = useWidgetStore();
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
const {
measurements: chartMeasurements,
duration: chartDuration,
name: widgetName,
} = useChartStore();
const [measurements, setmeasurements] = useState<any>({});
const [duration, setDuration] = useState("1h")
const [name, setName] = useState("Widget")
const [duration, setDuration] = useState("1h");
const [name, setName] = useState("Widget");
const [datas, setDatas] = useState<any>({});
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
const organization = email?.split("@")[1]?.split(".")[0];
// const datas = [
// { key: "Oil Tank:", value: "24/341" },
// { key: "Oil Refin:", value: 36.023 },
@@ -33,7 +43,8 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
// ];
useEffect(() => {
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0)
return;
const socket = io(`http://${iotApiUrl}`);
const inputData = {
measurements,
@@ -46,7 +57,6 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
socket.on("connect", startStream);
socket.on("lastOutput", (response) => {
const responseData = response;
setDatas(responseData);
});
@@ -59,14 +69,15 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
}, [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}`);
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)
setmeasurements(response.data.Data.measurements);
setDuration(response.data.Data.duration);
setName(response.data.widgetName);
} else {
console.log("Unexpected response:", response);
}
@@ -74,10 +85,7 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
console.error("There was an error!", error);
}
}
}
};
useEffect(() => {
fetchSavedInputes();
@@ -87,8 +95,7 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
if (selectedChartId?.id === id) {
fetchSavedInputes();
}
}
, [chartMeasurements, chartDuration, widgetName])
}, [chartMeasurements, chartDuration, widgetName]);
const rotationDegrees = {
x: (rotation[0] * 180) / Math.PI,
@@ -100,19 +107,22 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
transform: `rotateX(${rotationDegrees.x}deg) rotateY(${rotationDegrees.y}deg) rotateZ(${rotationDegrees.z}deg)`,
};
return (
<Html position={[position[0], position[1], position[2]]}
<Html
position={[position[0], position[1], position[2]]}
scale={[0.5, 0.5, 0.5]}
transform
zIndexRange={[1, 0]}
sprite
style={{
transform: transformStyle.transform,
transformStyle: 'preserve-3d',
transition: 'transform 0.1s ease-out'
transformStyle: "preserve-3d",
transition: "transform 0.1s ease-out",
}}
>
<div className="stateWorking-wrapper card"
<div
className={`stateWorking-wrapper card ${
selectedChartId?.id === id ? "activeChart" : ""
}`}
onClick={() => setSelectedChartId({ id: id, type: type })}
onContextMenu={onContextMenu}
>
@@ -120,12 +130,10 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
<div className="header">
<span>State</span>
<span>
{datas?.input1 ? datas.input1 : 'input1'} <span>.</span>
{datas?.input1 ? datas.input1 : "input1"} <span>.</span>
</span>
</div>
<div className="img">
{/* <img src={image} alt="" /> */}
</div>
<div className="img">{/* <img src={image} alt="" /> */}</div>
</div>
{/* Data */}
<div className="data-wrapper">
@@ -136,28 +144,52 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
</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 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 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 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 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 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 className="data">
{measurements?.input7?.fields
? measurements.input7.fields
: "input7"}
</div>
<div className="key">{datas?.input7 ? datas.input7 : "data"}</div>
</div>
</div>
</div>
@@ -166,5 +198,3 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
};
export default StateWorking;

View File

@@ -49,20 +49,32 @@ interface ThroughputProps {
onContextMenu?: (event: React.MouseEvent) => void;
}
const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, onContextMenu }) => {
const Throughput: React.FC<ThroughputProps> = ({
id,
type,
position,
rotation,
onContextMenu,
}) => {
const { selectedChartId, setSelectedChartId } = useWidgetStore();
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
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[] }>({
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]
const organization = email?.split("@")[1]?.split(".")[0];
// Sample data for the line graph
const graphData: ChartData<"line"> = {
@@ -112,7 +124,8 @@ const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, o
};
useEffect(() => {
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0)
return;
const socket = io(`http://${iotApiUrl}`);
@@ -122,7 +135,6 @@ const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, o
interval: 1000,
};
const startStream = () => {
socket.emit("lineInput", inputData);
};
@@ -157,14 +169,15 @@ const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, o
}, [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}`);
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)
setmeasurements(response.data.Data.measurements);
setDuration(response.data.Data.duration);
setName(response.data.widgetName);
} else {
console.log("Unexpected response:", response);
}
@@ -172,7 +185,7 @@ const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, o
console.error("There was an error!", error);
}
}
}
};
useEffect(() => {
fetchSavedInputes();
@@ -182,8 +195,7 @@ const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, o
if (selectedChartId?.id === id) {
fetchSavedInputes();
}
}
, [chartMeasurements, chartDuration, widgetName])
}, [chartMeasurements, chartDuration, widgetName]);
const rotationDegrees = {
x: (rotation[0] * 180) / Math.PI,
y: (rotation[1] * 180) / Math.PI,
@@ -195,19 +207,22 @@ const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, o
};
return (
<Html position={[position[0], position[1], position[2]]}
<Html
position={[position[0], position[1], position[2]]}
scale={[0.5, 0.5, 0.5]}
transform
zIndexRange={[1, 0]}
sprite
style={{
transform: transformStyle.transform,
transformStyle: 'preserve-3d',
transition: 'transform 0.1s ease-out'
transformStyle: "preserve-3d",
transition: "transform 0.1s ease-out",
}}
>
<div className="throughput-wrapper"
<div
className={`throughput-wrapper card ${
selectedChartId?.id === id ? "activeChart" : ""
}`}
onClick={() => setSelectedChartId({ id: id, type: type })}
onContextMenu={onContextMenu}
>
@@ -234,7 +249,10 @@ const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, o
</div>
<div className="line-graph">
{/* Line graph using react-chartjs-2 */}
<LineGraphComponent data={Object.keys(measurements).length > 0 ? chartData : graphData} options={graphOptions} />
<LineGraphComponent
data={Object.keys(measurements).length > 0 ? chartData : graphData}
options={graphOptions}
/>
</div>
<div className="footer">
You made an extra <span className="value">$1256.13</span> this month

View File

@@ -147,7 +147,7 @@ const Assets: React.FC = () => {
<div className="assets-container">
{categoryAssets &&
categoryAssets?.map((asset: any, index: number) => (
<div key={index} className="assets">
<div key={index} className="assets" id={asset.filename}>
<img
src={asset?.thumbnail}
alt={asset.filename}
@@ -171,6 +171,7 @@ const Assets: React.FC = () => {
<div className="assets-wrapper">
<div
className="back-button"
id="asset-backButtom"
onClick={() => {
setSelectedCategory(null);
setCategoryAssets([]);
@@ -182,7 +183,7 @@ const Assets: React.FC = () => {
<div className="assets-container">
{categoryAssets &&
categoryAssets?.map((asset: any, index: number) => (
<div key={index} className="assets">
<div key={index} className="assets" id={asset.filename}>
<img
src={asset?.thumbnail}
alt={asset.filename}
@@ -222,6 +223,7 @@ const Assets: React.FC = () => {
<div
key={index}
className="category"
id={category}
onClick={() => fetchCategoryAssets(category)}
>
<img

View File

@@ -4,6 +4,7 @@ import useTemplateStore from "../../../../store/useTemplateStore";
import { useSelectedZoneStore } from "../../../../store/useZoneStore";
import { getTemplateData } from "../../../../services/realTimeVisulization/zoneData/getTemplate";
import { useSocketStore } from "../../../../store/store";
import RenameInput from "../../../ui/inputs/RenameInput";
const Templates = () => {
const { templates, removeTemplate, setTemplates } = useTemplateStore();
@@ -34,7 +35,10 @@ const Templates = () => {
templateID: id,
};
if (visualizationSocket) {
visualizationSocket.emit("v2:viz-template:deleteTemplate", deleteTemplate);
visualizationSocket.emit(
"v2:viz-template:deleteTemplate",
deleteTemplate
);
}
removeTemplate(id);
} catch (error) {
@@ -65,11 +69,15 @@ const Templates = () => {
widgets: template.widgets,
});
useDroppedObjectsStore.getState().setZone(selectedZone.zoneName, selectedZone.zoneId);
useDroppedObjectsStore
.getState()
.setZone(selectedZone.zoneName, selectedZone.zoneId);
if (Array.isArray(template.floatingWidget)) {
template.floatingWidget.forEach((val: any) => {
useDroppedObjectsStore.getState().addObject(selectedZone.zoneName, val);
useDroppedObjectsStore
.getState()
.addObject(selectedZone.zoneName, val);
});
}
} catch (error) {
@@ -79,7 +87,7 @@ const Templates = () => {
return (
<div className="template-list">
{templates.map((template) => (
{templates.map((template, index) => (
<div key={template.id} className="template-item">
{template?.snapshot && (
<div className="template-image-container">
@@ -96,7 +104,8 @@ const Templates = () => {
onClick={() => handleLoadTemplate(template)}
className="template-name"
>
{template.name}
{/* {`Template ${index + 1}`} */}
<RenameInput value={`Template ${index + 1}`} />
</div>
<button
onClick={() => handleDeleteTemplate(template.id)}

View File

@@ -21,11 +21,13 @@ const Widgets3D = () => {
className="widget-item"
draggable
onDragStart={(e) => {
let name = widget.name
let crt = e.target
if (crt instanceof HTMLElement) {
const widget = crt.cloneNode(true) as HTMLElement;
e.dataTransfer.setDragImage(widget, 0, 0)
e.dataTransfer.effectAllowed = "move"
e.dataTransfer.setData("text/plain", "ui-" + name)
}
}}
onPointerDown={() => {
@@ -40,7 +42,7 @@ const Widgets3D = () => {
className="widget-image"
src={widget.img}
alt={widget.name}
// draggable={false}
draggable={false}
/>
</div>
))}

View File

@@ -16,7 +16,7 @@ import Analysis from "./analysis/Analysis";
import Simulations from "./simulation/Simulations";
import {
useSelectedActionSphere,
useselectedFloorItem,
useSelectedFloorItem,
} from "../../../store/store";
import GlobalProperties from "./properties/GlobalProperties";
import AsstePropertiies from "./properties/AssetProperties";
@@ -30,7 +30,7 @@ const SideBarRight: React.FC = () => {
const { toggleUI } = useToggleStore();
const { selectedActionSphere } = useSelectedActionSphere();
const { subModule, setSubModule } = useSubModuleStore();
const { selectedFloorItem } = useselectedFloorItem();
const { selectedFloorItem } = useSelectedFloorItem();
// Reset activeList whenever activeModule changes
useEffect(() => {
if (activeModule !== "simulation") setSubModule("properties");
@@ -101,7 +101,7 @@ const SideBarRight: React.FC = () => {
)}
{toggleUI &&
subModule === "zoneProperties" &&
activeModule === "builder" && (
(activeModule === "builder" || activeModule === "simulation") && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<ZoneProperties />
@@ -135,7 +135,7 @@ const SideBarRight: React.FC = () => {
selectedActionSphere.path.type === "StaticMachine" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<StaticMachineMechanics />
<StaticMachineMechanics />
</div>
</div>
)}
@@ -144,7 +144,7 @@ const SideBarRight: React.FC = () => {
selectedActionSphere.path.type === "ArmBot" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<ArmBotMechanics />
<ArmBotMechanics />
</div>
</div>
)}

View File

@@ -1,65 +1,121 @@
import React, { useRef, useMemo } from "react";
import React, { useRef, useMemo, useCallback, useState } from "react";
import { InfoIcon } from "../../../icons/ExportCommonIcons";
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
import { useEditingPoint, useEyeDropMode, usePreviewPosition, useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store";
import {
useSelectedActionSphere,
useSimulationStates,
useSocketStore
} from "../../../../store/store";
import * as Types from '../../../../types/world/worldTypes';
import PositionInput from "../customInput/PositionInputs";
import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt";
import LabeledButton from "../../../ui/inputs/LabledButton";
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
const ArmBotMechanics: React.FC = () => {
const { selectedActionSphere } = useSelectedActionSphere();
const { simulationStates, setSimulationStates } = useSimulationStates();
const { socket } = useSocketStore();
const [selectedTrigger, setSelectedTrigger] = useState<string | null>(null);
const propertiesContainerRef = useRef<HTMLDivElement>(null);
const { selectedPoint, connectedPointUuids } = useMemo(() => {
if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null, connectedPointUuids: [] };
// Get connected models for dropdowns
const connectedModels = useMemo(() => {
if (!selectedActionSphere?.points?.uuid) return [];
const vehiclePaths = simulationStates.filter(
}, [selectedActionSphere, simulationStates]);
// Get triggers only from connected models
const connectedTriggers = useMemo(() => {
}, [connectedModels, simulationStates]);
const { selectedPoint } = useMemo(() => {
if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null };
const armBotPaths = simulationStates.filter(
(path): path is Types.ArmBotEventsSchema => path.type === "ArmBot"
);
const points = vehiclePaths.find(
const points = armBotPaths.find(
(path) => path.points.uuid === selectedActionSphere.points.uuid
)?.points;
if (!points) return { selectedPoint: null, connectedPointUuids: [] };
const connectedUuids: string[] = [];
if (points.connections?.targets) {
points.connections.targets.forEach(target => {
connectedUuids.push(target.pointUUID);
});
}
return {
selectedPoint: points,
connectedPointUuids: connectedUuids
selectedPoint: points || null
};
}, [selectedActionSphere, simulationStates]);
const updateBackend = async (updatedPath: Types.ArmBotEventsSchema | undefined) => {
if (!updatedPath) return;
const email = localStorage.getItem("email");
const organization = email ? email.split("@")[1].split(".")[0] : "";
// if (!updatedPath) return;
// const email = localStorage.getItem("email");
// const organization = email ? email.split("@")[1].split(".")[0] : "";
// await setEventApi(
// organization,
// updatedPath.modeluuid,
// { type: "ArmBot", points: updatedPath.points }
// );
const data = {
organization: organization,
modeluuid: updatedPath.modeluuid,
eventData: { type: "ArmBot", points: updatedPath.points }
}
socket.emit('v2:model-asset:updateEventData', data);
// const data = {
// organization: organization,
// modeluuid: updatedPath.modeluuid,
// eventData: { type: "ArmBot", points: updatedPath.points }
// }
// socket.emit('v2:model-asset:updateEventData', data);
}
// const handleActionUpdate = useCallback((updatedAction: Partial<Types.ArmBotEventsSchema['points']['actions']>) => {
// if (!selectedActionSphere?.points?.uuid) return;
// const updatedPaths = simulationStates.map((path) => {
// return path;
// });
// const updatedPath = updatedPaths.find(
// (path): path is Types.ArmBotEventsSchema =>
// path.type === "ArmBot" &&
// path.points.uuid === selectedActionSphere.points.uuid
// );
// updateBackend(updatedPath);
// setSimulationStates(updatedPaths);
// }, [selectedActionSphere?.points?.uuid, simulationStates, setSimulationStates]);
// const handleSpeedChange = useCallback((speed: number) => {
// handleActionUpdate({ speed });
// }, [handleActionUpdate]);
// const handleProcessChange = useCallback((processes: Types.ArmBotEventsSchema['points']['actions']['processes']) => {
// handleActionUpdate({ processes });
// }, [handleActionUpdate]);
// const handleTriggerSelect = useCallback((displayName: string) => {
// const selected = connectedTriggers.find(t => t.displayName === displayName);
// setSelectedTrigger(selected?.uuid || null);
// }, [connectedTriggers]);
// const handleStartPointSelect = useCallback((pointUUID: string) => {
// if (!selectedTrigger || !selectedPoint) return;
// const updatedProcesses = selectedPoint.actions.processes?.map(process =>
// process.triggerId === selectedTrigger
// ? { ...process, startPoint: pointUUID }
// : process
// ) || [];
// handleProcessChange(updatedProcesses);
// }, [selectedTrigger, selectedPoint, handleProcessChange]);
// const handleEndPointSelect = useCallback((pointUUID: string) => {
// if (!selectedTrigger || !selectedPoint) return;
// const updatedProcesses = selectedPoint.actions.processes?.map(process =>
// process.triggerId === selectedTrigger
// ? { ...process, endPoint: pointUUID }
// : process
// ) || [];
// handleProcessChange(updatedProcesses);
// }, [selectedTrigger, selectedPoint, handleProcessChange]);
// const getCurrentProcess = useCallback(() => {
// if (!selectedTrigger || !selectedPoint) return null;
// return selectedPoint.actions.processes?.find(p => p.triggerId === selectedTrigger);
// }, [selectedTrigger, selectedPoint]);
return (
<div className="machine-mechanics-container" key={selectedPoint?.uuid}>
@@ -71,16 +127,50 @@ const ArmBotMechanics: React.FC = () => {
<div className="selected-properties-container" ref={propertiesContainerRef}>
<div className="properties-header">ArmBot Properties</div>
{selectedPoint && (
{/* {selectedPoint && (
<>
<InputWithDropDown
key={`speed-${selectedPoint.uuid}`}
label="ArmBot Speed"
value={selectedPoint.actions.speed.toString()}
onChange={(value) => handleSpeedChange(parseInt(value))}
/>
<LabledDropdown
key={`trigger-select-${selectedPoint.uuid}`}
label="Select Trigger"
defaultOption={connectedTriggers.find(t => t.uuid === selectedTrigger)?.displayName || ''}
onSelect={handleTriggerSelect}
options={connectedTriggers.map(trigger => trigger.displayName)}
/>
{selectedTrigger && (
<>
<LabledDropdown
key={`start-point-${selectedTrigger}`}
label="Start Point"
defaultOption={getCurrentProcess()?.startPoint || ''}
onSelect={handleStartPointSelect}
options={connectedModels.map((model, index) => `${model.modelName} [${index}]`)}
/>
<LabledDropdown
key={`end-point-${selectedTrigger}`}
label="End Point"
defaultOption={getCurrentProcess()?.endPoint || ''}
onSelect={handleEndPointSelect}
options={connectedModels.map((model, index) => `${model.modelName} [${index}]`)}
/>
</>
)}
</>
)}
)} */}
</div>
<div className="footer">
<InfoIcon />
Configure armbot properties.
Configure ArmBot properties and trigger-based processes.
</div>
</div>
</div>

View File

@@ -1,9 +1,9 @@
import React, { useRef, useMemo } from "react";
import React, { useRef, useMemo, useCallback } from "react";
import { InfoIcon } from "../../../icons/ExportCommonIcons";
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
import { useEditingPoint, useEyeDropMode, usePreviewPosition, useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store";
import { useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store";
import * as Types from '../../../../types/world/worldTypes';
import PositionInput from "../customInput/PositionInputs";
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt";
const StaticMachineMechanics: React.FC = () => {
@@ -16,11 +16,11 @@ const StaticMachineMechanics: React.FC = () => {
const { selectedPoint, connectedPointUuids } = useMemo(() => {
if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null, connectedPointUuids: [] };
const vehiclePaths = simulationStates.filter(
const staticMachinePaths = simulationStates.filter(
(path): path is Types.StaticMachineEventsSchema => path.type === "StaticMachine"
);
const points = vehiclePaths.find(
const points = staticMachinePaths.find(
(path) => path.points.uuid === selectedActionSphere.points.uuid
)?.points;
@@ -47,7 +47,7 @@ const StaticMachineMechanics: React.FC = () => {
// await setEventApi(
// organization,
// updatedPath.modeluuid,
// { type: "StaticMachine", points: updatedPath.points }
// { type: "Vehicle", points: updatedPath.points }
// );
const data = {
@@ -57,9 +57,77 @@ const StaticMachineMechanics: React.FC = () => {
}
socket.emit('v2:model-asset:updateEventData', data);
}
const handleActionUpdate = useCallback((updatedAction: Partial<Types.StaticMachineEventsSchema['points']['actions']>) => {
if (!selectedActionSphere?.points?.uuid) return;
const updatedPaths = simulationStates.map((path) => {
if (path.type === "StaticMachine" && path.points.uuid === selectedActionSphere.points.uuid) {
return {
...path,
points: {
...path.points,
actions: {
...path.points.actions,
...updatedAction
}
}
};
}
return path;
});
const updatedPath = updatedPaths.find(
(path): path is Types.StaticMachineEventsSchema =>
path.type === "StaticMachine" &&
path.points.uuid === selectedActionSphere.points.uuid
);
updateBackend(updatedPath);
setSimulationStates(updatedPaths);
}, [selectedActionSphere?.points?.uuid, simulationStates, setSimulationStates]);
const handleBufferChange = useCallback((buffer: number) => {
handleActionUpdate({ buffer });
}, [handleActionUpdate]);
const handleMaterialChange = useCallback((material: string) => {
handleActionUpdate({ material });
}, [handleActionUpdate]);
const handleTriggerChange = useCallback((updatedTrigger: Partial<Types.StaticMachineEventsSchema['points']['triggers']>) => {
if (!selectedActionSphere?.points?.uuid) return;
const updatedPaths = simulationStates.map((path) => {
if (path.type === "StaticMachine" && path.points.uuid === selectedActionSphere.points.uuid) {
return {
...path,
points: {
...path.points,
triggers: {
...path.points.triggers,
...updatedTrigger
}
}
};
}
return path;
});
const updatedPath = updatedPaths.find(
(path): path is Types.StaticMachineEventsSchema =>
path.type === "StaticMachine" &&
path.points.uuid === selectedActionSphere.points.uuid
);
updateBackend(updatedPath);
setSimulationStates(updatedPaths);
}, [selectedActionSphere?.points?.uuid, simulationStates, setSimulationStates]);
const handleTriggerTypeChange = useCallback((type: string) => {
handleTriggerChange({ type });
}, [handleTriggerChange]);
return (
<div className="machine-mechanics-container" key={selectedPoint?.uuid}>
@@ -67,20 +135,50 @@ const StaticMachineMechanics: React.FC = () => {
{selectedActionSphere?.path?.modelName || "Machine point not found"}
</div>
<div className="machine-mechanics-content-container">
<div className="selected-properties-container" ref={propertiesContainerRef}>
<div className="properties-header">Machine Properties</div>
{selectedPoint && (
<>
<InputWithDropDown
key={`buffer-${selectedPoint.uuid}`}
label="Buffer Time"
value={selectedPoint.actions.buffer.toString()}
onChange={(value) => handleBufferChange(parseInt(value))}
/>
<LabledDropdown
key={`material-${selectedPoint.uuid}`}
label="Material"
defaultOption={selectedPoint.actions.material}
onSelect={(value) => handleMaterialChange(value)}
options={["Inherit", "Crate", "Box"]}
/>
<LabledDropdown
key={`trigger-type-${selectedPoint.uuid}`}
label="Trigger Type"
defaultOption={selectedPoint.triggers.type}
onSelect={(value) => handleTriggerTypeChange(value)}
options={["OnComplete", "OnStart"]}
/>
{/* <LabeledButton
label="Reset"
value="Reset Settings"
onClick={() => {
// Implement reset functionality if needed
}}
/> */}
</>
)}
</div>
<div className="footer">
<InfoIcon />
Configure machine properties.
Configure machine interaction properties and triggers.
</div>
</div>
</div>

View File

@@ -5,6 +5,7 @@ import { useEditingPoint, useEyeDropMode, usePreviewPosition, useSelectedActionS
import * as Types from '../../../../types/world/worldTypes';
import PositionInput from "../customInput/PositionInputs";
import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt";
import LabeledButton from "../../../ui/inputs/LabledButton";
const VehicleMechanics: React.FC = () => {
const { selectedActionSphere } = useSelectedActionSphere();
@@ -126,6 +127,33 @@ const VehicleMechanics: React.FC = () => {
setSimulationStates(updatedPaths);
}, [selectedActionSphere?.points?.uuid, simulationStates, setSimulationStates]);
const ResetVehicleState = React.useCallback(() => {
if (!selectedActionSphere?.points?.uuid) return;
const updatedPaths = simulationStates.map((state) => {
if (state.type === "Vehicle" && state.points.uuid === selectedActionSphere.points.uuid) {
return {
...state,
points: {
...state.points,
actions: { ...state.points.actions, start: {}, end: {} }
}
};
}
return state;
});
const updatedPath = updatedPaths.find(
(path): path is Types.VehicleEventsSchema =>
path.type === "Vehicle" &&
path.points.uuid === selectedActionSphere.points.uuid
);
updateBackend(updatedPath);
setSimulationStates(updatedPaths);
}, [selectedActionSphere?.points?.uuid, simulationStates, setSimulationStates]);
const handleStartEyeDropClick = () => {
setEditingPoint('start');
setEyeDropMode(true);
@@ -193,6 +221,14 @@ const VehicleMechanics: React.FC = () => {
handleEyeDropClick={handleEndEyeDropClick}
/>
<LabeledButton
label="Reset"
value="Clear Points"
onClick={() => {
ResetVehicleState();
}}
/>
<InputWithDropDown
key={`hitcount-${selectedPoint.uuid}`}
label="Hit Count"

View File

@@ -4,7 +4,7 @@ import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
import { RemoveIcon } from "../../../icons/ExportCommonIcons";
import PositionInput from "../customInput/PositionInputs";
import RotationInput from "../customInput/RotationInput";
import { useselectedFloorItem } from "../../../../store/store";
import { useSelectedFloorItem } from "../../../../store/store";
import * as THREE from "three";
interface UserData {
@@ -16,7 +16,7 @@ interface UserData {
const AssetProperties: React.FC = () => {
const [userData, setUserData] = useState<UserData[]>([]); // State to track user data
const [nextId, setNextId] = useState(1); // Unique ID for new entries
const { selectedFloorItem } = useselectedFloorItem();
const { selectedFloorItem } = useSelectedFloorItem();
// Function to handle adding new user data
const handleAddUserData = () => {
const newUserData: UserData = {