Browse Source

add drawer

pull/66/head
Sacha Weatherstone 4 years ago
parent
commit
8fc705956b
No known key found for this signature in database GPG Key ID: 7AB2D7E206124B31
  1. 2
      src/App.tsx
  2. 50
      src/components/Drawer.tsx
  3. 98
      src/components/Drawer/Metrics.tsx
  4. 3
      src/components/Drawer/Notifications.tsx
  5. 65
      src/components/Drawer/index.tsx
  6. 4
      src/components/Widgets/PeersWidget.tsx
  7. 2
      src/core/subscriptions.ts

2
src/App.tsx

@ -10,7 +10,7 @@ import { useDeviceStore } from "@core/stores/deviceStore.js";
import { CommandPalette } from "./components/CommandPalette/Index.js";
import { DeviceSelector } from "./components/DeviceSelector.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 { PageNav } from "./components/PageNav.js";
import { Sidebar } from "./components/Sidebar.js";

50
src/components/Drawer.tsx

@ -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>
);
};

98
src/components/Drawer/Metrics.tsx

@ -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>
);
};

3
src/components/Drawer/Notifications.tsx

@ -0,0 +1,3 @@
export const Notifications = (): JSX.Element => {
return <div></div>;
};

65
src/components/Drawer/index.tsx

@ -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>
);
};

4
src/components/Widgets/PeersWidget.tsx

@ -23,9 +23,7 @@ export const PeersWidget = ({ peers }: PeersWidgetProps): JSX.Element => {
<UserGroupIcon className="h-6 text-white" />
</div>
<div>
<p className="truncate text-sm font-medium text-gray-500">
Connected Peers
</p>
<p className="truncate text-sm font-medium text-gray-500">Peers</p>
<div className="flex gap-1">
{peers.length > 0 ? (
<p className="text-lg font-semibold text-gray-900">

2
src/core/subscriptions.ts

@ -21,8 +21,6 @@ export const subscribeAll = (
});
connection.onTelemetryPacket.subscribe((telemetryPacket) => {
console.log(telemetryPacket.data.variant);
device.setMetrics(telemetryPacket);
});

Loading…
Cancel
Save