diff --git a/apps/dokploy/hooks/use-keyboard-nav.tsx b/apps/dokploy/hooks/use-keyboard-nav.tsx new file mode 100644 index 000000000..318f06914 --- /dev/null +++ b/apps/dokploy/hooks/use-keyboard-nav.tsx @@ -0,0 +1,77 @@ +"use client"; + +import { usePathname, useRouter, useSearchParams } from "next/navigation"; +import { useCallback, useEffect, useState } from "react"; + +const SHORTCUTS = { + g: "general", + e: "environment", + u: "domains", + p: "preview-deployments", + s: "schedules", + v: "volume-backups", + d: "deployments", + l: "logs", + m: "monitoring", + a: "advanced", +}; + +/** + * Use this to register keyboard shortcuts for the application page. Each + * shortcut must be prefixed with `g` (like GitHub). + * + * - `g g` "General", + * - `g e` "Environment", + * - `g u` "Domains", + * - `g p` "Preview Deployments", + * - `g s` "Schedules", + * - `g v` "Volume Backups", + * - `g d` "Deployments", + * - `g l` "Logs", + * - `g m` "Monitoring", + * - `g a` "Advanced" + */ +export function UseKeyboardNavForApplications() { + const [isModPressed, setModPressed] = useState(false); + const [timer, setTimer] = useState(null); + + const sp = useSearchParams(); + const router = useRouter(); + const pathname = usePathname(); + + const updateSearchParam = useCallback( + (name: string, value: string) => { + const params = new URLSearchParams(sp.toString()); + params.set(name, value); + + return params.toString(); + }, + [sp], + ); + + useEffect(() => { + const handleKeyDown = ({ key }: KeyboardEvent) => { + if (isModPressed) { + if (timer) clearTimeout(timer); + setModPressed(false); + + if (key in SHORTCUTS) { + const tab = SHORTCUTS[key]; + router.push( + `${pathname}?${updateSearchParam("tab", tab.toLowerCase())}`, + ); + } + } else { + if (key === "g") { + setModPressed(true); + setTimer(setTimeout(() => setModPressed(false), 5000)); + } + } + }; + + window.addEventListener("keydown", handleKeyDown); + return () => window.removeEventListener("keydown", handleKeyDown); + }, [isModPressed, timer, updateSearchParam, router, pathname]); + + return null; +} diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx index 209f6f65f..104b1ff7b 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx @@ -51,6 +51,7 @@ import { TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; +import { UseKeyboardNavForApplications } from "@/hooks/use-keyboard-nav"; import { appRouter } from "@/server/api/root"; import { api } from "@/utils/api"; @@ -91,6 +92,7 @@ const Service = ( return (
+