Skip to content

Commit bfcbd09

Browse files
committed
WIP adding a new Ask AI button to the side menu
1 parent c71509b commit bfcbd09

2 files changed

Lines changed: 50 additions & 12 deletions

File tree

apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
ChatBubbleLeftEllipsisIcon,
66
EnvelopeIcon,
77
LightBulbIcon,
8+
QuestionMarkCircleIcon,
89
SignalIcon,
910
StarIcon,
1011
} from "@heroicons/react/20/solid";
@@ -28,9 +29,12 @@ export function HelpAndFeedback() {
2829

2930
return (
3031
<Popover onOpenChange={(open) => setHelpMenuOpen(open)}>
31-
<PopoverSideMenuTrigger isOpen={isHelpMenuOpen} shortcut={{ key: "h" }}>
32+
<PopoverSideMenuTrigger
33+
isOpen={isHelpMenuOpen}
34+
shortcut={{ key: "h", enabledOnInputElements: false }}
35+
>
3236
<div className="flex items-center gap-1.5">
33-
<ChatBubbleLeftEllipsisIcon className="size-4 text-success" />
37+
<QuestionMarkCircleIcon className="size-4 text-success" />
3438
Help & Feedback
3539
</div>
3640
</PopoverSideMenuTrigger>

apps/webapp/app/components/navigation/SideMenu.tsx

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {
33
ArrowRightOnRectangleIcon,
44
BeakerIcon,
55
BellAlertIcon,
6-
BookOpenIcon,
76
ChartBarIcon,
87
ChevronRightIcon,
98
ClockIcon,
@@ -21,6 +20,7 @@ import {
2120
import { useNavigation } from "@remix-run/react";
2221
import { useEffect, useRef, useState, type ReactNode } from "react";
2322
import simplur from "simplur";
23+
import { AISparkleIcon } from "~/assets/icons/AISparkleIcon";
2424
import { ConnectedIcon, DisconnectedIcon } from "~/assets/icons/ConnectionIcons";
2525
import { RunsIcon } from "~/assets/icons/RunsIcon";
2626
import { TaskIcon } from "~/assets/icons/TaskIcon";
@@ -59,16 +59,11 @@ import {
5959
import connectedImage from "../../assets/images/cli-connected.png";
6060
import disconnectedImage from "../../assets/images/cli-disconnected.png";
6161
import { FreePlanUsage } from "../billing/FreePlanUsage";
62+
import { InlineCode } from "../code/InlineCode";
6263
import { useDevPresence } from "../DevPresence";
6364
import { ImpersonationBanner } from "../ImpersonationBanner";
6465
import { Button, ButtonContent, LinkButton } from "../primitives/Buttons";
65-
import {
66-
Dialog,
67-
DialogContent,
68-
DialogFooter,
69-
DialogHeader,
70-
DialogTrigger,
71-
} from "../primitives/Dialog";
66+
import { Dialog, DialogContent, DialogHeader, DialogTrigger } from "../primitives/Dialog";
7267
import { Paragraph } from "../primitives/Paragraph";
7368
import {
7469
Popover,
@@ -86,7 +81,8 @@ import { HelpAndFeedback } from "./HelpAndFeedbackPopover";
8681
import { SideMenuHeader } from "./SideMenuHeader";
8782
import { SideMenuItem } from "./SideMenuItem";
8883
import { SideMenuSection } from "./SideMenuSection";
89-
import { InlineCode } from "../code/InlineCode";
84+
import { useShortcutKeys } from "~/hooks/useShortcutKeys";
85+
import { ShortcutKey } from "../primitives/ShortcutKey";
9086

9187
type SideMenuUser = Pick<User, "email" | "admin"> & { isImpersonating: boolean };
9288
export type SideMenuProject = Pick<
@@ -116,6 +112,17 @@ export function SideMenu({
116112
const [showHeaderDivider, setShowHeaderDivider] = useState(false);
117113
const currentPlan = useCurrentPlan();
118114
const isFreeUser = currentPlan?.v3Subscription?.isPaying === false;
115+
const buttonRef = useRef<HTMLButtonElement>(null);
116+
117+
useShortcutKeys({
118+
shortcut: { key: "a", modifiers: ["mod", "shift"] },
119+
action: (e) => {
120+
e.preventDefault();
121+
if (buttonRef.current) {
122+
buttonRef.current.click();
123+
}
124+
},
125+
});
119126

120127
useEffect(() => {
121128
const handleScroll = () => {
@@ -251,7 +258,34 @@ export function SideMenu({
251258
</div>
252259
</div>
253260
<div className="flex flex-col gap-1 border-t border-grid-bright p-1">
254-
<HelpAndFeedback />
261+
<div className="flex w-full items-center justify-between">
262+
<HelpAndFeedback />
263+
<TooltipProvider disableHoverableContent>
264+
<Tooltip>
265+
<TooltipTrigger asChild>
266+
<div>
267+
<Button
268+
ref={buttonRef}
269+
variant="small-menu-item"
270+
data-action="ask-ai"
271+
onClick={() => {
272+
// TODO: sort action
273+
}}
274+
>
275+
<AISparkleIcon className="size-5" />
276+
</Button>
277+
</div>
278+
</TooltipTrigger>
279+
<TooltipContent
280+
side="top"
281+
className="flex items-center gap-1 py-1.5 pl-2.5 pr-2 text-xs"
282+
>
283+
Ask AI
284+
<ShortcutKey shortcut={{ key: "/", modifiers: ["mod"] }} variant="small" />
285+
</TooltipContent>
286+
</Tooltip>
287+
</TooltipProvider>
288+
</div>
255289
{isFreeUser && (
256290
<FreePlanUsage
257291
to={v3BillingPath(organization)}

0 commit comments

Comments
 (0)