diff --git a/apps/webapp/app/assets/icons/KeyboardDownIcon.tsx b/apps/webapp/app/assets/icons/KeyboardDownIcon.tsx new file mode 100644 index 0000000000..1ef015d900 --- /dev/null +++ b/apps/webapp/app/assets/icons/KeyboardDownIcon.tsx @@ -0,0 +1,17 @@ +export function KeyboardDownIcon({ className }: { className?: string }) { + return ( + + + + ); +} diff --git a/apps/webapp/app/assets/icons/KeyboardLeftIcon.tsx b/apps/webapp/app/assets/icons/KeyboardLeftIcon.tsx new file mode 100644 index 0000000000..6b6999e683 --- /dev/null +++ b/apps/webapp/app/assets/icons/KeyboardLeftIcon.tsx @@ -0,0 +1,17 @@ +export function KeyboardLeftIcon({ className }: { className?: string }) { + return ( + + + + ); +} diff --git a/apps/webapp/app/assets/icons/KeyboardRightIcon.tsx b/apps/webapp/app/assets/icons/KeyboardRightIcon.tsx new file mode 100644 index 0000000000..879e7e183c --- /dev/null +++ b/apps/webapp/app/assets/icons/KeyboardRightIcon.tsx @@ -0,0 +1,17 @@ +export function KeyboardRightIcon({ className }: { className?: string }) { + return ( + + + + ); +} diff --git a/apps/webapp/app/assets/icons/KeyboardUpIcon.tsx b/apps/webapp/app/assets/icons/KeyboardUpIcon.tsx new file mode 100644 index 0000000000..d87f26488d --- /dev/null +++ b/apps/webapp/app/assets/icons/KeyboardUpIcon.tsx @@ -0,0 +1,17 @@ +export function KeyboardUpIcon({ className }: { className?: string }) { + return ( + + + + ); +} diff --git a/apps/webapp/app/assets/icons/KeyboardWindowsIcon.tsx b/apps/webapp/app/assets/icons/KeyboardWindowsIcon.tsx new file mode 100644 index 0000000000..859a633a30 --- /dev/null +++ b/apps/webapp/app/assets/icons/KeyboardWindowsIcon.tsx @@ -0,0 +1,17 @@ +export function KeyboardWindowsIcon({ className }: { className?: string }) { + return ( + + + + + + + ); +} diff --git a/apps/webapp/app/components/ErrorDisplay.tsx b/apps/webapp/app/components/ErrorDisplay.tsx index fb2be3cfeb..fcb720df88 100644 --- a/apps/webapp/app/components/ErrorDisplay.tsx +++ b/apps/webapp/app/components/ErrorDisplay.tsx @@ -49,7 +49,7 @@ export function ErrorDisplay({ title, message, button }: DisplayOptionsProps) { {message && {message}} diff --git a/apps/webapp/app/components/ListPagination.tsx b/apps/webapp/app/components/ListPagination.tsx index 7ac60cd283..bdefc32399 100644 --- a/apps/webapp/app/components/ListPagination.tsx +++ b/apps/webapp/app/components/ListPagination.tsx @@ -30,10 +30,12 @@ function NextButton({ cursor }: { cursor?: string }) { trailingIconClassName="text-text-dimmed" className={cn( "flex items-center", - !path && - "cursor-not-allowed opacity-50 group-hover:bg-transparent group-hover:text-text-dimmed" + !path && "cursor-not-allowed opacity-50 group-hover/button:bg-transparent" )} onClick={(e) => !path && e.preventDefault()} + shortcut={{ key: "k" }} + tooltip="Next" + disabled={!path} > Next @@ -51,10 +53,12 @@ function PreviousButton({ cursor }: { cursor?: string }) { leadingIconClassName="text-text-dimmed" className={cn( "flex items-center", - !path && - "cursor-not-allowed opacity-50 group-hover:bg-transparent group-hover:text-text-dimmed" + !path && "cursor-not-allowed opacity-50 group-hover/button:bg-transparent" )} onClick={(e) => !path && e.preventDefault()} + shortcut={{ key: "j" }} + tooltip="Previous" + disabled={!path} > Prev diff --git a/apps/webapp/app/components/Shortcuts.tsx b/apps/webapp/app/components/Shortcuts.tsx new file mode 100644 index 0000000000..d44359bb4e --- /dev/null +++ b/apps/webapp/app/components/Shortcuts.tsx @@ -0,0 +1,148 @@ +import { Keyboard } from "lucide-react"; +import { Header3 } from "./primitives/Headers"; +import { Paragraph } from "./primitives/Paragraph"; +import { + Sheet, + SheetContent, + SheetDescription, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "./primitives/SheetV3"; +import { ShortcutKey } from "./primitives/ShortcutKey"; +import { Button } from "./primitives/Buttons"; + +export function Shortcuts() { + return ( + + + + + + + +
+ + + Keyboard shortcuts + +
+
+
+
+ General + + + + + + + + + + + + + + to + + + + + + + + + + + + +
+
+ Runs page + + + + + + + + + +
+
+ Run page + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + to + + + +
+
+ Schedules page + + + +
+
+ Alerts page + + + +
+
+
+
+
+ ); +} + +function Shortcut({ children, name }: { children: React.ReactNode; name: string }) { + return ( +
+ {name} + {children} +
+ ); +} diff --git a/apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx b/apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx index a68f1988c7..cb2f6a263c 100644 --- a/apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx +++ b/apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx @@ -19,7 +19,7 @@ import { Paragraph } from "../primitives/Paragraph"; import { Popover, PopoverContent, PopoverSideMenuTrigger } from "../primitives/Popover"; import { StepNumber } from "../primitives/StepNumber"; import { MenuCount, SideMenuItem } from "./SideMenuItem"; - +import { Shortcuts } from "../Shortcuts"; export function HelpAndFeedback() { const [isHelpMenuOpen, setHelpMenuOpen] = useState(false); const currentPlan = useCurrentPlan(); @@ -84,6 +84,7 @@ export function HelpAndFeedback() { data-action="changelog" target="_blank" /> +
Need help? diff --git a/apps/webapp/app/components/primitives/Buttons.tsx b/apps/webapp/app/components/primitives/Buttons.tsx index 7cd4a83f2d..138b6ed5a4 100644 --- a/apps/webapp/app/components/primitives/Buttons.tsx +++ b/apps/webapp/app/components/primitives/Buttons.tsx @@ -1,9 +1,10 @@ import { Link, LinkProps, NavLink, NavLinkProps } from "@remix-run/react"; -import React, { forwardRef, useImperativeHandle, useRef } from "react"; +import React, { forwardRef, ReactNode, useImperativeHandle, useRef } from "react"; import { ShortcutDefinition, useShortcutKeys } from "~/hooks/useShortcutKeys"; import { cn } from "~/utils/cn"; import { IconNamesOrString, NamedIcon } from "./NamedIcon"; import { ShortcutKey } from "./ShortcutKey"; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./Tooltip"; const sizes = { small: { @@ -65,8 +66,7 @@ const theme = { icon: "text-text-bright", }, minimal: { - textColor: - "text-text-dimmed group-hover/button:text-text-bright transition group-disabled/button:text-text-dimmed/80", + textColor: "text-text-dimmed group-disabled/button:text-text-dimmed transition", button: "bg-transparent group-hover/button:bg-tertiary disabled:opacity-50 group-disabled/button:bg-transparent group-disabled/button:pointer-events-none", shortcut: @@ -175,6 +175,8 @@ export type ButtonContentPropsType = { shortcut?: ShortcutDefinition; variant: keyof typeof variant; shortcutPosition?: "before-trailing-icon" | "after-trailing-icon"; + tooltip?: ReactNode; + iconSpacing?: string; }; export function ButtonContent(props: ButtonContentPropsType) { @@ -188,23 +190,34 @@ export function ButtonContent(props: ButtonContentPropsType) { fullWidth, textAlignLeft, className, + tooltip, + iconSpacing, } = props; const variation = allVariants.variant[props.variant]; - // Based on the size prop, we'll use the corresponding variant classnames const btnClassName = cn(allVariants.$all, variation.button); const iconClassName = variation.icon; const iconSpacingClassName = variation.iconSpacing; const shortcutClassName = variation.shortcut; const textColorClassName = variation.textColor; - return ( + const renderShortcutKey = () => + shortcut && ( + + ); + + const buttonContent = (
{LeadingIcon && @@ -238,13 +251,10 @@ export function ButtonContent(props: ButtonContentPropsType) { <>{text} ))} - {shortcut && props.shortcutPosition === "before-trailing-icon" && ( - - )} + {shortcut && + !tooltip && + props.shortcutPosition === "before-trailing-icon" && + renderShortcutKey()} {TrailingIcon && (typeof TrailingIcon === "string" ? ( @@ -269,16 +279,27 @@ export function ButtonContent(props: ButtonContentPropsType) { ))} {shortcut && - (!props.shortcutPosition || props.shortcutPosition === "after-trailing-icon") && ( - - )} + !tooltip && + (!props.shortcutPosition || props.shortcutPosition === "after-trailing-icon") && + renderShortcutKey()}
); + + if (tooltip) { + return ( + + + {buttonContent} + + {tooltip} {shortcut && renderShortcutKey()} + + + + ); + } + + return buttonContent; } type ButtonPropsType = Pick< diff --git a/apps/webapp/app/components/primitives/LinkWithDisabled.tsx b/apps/webapp/app/components/primitives/LinkWithDisabled.tsx deleted file mode 100644 index 85b87a9b14..0000000000 --- a/apps/webapp/app/components/primitives/LinkWithDisabled.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { Link } from "@remix-run/react"; -import { cn } from "~/utils/cn"; - -type Props = Parameters[0] & { - disabled?: boolean; - disabledClassName?: string; -}; - -export function LinkDisabled({ disabled = false, disabledClassName, ...props }: Props) { - if (disabled) { - return ( - - {props.children} - - ); - } else { - return {props.children}; - } -} diff --git a/apps/webapp/app/components/primitives/Pagination.tsx b/apps/webapp/app/components/primitives/Pagination.tsx index 633e815d03..20a1a93be2 100644 --- a/apps/webapp/app/components/primitives/Pagination.tsx +++ b/apps/webapp/app/components/primitives/Pagination.tsx @@ -2,8 +2,7 @@ import { ChevronRightIcon } from "@heroicons/react/24/outline"; import { ChevronLeftIcon } from "@heroicons/react/24/solid"; import { Link, useLocation } from "@remix-run/react"; import { cn } from "~/utils/cn"; -import { ButtonContent } from "./Buttons"; -import { LinkDisabled } from "./LinkWithDisabled"; +import { LinkButton } from "./Buttons"; export function PaginationControls({ currentPage, @@ -21,16 +20,17 @@ export function PaginationControls({ return ( ); } @@ -61,7 +62,7 @@ function pageUrl(location: ReturnType, page: number): string } const baseClass = - "flex items-center justify-center border border-transparent min-w-6 h-6 px-1 text-xs font-medium transition text-text-dimmed rounded-sm"; + "flex items-center justify-center border border-transparent min-w-6 h-6 px-1 text-xs font-medium transition text-text-dimmed rounded-sm focus-visible:focus-custom"; const unselectedClass = "hover:bg-tertiary hover:text-text-bright"; const selectedClass = "border-charcoal-600 bg-tertiary text-text-bright hover:bg-charcoal-600/50"; diff --git a/apps/webapp/app/components/primitives/SheetV3.tsx b/apps/webapp/app/components/primitives/SheetV3.tsx new file mode 100644 index 0000000000..2bac7e9cb9 --- /dev/null +++ b/apps/webapp/app/components/primitives/SheetV3.tsx @@ -0,0 +1,126 @@ +import * as SheetPrimitive from "@radix-ui/react-dialog"; +import { cva, type VariantProps } from "class-variance-authority"; +import * as React from "react"; +import { cn } from "~/utils/cn"; +import { Header2 } from "./Headers"; +import { NamedIcon } from "./NamedIcon"; +import { ShortcutKey } from "./ShortcutKey"; + +const Sheet = SheetPrimitive.Root; + +const SheetTrigger = SheetPrimitive.Trigger; + +const SheetClose = SheetPrimitive.Close; + +const SheetPortal = SheetPrimitive.Portal; + +const SheetOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +SheetOverlay.displayName = SheetPrimitive.Overlay.displayName; + +const sheetVariants = cva( + "fixed z-50 gap-4 overflow-y-auto bg-background-dimmed shadow-lg transition ease-in-out border-grid-dimmed data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-300", + { + variants: { + side: { + top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top", + bottom: + "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom", + left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm", + right: + "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm", + }, + }, + defaultVariants: { + side: "right", + }, + } +); + +interface SheetContentProps + extends React.ComponentPropsWithoutRef, + VariantProps {} + +const SheetContent = React.forwardRef< + React.ElementRef, + SheetContentProps +>(({ side = "right", className, children, ...props }, ref) => ( + + + + {children} + + +)); +SheetContent.displayName = SheetPrimitive.Content.displayName; + +const SheetHeader = ({ className, ...props }: React.HTMLAttributes) => ( +
+); +SheetHeader.displayName = "SheetHeader"; + +const SheetFooter = ({ className, ...props }: React.HTMLAttributes) => ( +
+); +SheetFooter.displayName = "SheetFooter"; + +const SheetTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + {children} + + + + Close + + +)); +SheetTitle.displayName = SheetPrimitive.Title.displayName; + +const SheetDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +SheetDescription.displayName = SheetPrimitive.Description.displayName; + +export { + Sheet, + SheetClose, + SheetContent, + SheetDescription, + SheetFooter, + SheetHeader, + SheetOverlay, + SheetPortal, + SheetTitle, + SheetTrigger, +}; diff --git a/apps/webapp/app/components/primitives/ShortcutKey.tsx b/apps/webapp/app/components/primitives/ShortcutKey.tsx index df422eaf2c..faa7745c11 100644 --- a/apps/webapp/app/components/primitives/ShortcutKey.tsx +++ b/apps/webapp/app/components/primitives/ShortcutKey.tsx @@ -1,25 +1,35 @@ -import { Fragment } from "react"; -import { Modifier, ShortcutDefinition } from "~/hooks/useShortcutKeys"; +import { KeyboardDownIcon } from "~/assets/icons/KeyboardDownIcon"; +import { KeyboardLeftIcon } from "~/assets/icons/KeyboardLeftIcon"; +import { KeyboardRightIcon } from "~/assets/icons/KeyboardRightIcon"; +import { KeyboardUpIcon } from "~/assets/icons/KeyboardUpIcon"; +import { KeyboardWindowsIcon } from "~/assets/icons/KeyboardWindowsIcon"; +import { Modifier, Shortcut } from "~/hooks/useShortcutKeys"; import { cn } from "~/utils/cn"; import { useOperatingSystem } from "./OperatingSystemProvider"; -import { - ChevronDownIcon, - ChevronLeftIcon, - ChevronRightIcon, - ChevronUpIcon, -} from "@heroicons/react/20/solid"; + +const medium = + "text-[0.75rem] font-medium min-w-[17px] rounded-[2px] tabular-nums px-1 ml-1 -mr-0.5 flex items-center gap-x-1.5 border border-dimmed/40 text-text-dimmed group-hover:text-text-bright/80 group-hover:border-dimmed/60 transition uppercase"; export const variants = { small: - "text-[0.6rem] font-medium min-w-[17px] rounded-[2px] px-1 ml-1 -mr-0.5 grid place-content-center border border-dimmed/40 text-text-dimmed group-hover:text-text-bright/80 group-hover:border-dimmed/60 transition uppercase", - medium: - "text-[0.75rem] font-medium min-w-[17px] rounded-[2px] px-1 ml-1 -mr-0.5 grid place-content-center border border-dimmed/40 text-text-dimmed group-hover:text-text-bright/80 group-hover:border-dimmed/60 transition uppercase", + "text-[0.6rem] font-medium min-w-[17px] rounded-[2px] tabular-nums px-1 ml-1 -mr-0.5 flex items-center gap-x-1 border border-dimmed/40 text-text-dimmed group-hover:text-text-bright/80 group-hover:border-dimmed/60 transition uppercase", + medium, + "medium/bright": cn(medium, "bg-charcoal-750 text-text-bright border-charcoal-650"), }; export type ShortcutKeyVariant = keyof typeof variants; +type ShortcutKey = Partial; + +type ShortcutKeyDefinition = + | { + windows: ShortcutKey; + mac: ShortcutKey; + } + | ShortcutKey; + type ShortcutKeyProps = { - shortcut: ShortcutDefinition; + shortcut: ShortcutKeyDefinition; variant: ShortcutKeyVariant; className?: string; }; @@ -29,50 +39,62 @@ export function ShortcutKey({ shortcut, variant, className }: ShortcutKeyProps) const isMac = platform === "mac"; let relevantShortcut = "mac" in shortcut ? (isMac ? shortcut.mac : shortcut.windows) : shortcut; const modifiers = relevantShortcut.modifiers ?? []; - const character = keyString(relevantShortcut.key, isMac, variant); + const character = relevantShortcut.key ? keyString(relevantShortcut.key, isMac, variant) : null; return ( {modifiers.map((k) => ( - {modifierString(k, isMac)} + + {modifierString(k, isMac, variant)} + ))} - {character} + {character && {character}} ); } -function keyString(key: String, isMac: boolean, size: "small" | "medium") { +function keyString(key: string, isMac: boolean, variant: "small" | "medium" | "medium/bright") { key = key.toLowerCase(); - const className = size === "small" ? "w-2.5 h-4" : "w-3 h-5"; + const className = variant === "small" ? "w-2.5 h-4" : "w-3 h-5"; switch (key) { case "enter": - return isMac ? "↵" : key; + return isMac ? "↵" : Enter; + case "esc": + return Esc; + case "del": + return Del; case "arrowdown": - return ; + return ; case "arrowup": - return ; + return ; case "arrowleft": - return ; + return ; case "arrowright": - return ; + return ; default: return key; } } -function modifierString(modifier: Modifier, isMac: boolean) { +function modifierString( + modifier: Modifier, + isMac: boolean, + variant: "small" | "medium" | "medium/bright" +): string | JSX.Element { + const className = variant === "small" ? "w-2.5 h-4" : "w-3.5 h-5"; + switch (modifier) { case "alt": - return isMac ? "⌥" : "Alt+"; + return isMac ? "⌥" : Alt; case "ctrl": - return isMac ? "⌃" : "Ctrl+"; + return isMac ? "⌃" : Ctrl; case "meta": - return isMac ? "⌘" : "⊞+"; + return isMac ? "⌘" : ; case "shift": - return isMac ? "⇧" : "Shift+"; + return "⇧"; case "mod": - return isMac ? "⌘" : "Ctrl+"; + return isMac ? "⌘" : Ctrl; } } diff --git a/apps/webapp/app/components/primitives/Switch.tsx b/apps/webapp/app/components/primitives/Switch.tsx index 2c3121676f..5cb860910b 100644 --- a/apps/webapp/app/components/primitives/Switch.tsx +++ b/apps/webapp/app/components/primitives/Switch.tsx @@ -8,15 +8,15 @@ const variations = { large: { container: "flex items-center gap-x-2 rounded-md hover:bg-tertiary p-2 transition focus-custom", root: "h-6 w-11", - thumb: "h-5 w-5 data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0", - text: "text-sm text-charcoal-400 group-hover:text-charcoal-200 transition", + thumb: "size-5 data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0", + text: "text-sm text-text-dimmed", }, small: { container: "flex items-center h-[1.5rem] gap-x-1.5 rounded hover:bg-tertiary disabled:hover:bg-transparent pr-1 py-[0.1rem] pl-1.5 transition focus-custom disabled:hover:text-charcoal-400 disabled:opacity-50 text-charcoal-400 hover:text-charcoal-200 disabled:hover:cursor-not-allowed hover:cursor-pointer", root: "h-3 w-6", - thumb: "h-2.5 w-2.5 data-[state=checked]:translate-x-2.5 data-[state=unchecked]:translate-x-0", - text: "text-xs", + thumb: "size-2.5 data-[state=checked]:translate-x-2.5 data-[state=unchecked]:translate-x-0", + text: "text-xs text-text-dimmed", }, }; @@ -38,7 +38,7 @@ export const Switch = React.forwardRef diff --git a/apps/webapp/app/components/runs/v3/BatchFilters.tsx b/apps/webapp/app/components/runs/v3/BatchFilters.tsx index 02474fa46f..f7ab261d4e 100644 --- a/apps/webapp/app/components/runs/v3/BatchFilters.tsx +++ b/apps/webapp/app/components/runs/v3/BatchFilters.tsx @@ -400,7 +400,7 @@ function BatchIdDropdown({ disabled={error !== undefined || !batchId} variant="secondary/small" shortcut={{ - modifiers: ["meta"], + modifiers: ["mod"], key: "Enter", enabledOnInputElements: true, }} diff --git a/apps/webapp/app/components/runs/v3/CancelRunDialog.tsx b/apps/webapp/app/components/runs/v3/CancelRunDialog.tsx index d4264886b7..2d0439402f 100644 --- a/apps/webapp/app/components/runs/v3/CancelRunDialog.tsx +++ b/apps/webapp/app/components/runs/v3/CancelRunDialog.tsx @@ -40,7 +40,7 @@ export function CancelRunDialog({ runFriendlyId, redirectPath }: CancelRunDialog variant="danger/medium" LeadingIcon={isLoading ? "spinner-white" : NoSymbolIcon} disabled={isLoading} - shortcut={{ modifiers: ["meta"], key: "enter" }} + shortcut={{ modifiers: ["mod"], key: "enter" }} > {isLoading ? "Canceling..." : "Cancel run"} diff --git a/apps/webapp/app/components/runs/v3/CheckBatchCompletionDialog.tsx b/apps/webapp/app/components/runs/v3/CheckBatchCompletionDialog.tsx index 70a51a3cf6..10df63a4de 100644 --- a/apps/webapp/app/components/runs/v3/CheckBatchCompletionDialog.tsx +++ b/apps/webapp/app/components/runs/v3/CheckBatchCompletionDialog.tsx @@ -39,7 +39,7 @@ export function CheckBatchCompletionDialog({ variant="primary/medium" LeadingIcon={isLoading ? "spinner-white" : undefined} disabled={isLoading} - shortcut={{ modifiers: ["meta"], key: "enter" }} + shortcut={{ modifiers: ["mod"], key: "enter" }} > {isLoading ? "Attempting resume..." : "Attempt resume"} diff --git a/apps/webapp/app/components/runs/v3/ReplayRunDialog.tsx b/apps/webapp/app/components/runs/v3/ReplayRunDialog.tsx index 589b686a5c..e29b8a9e4b 100644 --- a/apps/webapp/app/components/runs/v3/ReplayRunDialog.tsx +++ b/apps/webapp/app/components/runs/v3/ReplayRunDialog.tsx @@ -159,7 +159,7 @@ function ReplayForm({ variant="primary/medium" LeadingIcon={isSubmitting ? ButtonSpinner : undefined} disabled={isSubmitting} - shortcut={{ modifiers: ["meta"], key: "enter", enabledOnInputElements: true }} + shortcut={{ modifiers: ["mod"], key: "enter", enabledOnInputElements: true }} > {isSubmitting ? "Replaying..." : "Replay run"} diff --git a/apps/webapp/app/components/runs/v3/RetryDeploymentIndexingDialog.tsx b/apps/webapp/app/components/runs/v3/RetryDeploymentIndexingDialog.tsx index d689a874e8..6c1ca5fe92 100644 --- a/apps/webapp/app/components/runs/v3/RetryDeploymentIndexingDialog.tsx +++ b/apps/webapp/app/components/runs/v3/RetryDeploymentIndexingDialog.tsx @@ -48,7 +48,7 @@ export function RetryDeploymentIndexingDialog({ variant="primary/medium" LeadingIcon={isLoading ? "spinner-white" : ArrowPathIcon} disabled={isLoading} - shortcut={{ modifiers: ["meta"], key: "enter" }} + shortcut={{ modifiers: ["mod"], key: "enter" }} > {isLoading ? "Retrying..." : "Retry indexing"} diff --git a/apps/webapp/app/components/runs/v3/RollbackDeploymentDialog.tsx b/apps/webapp/app/components/runs/v3/RollbackDeploymentDialog.tsx index aeb2f61cc0..ccba03b030 100644 --- a/apps/webapp/app/components/runs/v3/RollbackDeploymentDialog.tsx +++ b/apps/webapp/app/components/runs/v3/RollbackDeploymentDialog.tsx @@ -48,7 +48,7 @@ export function RollbackDeploymentDialog({ variant="primary/medium" LeadingIcon={isLoading ? "spinner-white" : ArrowPathIcon} disabled={isLoading} - shortcut={{ modifiers: ["meta"], key: "enter" }} + shortcut={{ modifiers: ["mod"], key: "enter" }} > {isLoading ? "Rolling back..." : "Roll back deployment"} diff --git a/apps/webapp/app/components/runs/v3/RunFilters.tsx b/apps/webapp/app/components/runs/v3/RunFilters.tsx index 242ef0a491..6cc75a6129 100644 --- a/apps/webapp/app/components/runs/v3/RunFilters.tsx +++ b/apps/webapp/app/components/runs/v3/RunFilters.tsx @@ -804,7 +804,7 @@ function RunIdDropdown({ disabled={error !== undefined || !runId} variant="secondary/small" shortcut={{ - modifiers: ["meta"], + modifiers: ["mod"], key: "Enter", enabledOnInputElements: true, }} @@ -922,7 +922,7 @@ function BatchIdDropdown({ disabled={error !== undefined || !batchId} variant="secondary/small" shortcut={{ - modifiers: ["meta"], + modifiers: ["mod"], key: "Enter", enabledOnInputElements: true, }} @@ -1040,7 +1040,7 @@ function ScheduleIdDropdown({ disabled={error !== undefined || !scheduleId} variant="secondary/small" shortcut={{ - modifiers: ["meta"], + modifiers: ["mod"], key: "Enter", enabledOnInputElements: true, }} diff --git a/apps/webapp/app/components/runs/v3/SharedFilters.tsx b/apps/webapp/app/components/runs/v3/SharedFilters.tsx index 3f07f133ed..03474b5960 100644 --- a/apps/webapp/app/components/runs/v3/SharedFilters.tsx +++ b/apps/webapp/app/components/runs/v3/SharedFilters.tsx @@ -390,7 +390,7 @@ export function CustomDateRangeDropdown({ @@ -403,7 +403,7 @@ function ReplayRuns({ onOpen }: { onOpen: (open: boolean) => void }) { variant="primary/medium" LeadingIcon={isLoading ? "spinner-white" : ArrowPathIcon} disabled={isLoading} - shortcut={{ modifiers: ["meta"], key: "enter" }} + shortcut={{ modifiers: ["mod"], key: "enter" }} > {isLoading ? "Replaying..." : `Replay ${selectedItems.size} runs`} diff --git a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.schedules.new/route.tsx b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.schedules.new/route.tsx index 56c82e9148..d85c3d53f4 100644 --- a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.schedules.new/route.tsx +++ b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.schedules.new/route.tsx @@ -393,7 +393,7 @@ export function UpsertScheduleForm({ variant="primary/medium" type="submit" disabled={isLoading} - shortcut={{ key: "enter", modifiers: ["meta"] }} + shortcut={{ key: "enter", modifiers: ["mod"] }} LeadingIcon={isLoading ? "spinner" : undefined} > {buttonText(mode, isLoading)} diff --git a/apps/webapp/app/routes/storybook.buttons/route.tsx b/apps/webapp/app/routes/storybook.buttons/route.tsx index 3baff3b1c3..f6e6ce0b7e 100644 --- a/apps/webapp/app/routes/storybook.buttons/route.tsx +++ b/apps/webapp/app/routes/storybook.buttons/route.tsx @@ -70,7 +70,7 @@ export default function Story() {
Shortcut - -
@@ -193,19 +193,19 @@ export default function Story() {
Shortcut - - - - -
diff --git a/apps/webapp/app/routes/storybook.shortcuts/route.tsx b/apps/webapp/app/routes/storybook.shortcuts/route.tsx index 54b7ddad59..785247a4c9 100644 --- a/apps/webapp/app/routes/storybook.shortcuts/route.tsx +++ b/apps/webapp/app/routes/storybook.shortcuts/route.tsx @@ -7,11 +7,13 @@ import { ShortcutDefinition } from "~/hooks/useShortcutKeys"; const shortcuts: ShortcutDefinition[] = [ { key: "esc" }, { key: "f" }, - { key: "f", modifiers: ["meta"] }, - { key: "k", modifiers: ["meta"] }, + { key: "f", modifiers: ["mod"] }, + { key: "k", modifiers: ["mod"] }, { key: "del", modifiers: ["ctrl", "alt"] }, - { key: "enter", modifiers: ["meta"] }, + { key: "f", modifiers: ["shift"] }, { key: "enter", modifiers: ["mod"] }, + { key: "enter", modifiers: ["mod"] }, + { key: "g", modifiers: ["meta"] }, ]; export default function Story() { @@ -31,6 +33,7 @@ function Collection({ platform }: { platform: "mac" | "windows" }) {
+