Skip to content

Commit 4c7aaee

Browse files
authored
chore: cmd+k enhancements (#596)
1 parent 5f6c30a commit 4c7aaee

File tree

6 files changed

+238
-116
lines changed

6 files changed

+238
-116
lines changed

keep-ui/app/alerts/alerts.tsx

+10-9
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ export default function Alerts({
6363
const [groupedByAlerts, setGroupedByAlerts] = useState<{
6464
[key: string]: Alert[];
6565
}>({});
66-
const [alertNameSearchString, setAlertNameSearchString] = useState<string>(
67-
searchParams?.get("searchQuery") || ""
66+
const [alertSearchString, setAlertSearchString] = useState<string>(
67+
searchParams?.get("searchQuery") || searchParams?.get("fingerprint") || ""
6868
);
6969
const [selectedStatus, setSelectedStatus] = useState<string[]>([]);
7070
const [selectedAssignees, setSelectedAssignees] = useState<string[]>([]);
@@ -225,13 +225,14 @@ export default function Alerts({
225225

226226
function searchAlert(alert: Alert): boolean {
227227
return (
228-
alertNameSearchString === "" ||
229-
alertNameSearchString === undefined ||
230-
alertNameSearchString === null ||
231-
alert.name.toLowerCase().includes(alertNameSearchString.toLowerCase()) ||
228+
alertSearchString === "" ||
229+
alertSearchString === undefined ||
230+
alertSearchString === null ||
231+
alert.name.toLowerCase().includes(alertSearchString.toLowerCase()) ||
232232
alert.description
233233
?.toLowerCase()
234-
.includes(alertNameSearchString.toLowerCase()) ||
234+
.includes(alertSearchString.toLowerCase()) ||
235+
alert.fingerprint === alertSearchString ||
235236
false
236237
);
237238
}
@@ -302,9 +303,9 @@ export default function Alerts({
302303
className="max-w-[280px] ml-2.5"
303304
icon={MagnifyingGlassIcon}
304305
placeholder="Search Alert..."
305-
value={alertNameSearchString}
306+
value={alertSearchString}
306307
onChange={(e) => {
307-
setAlertNameSearchString(e.target.value);
308+
setAlertSearchString(e.target.value);
308309
router.push(
309310
pathname +
310311
"?" +

keep-ui/app/command-menu.tsx

+161-85
Original file line numberDiff line numberDiff line change
@@ -1,146 +1,222 @@
11
"use client";
22

3-
import { Command } from 'cmdk'
4-
import { useState, useEffect } from 'react';
5-
import { useRouter } from 'next/navigation';
6-
import { GitHubLogoIcon, FileTextIcon, TwitterLogoIcon } from '@radix-ui/react-icons'
7-
8-
import '../styles/linear.scss';
3+
import { Command } from "cmdk";
4+
import { useState, useEffect } from "react";
5+
import { useRouter } from "next/navigation";
6+
import {
7+
GitHubLogoIcon,
8+
FileTextIcon,
9+
TwitterLogoIcon,
10+
} from "@radix-ui/react-icons";
11+
import {
12+
GlobeAltIcon,
13+
UserGroupIcon,
14+
EnvelopeIcon,
15+
KeyIcon,
16+
BriefcaseIcon,
17+
} from "@heroicons/react/24/outline";
918

19+
import "../styles/linear.scss";
1020

1121
export function CMDK() {
12-
const [open, setOpen] = useState(false)
13-
const router = useRouter();
22+
const [open, setOpen] = useState(false);
23+
const router = useRouter();
1424

1525
// Toggle the menu when ⌘K is pressed
1626
useEffect(() => {
1727
const down = (e: any) => {
18-
if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
19-
e.preventDefault()
20-
setOpen((open) => !open)
28+
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
29+
e.preventDefault();
30+
setOpen((open) => !open);
2131
}
22-
}
32+
};
2333

24-
document.addEventListener('keydown', down)
25-
return () => document.removeEventListener('keydown', down)
26-
}, [])
34+
document.addEventListener("keydown", down);
35+
return () => document.removeEventListener("keydown", down);
36+
}, []);
2737
return (
2838
<div className="linear">
2939
<Command.Dialog open={open} onOpenChange={setOpen}>
3040
<div cmdk-linear-badge="">Keep Command Palette</div>
3141
<Command.Input autoFocus placeholder="Type a command or search..." />
3242
<Command.Group heading="Navigate">
33-
<Command.List>
43+
<Command.List>
3444
<Command.Empty>No results found.</Command.Empty>
3545
{navigationItems.map(({ icon, label, shortcut, navigate }) => {
36-
return (
37-
<Command.Item key={label} value={label} onSelect={() => {
38-
setOpen((open) => !open);
39-
router.push(navigate!);
40-
}}>
41-
{icon}
42-
{label}
43-
<div cmdk-linear-shortcuts="">
46+
return (
47+
<Command.Item
48+
key={label}
49+
value={label}
50+
onSelect={() => {
51+
setOpen((open) => !open);
52+
router.push(navigate!);
53+
}}
54+
>
55+
{icon}
56+
{label}
57+
<div cmdk-linear-shortcuts="">
4458
{shortcut.map((key) => {
45-
return <kbd key={key}>{key}</kbd>
59+
return <kbd key={key}>{key}</kbd>;
4660
})}
47-
</div>
61+
</div>
4862
</Command.Item>
49-
)
63+
);
5064
})}
51-
</Command.List>
65+
</Command.List>
5266
</Command.Group>
5367
<Command.Group heading="External sources">
54-
<Command.List>
68+
<Command.List>
5569
{externalItems.map(({ icon, label, shortcut, navigate }) => {
56-
return (
57-
<Command.Item key={label} value={label} onSelect={() => {
58-
setOpen((open) => !open);
59-
window.open(navigate, "_blank");
60-
}}>
61-
{icon}
62-
{label}
63-
<div cmdk-linear-shortcuts="">
70+
return (
71+
<Command.Item
72+
key={label}
73+
value={label}
74+
onSelect={() => {
75+
setOpen((open) => !open);
76+
window.open(navigate, "_blank");
77+
}}
78+
>
79+
{icon}
80+
{label}
81+
<div cmdk-linear-shortcuts="">
6482
{shortcut.map((key) => {
65-
return <kbd key={key}>{key}</kbd>
83+
return <kbd key={key}>{key}</kbd>;
6684
})}
67-
</div>
85+
</div>
6886
</Command.Item>
69-
)
87+
);
7088
})}
71-
</Command.List>
89+
</Command.List>
7290
</Command.Group>
7391
</Command.Dialog>
7492
</div>
75-
)
93+
);
7694
}
7795

7896
const navigationItems = [
97+
{
98+
icon: <ConnectIntegrationIcon />,
99+
label: "Go to the providers page",
100+
shortcut: ["p"],
101+
navigate: "/providers",
102+
},
79103
{
80104
icon: <GoToConsoleIcon />,
81-
label: 'Go to alert console',
82-
shortcut: ['G'],
83-
navigate: '/alerts'
105+
label: "Go to alert console",
106+
shortcut: ["g"],
107+
navigate: "/alerts",
84108
},
85109
{
86-
icon: <ConnectIntegrationIcon />,
87-
label: 'Go to the providers page',
88-
shortcut: ['P'],
89-
navigate: '/providers'
110+
icon: <BriefcaseIcon />,
111+
label: "Go to the workflows page",
112+
shortcut: ["wf"],
113+
navigate: "/workflows",
114+
},
115+
{
116+
icon: <UserGroupIcon />,
117+
label: "Go to users management",
118+
shortcut: ["u"],
119+
navigate: "/settings",
120+
},
121+
{
122+
icon: <GlobeAltIcon />,
123+
label: "Go to generic webhook",
124+
shortcut: ["w"],
125+
navigate: "/settings?selectedTab=webhook",
126+
},
127+
{
128+
icon: <EnvelopeIcon />,
129+
label: "Go to SMTP settings",
130+
shortcut: ["s"],
131+
navigate: "/settings?selectedTab=smtp",
90132
},
91133
{
92-
icon: <CreateAlertIcon />,
93-
label: 'Go to alert workflow builder',
94-
shortcut: ['D'],
95-
navigate: '/workflows/builder'
96-
}
97-
]
134+
icon: <KeyIcon />,
135+
label: "Go to API key",
136+
shortcut: ["a"],
137+
navigate: "/settings?selectedTab=api-key",
138+
},
139+
];
98140

99141
const externalItems = [
100-
{
101-
icon: <FileTextIcon />,
102-
label: 'Keep Docs',
103-
shortcut: ['⇧', 'D'],
104-
navigate: 'https://docs.keephq.dev'
105-
},
106-
{
107-
icon: <GitHubLogoIcon />,
108-
label: 'Keep Source code',
109-
shortcut: ['⇧', 'C'],
110-
navigate: 'https://github.com/keephq/keep'
111-
},
112-
{
113-
icon: <TwitterLogoIcon />,
114-
label: 'Keep Twitter',
115-
shortcut: ['⇧', 'T'],
116-
navigate: 'https://twitter.com/keepalerting'
117-
}
118-
]
142+
{
143+
icon: <FileTextIcon />,
144+
label: "Keep Docs",
145+
shortcut: ["⇧", "D"],
146+
navigate: "https://docs.keephq.dev",
147+
},
148+
{
149+
icon: <GitHubLogoIcon />,
150+
label: "Keep Source code",
151+
shortcut: ["⇧", "C"],
152+
navigate: "https://github.com/keephq/keep",
153+
},
154+
{
155+
icon: <TwitterLogoIcon />,
156+
label: "Keep Twitter",
157+
shortcut: ["⇧", "T"],
158+
navigate: "https://twitter.com/keepalerting",
159+
},
160+
];
119161

120162
function ConnectIntegrationIcon() {
121163
return (
122-
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 1920 1920" xmlns="http://www.w3.org/2000/svg">
123-
<path d="M1581.235 734.118c0 217.976-177.317 395.294-395.294 395.294H960.06c-217.977 0-395.294-177.318-395.294-395.294V564.706h1016.47v169.412Zm225.883-282.353h-338.824V0h-112.941v451.765H790.647V0H677.706v451.765H338.882v112.94h112.942v169.413c0 280.207 228.028 508.235 508.235 508.235h56.47v395.294c0 93.402-76.009 169.412-169.411 169.412-93.403 0-169.412-76.01-169.412-169.412 0-155.633-126.72-282.353-282.353-282.353S113 1482.014 113 1637.647V1920h112.941v-282.353c0-93.402 76.01-169.412 169.412-169.412s169.412 76.01 169.412 169.412c0 155.633 126.72 282.353 282.353 282.353 155.746 0 282.353-126.72 282.353-282.353v-395.294h56.47c280.207 0 508.235-228.028 508.235-508.235V564.706h112.942V451.765Z" fill-rule="evenodd"/>
124-
</svg>
125-
)
164+
<svg
165+
fill="#000000"
166+
width="800px"
167+
height="800px"
168+
viewBox="0 0 1920 1920"
169+
xmlns="http://www.w3.org/2000/svg"
170+
>
171+
<path
172+
d="M1581.235 734.118c0 217.976-177.317 395.294-395.294 395.294H960.06c-217.977 0-395.294-177.318-395.294-395.294V564.706h1016.47v169.412Zm225.883-282.353h-338.824V0h-112.941v451.765H790.647V0H677.706v451.765H338.882v112.94h112.942v169.413c0 280.207 228.028 508.235 508.235 508.235h56.47v395.294c0 93.402-76.009 169.412-169.411 169.412-93.403 0-169.412-76.01-169.412-169.412 0-155.633-126.72-282.353-282.353-282.353S113 1482.014 113 1637.647V1920h112.941v-282.353c0-93.402 76.01-169.412 169.412-169.412s169.412 76.01 169.412 169.412c0 155.633 126.72 282.353 282.353 282.353 155.746 0 282.353-126.72 282.353-282.353v-395.294h56.47c280.207 0 508.235-228.028 508.235-508.235V564.706h112.942V451.765Z"
173+
fill-rule="evenodd"
174+
/>
175+
</svg>
176+
);
126177
}
127178

128179
function GoToConsoleIcon() {
129180
return (
130-
<svg width="800px" height="800px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M5 6l2.702 2.5L5 11zm0 12l2.702-2.5L5 13zm5-9h10V8H10zm0 7h7v-1h-7zM1 3h22v18H1zm1 17h20V4H2z"/><path fill="none" d="M0 0h24v24H0z"/></svg>
131-
)
181+
<svg
182+
width="800px"
183+
height="800px"
184+
viewBox="0 0 24 24"
185+
xmlns="http://www.w3.org/2000/svg"
186+
>
187+
<path d="M5 6l2.702 2.5L5 11zm0 12l2.702-2.5L5 13zm5-9h10V8H10zm0 7h7v-1h-7zM1 3h22v18H1zm1 17h20V4H2z" />
188+
<path fill="none" d="M0 0h24v24H0z" />
189+
</svg>
190+
);
132191
}
133192

134193
function CreateAlertIcon() {
135194
return (
136-
<svg xmlns="http://www.w3.org/2000/svg" fill="#000000" width="800px" height="800px" viewBox="0 0 24 24"><path d="M10.01 21.01c0 1.1.89 1.99 1.99 1.99s1.99-.89 1.99-1.99h-3.98zm8.87-4.19V11c0-3.25-2.25-5.97-5.29-6.69v-.72C13.59 2.71 12.88 2 12 2s-1.59.71-1.59 1.59v.72C7.37 5.03 5.12 7.75 5.12 11v5.82L3 18.94V20h18v-1.06l-2.12-2.12zM16 13.01h-3v3h-2v-3H8V11h3V8h2v3h3v2.01z"/></svg>
137-
)
195+
<svg
196+
xmlns="http://www.w3.org/2000/svg"
197+
fill="#000000"
198+
width="800px"
199+
height="800px"
200+
viewBox="0 0 24 24"
201+
>
202+
<path d="M10.01 21.01c0 1.1.89 1.99 1.99 1.99s1.99-.89 1.99-1.99h-3.98zm8.87-4.19V11c0-3.25-2.25-5.97-5.29-6.69v-.72C13.59 2.71 12.88 2 12 2s-1.59.71-1.59 1.59v.72C7.37 5.03 5.12 7.75 5.12 11v5.82L3 18.94V20h18v-1.06l-2.12-2.12zM16 13.01h-3v3h-2v-3H8V11h3V8h2v3h3v2.01z" />
203+
</svg>
204+
);
138205
}
139206

140207
function GoToDashboardIcon() {
141208
return (
142-
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 1920 1920" xmlns="http://www.w3.org/2000/svg">
143-
<path d="M833.935 1063.327c28.913 170.315 64.038 348.198 83.464 384.79 27.557 51.84 92.047 71.944 144 44.387 51.84-27.558 71.717-92.273 44.16-144.113-19.426-36.593-146.937-165.46-271.624-285.064Zm-43.821-196.405c61.553 56.923 370.899 344.81 415.285 428.612 56.696 106.842 15.811 239.887-91.144 296.697-32.64 17.28-67.765 25.411-102.325 25.411-78.72 0-154.955-42.353-194.371-116.555-44.386-83.802-109.102-501.346-121.638-584.245-3.501-23.717 8.245-47.21 29.365-58.277 21.346-11.294 47.096-8.02 64.828 8.357ZM960.045 281.99c529.355 0 960 430.757 960 960 0 77.139-8.922 153.148-26.654 225.882l-10.39 43.144h-524.386v-112.942h434.258c9.487-50.71 14.231-103.115 14.231-156.084 0-467.125-380.047-847.06-847.059-847.06-467.125 0-847.059 379.935-847.059 847.06 0 52.97 4.744 105.374 14.118 156.084h487.454v112.942H36.977l-10.39-43.144C8.966 1395.137.044 1319.128.044 1241.99c0-529.243 430.645-960 960-960Zm542.547 390.686 79.85 79.85-112.716 112.715-79.85-79.85 112.716-112.715Zm-1085.184 0L530.123 785.39l-79.85 79.85L337.56 752.524l79.849-79.85Zm599.063-201.363v159.473H903.529V471.312h112.942Z" fill-rule="evenodd"/>
209+
<svg
210+
fill="#000000"
211+
width="800px"
212+
height="800px"
213+
viewBox="0 0 1920 1920"
214+
xmlns="http://www.w3.org/2000/svg"
215+
>
216+
<path
217+
d="M833.935 1063.327c28.913 170.315 64.038 348.198 83.464 384.79 27.557 51.84 92.047 71.944 144 44.387 51.84-27.558 71.717-92.273 44.16-144.113-19.426-36.593-146.937-165.46-271.624-285.064Zm-43.821-196.405c61.553 56.923 370.899 344.81 415.285 428.612 56.696 106.842 15.811 239.887-91.144 296.697-32.64 17.28-67.765 25.411-102.325 25.411-78.72 0-154.955-42.353-194.371-116.555-44.386-83.802-109.102-501.346-121.638-584.245-3.501-23.717 8.245-47.21 29.365-58.277 21.346-11.294 47.096-8.02 64.828 8.357ZM960.045 281.99c529.355 0 960 430.757 960 960 0 77.139-8.922 153.148-26.654 225.882l-10.39 43.144h-524.386v-112.942h434.258c9.487-50.71 14.231-103.115 14.231-156.084 0-467.125-380.047-847.06-847.059-847.06-467.125 0-847.059 379.935-847.059 847.06 0 52.97 4.744 105.374 14.118 156.084h487.454v112.942H36.977l-10.39-43.144C8.966 1395.137.044 1319.128.044 1241.99c0-529.243 430.645-960 960-960Zm542.547 390.686 79.85 79.85-112.716 112.715-79.85-79.85 112.716-112.715Zm-1085.184 0L530.123 785.39l-79.85 79.85L337.56 752.524l79.849-79.85Zm599.063-201.363v159.473H903.529V471.312h112.942Z"
218+
fill-rule="evenodd"
219+
/>
144220
</svg>
145-
)
221+
);
146222
}

keep-ui/app/navbar-inner.tsx

+13-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import { signOut } from "next-auth/react";
55
import { Fragment } from "react";
66
import {
77
Bars3Icon,
8+
BellAlertIcon,
9+
BriefcaseIcon,
810
DocumentTextIcon,
11+
EnvelopeOpenIcon,
12+
PuzzlePieceIcon,
913
XMarkIcon,
1014
} from "@heroicons/react/24/outline";
1115
import Link from "next/link";
@@ -17,9 +21,14 @@ import { User } from "next-auth";
1721
import { InternalConfig } from "types/internal-config";
1822

1923
const navigation = [
20-
{ name: "Providers", href: "/providers" },
21-
{ name: "Alerts", href: "/alerts" },
22-
{ name: "Workflows", href: "/workflows" },
24+
{ name: "Providers", href: "/providers", icon: PuzzlePieceIcon },
25+
{ name: "Alerts", href: "/alerts", icon: BellAlertIcon },
26+
{ name: "Workflows", href: "/workflows", icon: BriefcaseIcon },
27+
// {
28+
// name: "Notifications Hub",
29+
// href: "/notifications-hub",
30+
// icon: EnvelopeOpenIcon,
31+
// },
2332
];
2433

2534
function classNames(...classes: string[]) {
@@ -108,6 +117,7 @@ export default function NavbarInner({ user }: { user?: User }) {
108117
)}
109118
aria-current={pathname === item.href ? "page" : undefined}
110119
>
120+
<Icon icon={item.icon} color="gray" />
111121
{item.name}
112122
</Link>
113123
))}

0 commit comments

Comments
 (0)