Skip to content

Commit 0c765dd

Browse files
committed
feat: add keyboard shortcuts and command menu
Adds keyboard shortcuts for logout (vim styled `:q` to logout), command menu (`CTRL / CMD + K`), search on active page (vim styled `/`, if there is a valid search input) and switching servers (`CTRL / CMD + {{N}}` and vim styled `:{{N}}` to switch servers, where {{N}} is the server index). Also adds a command menu for quick navigation to user profiles, searching users, and executing commands like rebuilding packages or viewing build logs for a specific package. Revamped existing shortcut listeners to use a generic hook, instead of specific listeners for logout and find shortcuts. Fix sidebar item icons not visible when the sidebar is collapsed. Signed-off-by: SoulHarsh007 <[email protected]>
1 parent e9212e6 commit 0c765dd

17 files changed

+598
-151
lines changed

CachyOS Builder Dashboard.code-workspace

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@
88
"cSpell.words": [
99
"Cachy",
1010
"cachyos",
11+
"cmdk",
1112
"headlessui",
1213
"marsidev",
14+
"nums",
1315
"pkgbase",
1416
"pkgname",
1517
"QPKG",
1618
"remixicon",
1719
"rxdb",
1820
"scrollback",
1921
"sonner",
22+
"tabler",
2023
"toastify",
2124
"Upsert",
2225
"vercel",

src/app/dashboard/audit-logs/page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ export default function AuditLogsPage() {
182182
{
183183
icon: Search,
184184
id: 'description',
185+
isPrimary: true,
185186
placeholder: 'Search description...',
186187
},
187188
],

src/app/dashboard/layout.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {AppSidebar} from '@/components/app-sidebar';
2+
import {CommandMenu} from '@/components/command-menu';
23
import {HeaderBreadcrumbs} from '@/components/header-breadcrumbs';
34
import {Separator} from '@/components/ui/separator';
45
import {
@@ -26,7 +27,10 @@ export default function RootLayout({
2627
<HeaderBreadcrumbs />
2728
</div>
2829
</header>
29-
<div className="flex flex-1 flex-col gap-4 p-4 pt-0">{children}</div>
30+
<div className="flex flex-1 flex-col gap-4 p-4 pt-0">
31+
<CommandMenu />
32+
{children}
33+
</div>
3034
</SidebarInset>
3135
</SidebarProvider>
3236
);

src/app/dashboard/package-list/page.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@
33
import {ColumnDef} from '@tanstack/react-table';
44
import {Ellipsis, Logs, RotateCcw, Search, SquareTerminal} from 'lucide-react';
55
import Link from 'next/link';
6-
import {Fragment, useCallback, useEffect, useMemo, useState} from 'react';
6+
import {
7+
Fragment,
8+
useCallback,
9+
useEffect,
10+
useMemo,
11+
useRef,
12+
useState,
13+
} from 'react';
714
import {toast} from 'sonner';
815
import {useDebounce} from 'use-debounce';
916

@@ -27,6 +34,7 @@ import {
2734
} from '@/components/ui/dropdown-menu';
2835
import {Input} from '@/components/ui/input';
2936
import {useSidebar} from '@/components/ui/sidebar';
37+
import {useGenericShortcutListener} from '@/hooks/use-keyboard-shortcut-listener';
3038
import {
3139
BasePackageWithIDList,
3240
ListPackageResponse,
@@ -64,6 +72,14 @@ export default function PackageListPage() {
6472
}
6573
setShowRebuildModal(state);
6674
}, []);
75+
const primarySearchFilterInputRef = useRef<HTMLInputElement>(null);
76+
const primarySearchFilterShortcutCallback = useCallback(() => {
77+
if (primarySearchFilterInputRef.current) {
78+
primarySearchFilterInputRef.current.focus();
79+
}
80+
}, []);
81+
82+
useGenericShortcutListener('/', primarySearchFilterShortcutCallback, true);
6783

6884
const columns: ColumnDef<Package>[] = useMemo(
6985
() => [
@@ -427,6 +443,7 @@ export default function PackageListPage() {
427443
id="package-search"
428444
onChange={e => setSearchQuery(e.target.value)}
429445
placeholder="Search packages..."
446+
ref={primarySearchFilterInputRef}
430447
type="text"
431448
value={searchQuery}
432449
/>

src/app/dashboard/rebuild-queue/page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ export default function RebuildQueuePackageListPage() {
361361
{
362362
icon: Search,
363363
id: 'pkgbase',
364+
isPrimary: true,
364365
placeholder: 'Search packages...',
365366
},
366367
],

src/components/app-sidebar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import {Activity, Package, PieChart, Repeat2} from 'lucide-react';
3+
import {Activity, Logs, Package, PieChart, Repeat2} from 'lucide-react';
44
import * as React from 'react';
55
import {toast} from 'sonner';
66

@@ -31,7 +31,7 @@ const items = [
3131
url: '/dashboard/rebuild-queue',
3232
},
3333
{
34-
icon: Activity,
34+
icon: Logs,
3535
name: 'Audit Logs',
3636
url: '/dashboard/audit-logs',
3737
},

0 commit comments

Comments
 (0)