add drawer
This commit is contained in:
+1
-1
@@ -10,7 +10,7 @@ import { useDeviceStore } from "@core/stores/deviceStore.js";
|
|||||||
import { CommandPalette } from "./components/CommandPalette/Index.js";
|
import { CommandPalette } from "./components/CommandPalette/Index.js";
|
||||||
import { DeviceSelector } from "./components/DeviceSelector.js";
|
import { DeviceSelector } from "./components/DeviceSelector.js";
|
||||||
import { DialogManager } from "./components/Dialog/DialogManager.js";
|
import { DialogManager } from "./components/Dialog/DialogManager.js";
|
||||||
import { Drawer } from "./components/Drawer.js";
|
import { Drawer } from "./components/Drawer/index.js";
|
||||||
import { NewDevice } from "./components/NewDevice.js";
|
import { NewDevice } from "./components/NewDevice.js";
|
||||||
import { PageNav } from "./components/PageNav.js";
|
import { PageNav } from "./components/PageNav.js";
|
||||||
import { Sidebar } from "./components/Sidebar.js";
|
import { Sidebar } from "./components/Sidebar.js";
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
import type React from "react";
|
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
import { useDevice } from "@app/core/providers/useDevice.js";
|
|
||||||
import { ChevronDownIcon, ChevronUpIcon } from "@heroicons/react/24/outline";
|
|
||||||
|
|
||||||
export const Drawer = (): JSX.Element => {
|
|
||||||
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
||||||
|
|
||||||
const tabs = [{ title: "Notifications" }, { title: "Debug" }];
|
|
||||||
|
|
||||||
const { config, moduleConfig, hardware, nodes, waypoints, connection } =
|
|
||||||
useDevice();
|
|
||||||
|
|
||||||
const [serialLogs, setSerialLogs] = useState<string>("");
|
|
||||||
|
|
||||||
connection?.onDeviceDebugLog.subscribe((packet) => {
|
|
||||||
setSerialLogs(serialLogs + new TextDecoder().decode(packet));
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={`shadow-md ${drawerOpen ? "h-40" : "h-8"}`}>
|
|
||||||
<div className="flex h-8 bg-slate-50">
|
|
||||||
<div
|
|
||||||
onClick={() => {
|
|
||||||
setDrawerOpen(!drawerOpen);
|
|
||||||
}}
|
|
||||||
className="ml-auto flex px-2 hover:cursor-pointer hover:bg-slate-100"
|
|
||||||
>
|
|
||||||
<div className="m-auto">
|
|
||||||
{drawerOpen ? (
|
|
||||||
<ChevronDownIcon className="h-4 text-gray-700" />
|
|
||||||
) : (
|
|
||||||
<ChevronUpIcon className="h-4 text-gray-700" />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className={`${drawerOpen ? "flex" : "hidden"}`}>
|
|
||||||
<div>
|
|
||||||
{serialLogs.split("\n").map((line, index) => (
|
|
||||||
<div key={index} className="text-sm">
|
|
||||||
{line}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
import "chartjs-adapter-date-fns";
|
||||||
|
|
||||||
|
import type React from "react";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Chart as ChartJS,
|
||||||
|
Filler,
|
||||||
|
Legend,
|
||||||
|
LinearScale,
|
||||||
|
LineElement,
|
||||||
|
PointElement,
|
||||||
|
TimeSeriesScale,
|
||||||
|
Tooltip
|
||||||
|
} from "chart.js";
|
||||||
|
import { Line } from "react-chartjs-2";
|
||||||
|
|
||||||
|
import { useDevice } from "@app/core/providers/useDevice.js";
|
||||||
|
|
||||||
|
export const Metrics = (): JSX.Element => {
|
||||||
|
const { nodes, hardware } = useDevice();
|
||||||
|
|
||||||
|
const myNode = nodes.find((n) => n.data.num === hardware.myNodeNum);
|
||||||
|
|
||||||
|
ChartJS.register(
|
||||||
|
LinearScale,
|
||||||
|
PointElement,
|
||||||
|
LineElement,
|
||||||
|
Tooltip,
|
||||||
|
Filler,
|
||||||
|
Legend,
|
||||||
|
TimeSeriesScale
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex h-full w-full flex-grow">
|
||||||
|
{/* {myNode?.deviceMetrics.map((metric) => (
|
||||||
|
<p>{metric.airUtilTx}</p>
|
||||||
|
))} */}
|
||||||
|
<Line
|
||||||
|
className="h-full w-full flex-grow"
|
||||||
|
options={{
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
type: "timeseries"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
data={{
|
||||||
|
labels: [],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
fill: true,
|
||||||
|
label: "airUtilTx",
|
||||||
|
data: myNode?.deviceMetrics.map((metric) => {
|
||||||
|
return {
|
||||||
|
x: metric.timestamp,
|
||||||
|
y: metric.airUtilTx
|
||||||
|
};
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fill: true,
|
||||||
|
label: "channelUtilization",
|
||||||
|
data: myNode?.deviceMetrics.map((metric) => {
|
||||||
|
return {
|
||||||
|
x: metric.timestamp,
|
||||||
|
y: metric.channelUtilization
|
||||||
|
};
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fill: true,
|
||||||
|
label: "batteryLevel",
|
||||||
|
data: myNode?.deviceMetrics.map((metric) => {
|
||||||
|
return {
|
||||||
|
x: metric.timestamp,
|
||||||
|
y: metric.batteryLevel
|
||||||
|
};
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fill: true,
|
||||||
|
label: "voltage",
|
||||||
|
data: myNode?.deviceMetrics.map((metric) => {
|
||||||
|
return {
|
||||||
|
x: metric.timestamp,
|
||||||
|
y: metric.voltage
|
||||||
|
};
|
||||||
|
})
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export const Notifications = (): JSX.Element => {
|
||||||
|
return <div></div>;
|
||||||
|
};
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
import type React from "react";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
import { Tab } from "@headlessui/react";
|
||||||
|
import { ChevronDownIcon, ChevronUpIcon } from "@heroicons/react/24/outline";
|
||||||
|
|
||||||
|
import type { TabType } from "../layout/page/TabbedContent.js";
|
||||||
|
import { Metrics } from "./Metrics.js";
|
||||||
|
import { Notifications } from "./Notifications.js";
|
||||||
|
|
||||||
|
export const Drawer = (): JSX.Element => {
|
||||||
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
||||||
|
|
||||||
|
const tabs: TabType[] = [
|
||||||
|
{ name: "Notifications", element: Notifications },
|
||||||
|
{ name: "Metrics", element: Metrics }
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<Tab.Group>
|
||||||
|
<Tab.List className="flex">
|
||||||
|
{tabs.map((tab, index) => (
|
||||||
|
<Tab key={index}>
|
||||||
|
{({ selected }) => (
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
setDrawerOpen(true);
|
||||||
|
}}
|
||||||
|
className={`flex h-full cursor-pointer px-1 first:pl-2 last:pr-2 hover:bg-orange-300 ${
|
||||||
|
selected ? "bg-orange-500 text-white" : "bg-white text-black"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<span className="m-auto select-none">{tab.name}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Tab>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<div className="ml-auto flex h-8">
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
setDrawerOpen(!drawerOpen);
|
||||||
|
}}
|
||||||
|
className="flex cursor-pointer px-2"
|
||||||
|
>
|
||||||
|
<div className="m-auto">
|
||||||
|
{drawerOpen ? (
|
||||||
|
<ChevronDownIcon className="h-4 text-gray-700" />
|
||||||
|
) : (
|
||||||
|
<ChevronUpIcon className="h-4 text-gray-700" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Tab.List>
|
||||||
|
|
||||||
|
<Tab.Panels className={`${drawerOpen ? "flex" : "hidden"}`}>
|
||||||
|
{tabs.map((tab, index) => (
|
||||||
|
<Tab.Panel key={index} className="flex h-40 flex-grow">
|
||||||
|
{tab.element}
|
||||||
|
</Tab.Panel>
|
||||||
|
))}
|
||||||
|
</Tab.Panels>
|
||||||
|
</Tab.Group>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -23,9 +23,7 @@ export const PeersWidget = ({ peers }: PeersWidgetProps): JSX.Element => {
|
|||||||
<UserGroupIcon className="h-6 text-white" />
|
<UserGroupIcon className="h-6 text-white" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="truncate text-sm font-medium text-gray-500">
|
<p className="truncate text-sm font-medium text-gray-500">Peers</p>
|
||||||
Connected Peers
|
|
||||||
</p>
|
|
||||||
<div className="flex gap-1">
|
<div className="flex gap-1">
|
||||||
{peers.length > 0 ? (
|
{peers.length > 0 ? (
|
||||||
<p className="text-lg font-semibold text-gray-900">
|
<p className="text-lg font-semibold text-gray-900">
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ export const subscribeAll = (
|
|||||||
});
|
});
|
||||||
|
|
||||||
connection.onTelemetryPacket.subscribe((telemetryPacket) => {
|
connection.onTelemetryPacket.subscribe((telemetryPacket) => {
|
||||||
console.log(telemetryPacket.data.variant);
|
|
||||||
|
|
||||||
device.setMetrics(telemetryPacket);
|
device.setMetrics(telemetryPacket);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user