mirror of
https://github.com/fankes/beszel.git
synced 2025-10-19 17:59:28 +08:00
feat: add keyboard navigation for systems
This commit is contained in:
@@ -22,7 +22,7 @@ import {
|
|||||||
import { useEffect } from "react"
|
import { useEffect } from "react"
|
||||||
import { useStore } from "@nanostores/react"
|
import { useStore } from "@nanostores/react"
|
||||||
import { $systems } from "@/lib/stores"
|
import { $systems } from "@/lib/stores"
|
||||||
import { getHostDisplayValue, isAdmin } from "@/lib/utils"
|
import { getHostDisplayValue, isAdmin, listen } from "@/lib/utils"
|
||||||
import { $router, basePath, navigate } from "./router"
|
import { $router, basePath, navigate } from "./router"
|
||||||
import { Trans, t } from "@lingui/macro"
|
import { Trans, t } from "@lingui/macro"
|
||||||
import { getPagePath } from "@nanostores/router"
|
import { getPagePath } from "@nanostores/router"
|
||||||
@@ -37,9 +37,7 @@ export default function CommandPalette({ open, setOpen }: { open: boolean; setOp
|
|||||||
setOpen(!open)
|
setOpen(!open)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return listen(document, "keydown", down)
|
||||||
document.addEventListener("keydown", down)
|
|
||||||
return () => document.removeEventListener("keydown", down)
|
|
||||||
}, [open, setOpen])
|
}, [open, setOpen])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@@ -12,6 +12,7 @@ import {
|
|||||||
getHostDisplayValue,
|
getHostDisplayValue,
|
||||||
getPbTimestamp,
|
getPbTimestamp,
|
||||||
getSizeAndUnit,
|
getSizeAndUnit,
|
||||||
|
listen,
|
||||||
toFixedFloat,
|
toFixedFloat,
|
||||||
useLocalStorage,
|
useLocalStorage,
|
||||||
} from "@/lib/utils"
|
} from "@/lib/utils"
|
||||||
@@ -25,6 +26,8 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from ".
|
|||||||
import { timeTicks } from "d3-time"
|
import { timeTicks } from "d3-time"
|
||||||
import { Plural, Trans, t } from "@lingui/macro"
|
import { Plural, Trans, t } from "@lingui/macro"
|
||||||
import { useLingui } from "@lingui/react"
|
import { useLingui } from "@lingui/react"
|
||||||
|
import { $router, navigate } from "../router"
|
||||||
|
import { getPagePath } from "@nanostores/router"
|
||||||
|
|
||||||
const AreaChartDefault = lazy(() => import("../charts/area-chart"))
|
const AreaChartDefault = lazy(() => import("../charts/area-chart"))
|
||||||
const ContainerChart = lazy(() => import("../charts/container-chart"))
|
const ContainerChart = lazy(() => import("../charts/container-chart"))
|
||||||
@@ -288,6 +291,30 @@ export default function SystemDetail({ name }: { name: string }) {
|
|||||||
const distanceToBottom = wrapperRect.bottom - chartRect.bottom
|
const distanceToBottom = wrapperRect.bottom - chartRect.bottom
|
||||||
setBottomSpacing(tooltipHeight - distanceToBottom)
|
setBottomSpacing(tooltipHeight - distanceToBottom)
|
||||||
}, [netCardRef, containerData])
|
}, [netCardRef, containerData])
|
||||||
|
|
||||||
|
// keyboard navigation between systems
|
||||||
|
useEffect(() => {
|
||||||
|
const handleKeyUp = (e: KeyboardEvent) => {
|
||||||
|
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const currentIndex = systems.findIndex(s => s.name === name)
|
||||||
|
if (currentIndex === -1 || systems.length <= 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch (e.key) {
|
||||||
|
case "ArrowLeft":
|
||||||
|
case "h":
|
||||||
|
const prevIndex = (currentIndex - 1 + systems.length) % systems.length
|
||||||
|
return navigate(getPagePath($router, "system", { name: systems[prevIndex].name }))
|
||||||
|
case "ArrowRight":
|
||||||
|
case "l":
|
||||||
|
const nextIndex = (currentIndex + 1) % systems.length
|
||||||
|
return navigate(getPagePath($router, "system", { name: systems[nextIndex].name }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return listen(document, "keyup", handleKeyUp)
|
||||||
|
}, [name])
|
||||||
|
|
||||||
if (!system.id) {
|
if (!system.id) {
|
||||||
return null
|
return null
|
||||||
|
@@ -15,7 +15,16 @@ import { prependBasePath } from "@/components/router"
|
|||||||
export function cn(...inputs: ClassValue[]) {
|
export function cn(...inputs: ClassValue[]) {
|
||||||
return twMerge(clsx(inputs))
|
return twMerge(clsx(inputs))
|
||||||
}
|
}
|
||||||
// export const cn = clsx
|
|
||||||
|
/** Adds event listener to node and returns function that removes the listener */
|
||||||
|
export function listen<T extends Event = Event>(
|
||||||
|
node: Node,
|
||||||
|
event: string,
|
||||||
|
handler: (event: T) => void
|
||||||
|
) {
|
||||||
|
node.addEventListener(event, handler as EventListener)
|
||||||
|
return () => node.removeEventListener(event, handler as EventListener)
|
||||||
|
}
|
||||||
|
|
||||||
export async function copyToClipboard(content: string) {
|
export async function copyToClipboard(content: string) {
|
||||||
const duration = 1500
|
const duration = 1500
|
||||||
|
Reference in New Issue
Block a user