Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shortcut improvements #1573

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open

Shortcut improvements #1573

wants to merge 24 commits into from

Conversation

samejr
Copy link
Member

@samejr samejr commented Dec 17, 2024

New shortcut panel

CleanShot 2024-12-17 at 15 33 55

Shortcut panel accessed via the Help & Feedback popover

CleanShot 2024-12-17 at 15 33 45

Navigate pagination left/right with 'j' and 'k' shortcut keys

CleanShot 2024-12-17 at 15 35 03
CleanShot 2024-12-17 at 15 35 41

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new component for displaying keyboard shortcuts in a modal.
    • Added contextual tooltips and keyboard shortcuts for pagination buttons.
    • Added new keyboard icon components for improved visual representation.
  • Enhancements

    • Improved error handling for batch ID filtering.
    • Enhanced keyboard shortcut handling across various components by updating modifier keys.
    • Updated the visual styling of the Switch component for better user experience.
    • Refined the handling of cron pattern validation in the schedule form.
  • Bug Fixes

    • Fixed tooltip rendering for buttons based on new properties.
  • Refactor

    • Updated styling and structure for several components, including buttons and modals.
  • Chores

    • Removed unused LinkWithDisabled component.

Copy link

changeset-bot bot commented Dec 17, 2024

⚠️ No Changeset found

Latest commit: ba16fcc

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

coderabbitai bot commented Dec 17, 2024

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 eslint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

apps/webapp/app/components/Shortcuts.tsx

Oops! Something went wrong! :(

ESLint: 8.45.0

ESLint couldn't find the config "custom" to extend from. Please check that the name of the config is correct.

The config "custom" was referenced from the config file in "/.eslintrc.js".

If you still have problems, please stop by https://eslint.org/chat/help to chat with the team.

Walkthrough

This pull request introduces a comprehensive set of modifications across multiple components in the web application, focusing on enhancing keyboard shortcuts, tooltips, and user interface elements. The changes primarily involve updating shortcut modifiers from "meta" to "mod", adding new components like Shortcuts and SheetV3, and improving button and pagination interactions. The modifications aim to provide a more consistent and accessible user experience across different platforms and components.

Changes

File Change Summary
apps/webapp/app/components/ErrorDisplay.tsx Updated LinkButton shortcut from meta to mod modifier
apps/webapp/app/components/ListPagination.tsx Added keyboard shortcuts and tooltips to NextButton and PreviousButton
apps/webapp/app/components/Shortcuts.tsx New component for displaying keyboard shortcuts in a modal sheet
apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx Added Shortcuts component to help menu
apps/webapp/app/components/primitives/Buttons.tsx Enhanced button functionality with tooltip support
apps/webapp/app/components/primitives/LinkWithDisabled.tsx Removed LinkDisabled component
apps/webapp/app/components/primitives/Pagination.tsx Replaced LinkDisabled with LinkButton in pagination controls
apps/webapp/app/components/primitives/SheetV3.tsx New modal sheet interface components
apps/webapp/app/components/primitives/ShortcutKey.tsx Updated variant handling and rendering of shortcut keys
Multiple run-related components Updated shortcut modifiers from meta to mod

Possibly related PRs

Suggested reviewers

  • matt-aitken

Poem

🐰 Hop, hop, keyboard shortcuts dance,
From meta to mod, a nimble advance!
Tooltips sparkle, buttons shine bright,
Accessibility leaps to a new height!
Code rabbits rejoice, the UI's now sleek! 🚀


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (13)
apps/webapp/app/components/runs/v3/CheckBatchCompletionDialog.tsx (1)

42-42: Consider adding a tooltip to improve shortcut discoverability.

Since this is part of a broader effort to improve shortcuts, consider adding a tooltip to make the shortcut more discoverable. This would help users learn and remember the available shortcuts.

 <Button
   type="submit"
   name="redirectUrl"
   value={redirectPath}
   variant="primary/medium"
   LeadingIcon={isLoading ? "spinner-white" : undefined}
   disabled={isLoading}
   shortcut={{ modifiers: ["mod"], key: "enter" }}
+  tooltip={`Resume (${navigator.platform.includes('Mac') ? '⌘' : 'Ctrl'}+Enter)`}
 >
apps/webapp/app/components/runs/v3/RollbackDeploymentDialog.tsx (1)

51-53: Consider adding an aria-label for the shortcut.

For better accessibility, consider adding an aria-label to describe the keyboard shortcut.

 <Button
   type="submit"
   name="redirectUrl"
   value={redirectPath}
   variant="primary/medium"
   LeadingIcon={isLoading ? "spinner-white" : ArrowPathIcon}
   disabled={isLoading}
   shortcut={{ modifiers: ["mod"], key: "enter" }}
+  aria-label={`Roll back deployment (${navigator.platform.includes('Mac') ? '⌘' : 'Ctrl'}+Enter)`}
 >
   {isLoading ? "Rolling back..." : "Roll back deployment"}
 </Button>
apps/webapp/app/components/runs/v3/CancelRunDialog.tsx (1)

43-43: Consider adding a tooltip to improve shortcut discoverability.

Since this is part of a larger effort to improve shortcuts, consider adding a tooltip to help users discover this shortcut.

 <Button
   type="submit"
   name="redirectUrl"
   value={redirectPath}
   variant="danger/medium"
   LeadingIcon={isLoading ? "spinner-white" : NoSymbolIcon}
   disabled={isLoading}
   shortcut={{ modifiers: ["mod"], key: "enter" }}
+  tooltip={`Press ${navigator.platform.includes('Mac') ? '⌘' : 'Ctrl'}+Enter to confirm`}
 >
apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx (1)

87-87: Consider enhancing the Shortcuts component integration

The placement of the Shortcuts component in the menu structure is logical. However, consider the following improvements:

  1. Add an aria-label for better accessibility
  2. Consider adding a visual separator or header similar to the "Need help?" section below it
-            <Shortcuts />
+            <Paragraph className="pb-1 pl-1.5 pt-1.5 text-xs">Keyboard Shortcuts</Paragraph>
+            <Shortcuts aria-label="Keyboard shortcuts menu" />
apps/webapp/app/components/primitives/Pagination.tsx (2)

23-34: Consider enhancing shortcut discoverability in tooltip

The implementation of the 'j' shortcut for previous page navigation is good, but could be more discoverable.

Consider updating the tooltip to include the shortcut:

-        tooltipDescription="Previous"
+        tooltipDescription="Previous (j)"

Also, consider adding a check to prevent shortcut triggering while focus is in text input fields.


42-53: Consider extracting common button configuration

The implementation looks good but there's duplicate configuration between Previous/Next buttons.

Consider creating a shared configuration object:

const PAGINATION_BUTTONS = {
  previous: {
    key: "j",
    label: "Previous",
    Icon: ChevronLeftIcon,
    isLeading: true,
  },
  next: {
    key: "k",
    label: "Next",
    Icon: ChevronRightIcon,
    isLeading: false,
  },
} as const;

This would reduce duplication and make maintenance easier.

apps/webapp/app/components/primitives/ShortcutKey.tsx (2)

11-19: Consider adding JSDoc comments for variants

The variant restructuring looks good, but documenting the visual differences between variants would help other developers.

Add documentation like this:

+/**
+ * Base styles for medium-sized shortcut keys
+ */
 const medium = "text-[0.75rem] font-medium...";

+/**
+ * Variant styles for shortcut keys:
+ * - small: Compact layout for tight spaces
+ * - medium: Standard size with default styling
+ * - medium/bright: Highlighted version with darker background
+ */
 export const variants = {

38-42: Add ARIA attributes for accessibility

While the span usage improves semantics, adding ARIA attributes would enhance screen reader support.

-    <span className={cn(variants[variant], className)}>
+    <span 
+      className={cn(variants[variant], className)}
+      role="tooltip" 
+      aria-label={`Keyboard shortcut: ${modifiers.join(' ')} ${character}`}
+    >
apps/webapp/app/components/primitives/Buttons.tsx (1)

221-222: Avoid potential undefined class names

When applying iconSpacingClassName and iconSpacing, ensure they are defined to prevent undefined from appearing in the className attribute.

Consider setting default values or conditionally adding these class names:

 <div
   className={cn(
     textAlignLeft ? "text-left" : "justify-center",
     "flex w-full items-center",
-    iconSpacingClassName,
-    iconSpacing
+    iconSpacingClassName || "",
+    iconSpacing || ""
   )}
 >
apps/webapp/app/components/Shortcuts.tsx (2)

141-148: Add type definition for Shortcut component props

Extract the props interface for better type safety and documentation.

+interface ShortcutProps {
+  children: React.ReactNode;
+  name: string;
+}
+
-function Shortcut({ children, name }: { children: React.ReactNode; name: string }) {
+function Shortcut({ children, name }: ShortcutProps) {

43-134: Consider extracting shortcut definitions

The shortcut definitions could be moved to a separate configuration file for better maintainability and reusability.

Consider creating a shortcuts.config.ts file:

export interface ShortcutSection {
  title: string;
  shortcuts: Array<{
    name: string;
    shortcut: ShortcutDefinition | ShortcutDefinition[];
  }>;
}

export const shortcutSections: ShortcutSection[] = [
  {
    title: "General",
    shortcuts: [
      {
        name: "Close",
        shortcut: { key: "esc" }
      },
      // ... other shortcuts
    ]
  },
  // ... other sections
];

This would make it easier to maintain and update shortcuts across the application.

apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.schedules.new/route.tsx (1)

Line range hint 89-93: Consider enhancing error handling with more specific messages

While the current error handling includes logging, consider providing more specific error messages to users based on the error type, while maintaining security by not exposing sensitive details.

 } catch (error: any) {
   logger.error("Failed to create schedule", error);
 
-  const errorMessage = `Something went wrong. Please try again.`;
+  const errorMessage = error.code === "P2025" 
+    ? "The schedule could not be found. It may have been deleted."
+    : "Something went wrong. Please try again.";
   return redirectWithErrorMessage(
     v3SchedulesPath({ slug: organizationSlug }, { slug: projectParam }),
     request,
     errorMessage
   );
apps/webapp/app/components/ListPagination.tsx (1)

33-33: Consider adding visual feedback for keyboard navigation

The hover styles are well-handled, but consider adding visual feedback when shortcuts are used to improve the user experience.

-        !path && "cursor-not-allowed opacity-50 group-hover/button:bg-transparent"
+        !path && "cursor-not-allowed opacity-50 group-hover/button:bg-transparent",
+        "focus-visible:ring-2 focus-visible:ring-primary/10 transition-all"

Also applies to: 56-56

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3418aa6 and 72d1381.

📒 Files selected for processing (22)
  • apps/webapp/app/components/ErrorDisplay.tsx (1 hunks)
  • apps/webapp/app/components/ListPagination.tsx (2 hunks)
  • apps/webapp/app/components/Shortcuts.tsx (1 hunks)
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx (2 hunks)
  • apps/webapp/app/components/primitives/Buttons.tsx (6 hunks)
  • apps/webapp/app/components/primitives/LinkWithDisabled.tsx (0 hunks)
  • apps/webapp/app/components/primitives/Pagination.tsx (2 hunks)
  • apps/webapp/app/components/primitives/SheetV3.tsx (1 hunks)
  • apps/webapp/app/components/primitives/ShortcutKey.tsx (2 hunks)
  • apps/webapp/app/components/primitives/Switch.tsx (2 hunks)
  • apps/webapp/app/components/runs/v3/BatchFilters.tsx (1 hunks)
  • apps/webapp/app/components/runs/v3/CancelRunDialog.tsx (1 hunks)
  • apps/webapp/app/components/runs/v3/CheckBatchCompletionDialog.tsx (1 hunks)
  • apps/webapp/app/components/runs/v3/ReplayRunDialog.tsx (1 hunks)
  • apps/webapp/app/components/runs/v3/RetryDeploymentIndexingDialog.tsx (1 hunks)
  • apps/webapp/app/components/runs/v3/RollbackDeploymentDialog.tsx (1 hunks)
  • apps/webapp/app/components/runs/v3/RunFilters.tsx (3 hunks)
  • apps/webapp/app/components/runs/v3/SharedFilters.tsx (1 hunks)
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs._index/route.tsx (2 hunks)
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.schedules.new/route.tsx (1 hunks)
  • apps/webapp/app/routes/storybook.buttons/route.tsx (3 hunks)
  • apps/webapp/app/routes/storybook.shortcuts/route.tsx (2 hunks)
💤 Files with no reviewable changes (1)
  • apps/webapp/app/components/primitives/LinkWithDisabled.tsx
✅ Files skipped from review due to trivial changes (3)
  • apps/webapp/app/components/runs/v3/SharedFilters.tsx
  • apps/webapp/app/components/runs/v3/ReplayRunDialog.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs._index/route.tsx
🧰 Additional context used
🪛 Biome (1.9.4)
apps/webapp/app/components/primitives/ShortcutKey.tsx

[error] 46-46: Don't use 'String' as a type.

Use lowercase primitives for consistency.
Safe fix: Use 'string' instead

(lint/complexity/noBannedTypes)

🔇 Additional comments (22)
apps/webapp/app/components/runs/v3/CheckBatchCompletionDialog.tsx (1)

42-42: LGTM! Good platform-agnostic shortcut implementation.

The change from "meta" to "mod" improves cross-platform compatibility. This modifier automatically maps to Command (⌘) on macOS and Control (Ctrl) on Windows/Linux, providing a consistent experience across different operating systems.

apps/webapp/app/components/runs/v3/RollbackDeploymentDialog.tsx (1)

51-51: LGTM! Good platform-agnostic shortcut implementation.

The change from "meta" to "mod" improves cross-platform compatibility by automatically adapting to Command (⌘) on macOS and Control on Windows/Linux.

apps/webapp/app/components/runs/v3/CancelRunDialog.tsx (1)

43-43: LGTM! Good improvement for cross-platform compatibility.

Changing from "meta" to "mod" is a positive improvement as it makes the shortcut more consistent across different operating systems:

  • macOS: maps to Command (⌘)
  • Windows/Linux: maps to Control (Ctrl)
apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx (1)

22-22: Verify the Shortcuts component import path

The import looks correct, but let's ensure the component exists at the specified location.

✅ Verification successful

The fd command confirmed that the Shortcuts component exists at apps/webapp/app/components/Shortcuts.tsx, which matches the relative import path ../Shortcuts from apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx. Let me generate the final response:

Import path for Shortcuts component is correct

The Shortcuts component exists at the expected location relative to HelpAndFeedbackPopover.tsx, confirming that the import statement is valid.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the Shortcuts component exists
fd -e tsx -e ts "Shortcuts" apps/webapp/app/components

Length of output: 95

apps/webapp/app/components/primitives/SheetV3.tsx (1)

1-126: Components are well-implemented and adhere to best practices

The SheetV3 components are thoughtfully implemented, making effective use of React's forwardRef and Radix UI's dialog primitives. The code is clean, readable, and follows consistent coding standards. Exporting the components at the end enhances reusability across the application.

apps/webapp/app/components/primitives/Pagination.tsx (2)

5-5: LGTM: Clean import addition

The LinkButton import aligns with the modernization of the pagination controls.


27-27: Verify shortcut conflicts across the application

Let's ensure the 'j' and 'k' shortcuts don't conflict with existing shortcuts.

Also applies to: 46-46

✅ Verification successful

Keyboard shortcuts 'j' and 'k' are consistently implemented

The shortcuts are properly implemented and documented:

  • 'j' for Previous page is consistently used across pagination components
  • 'k' for Next page is consistently used across pagination components
  • These shortcuts are properly documented in the Shortcuts component
  • No conflicting uses of these keys were found in other keyboard handlers
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other shortcut definitions using j or k
echo "Searching for potential shortcut conflicts..."
rg -l "shortcut.*['\"]([jk])['\"]" --type typescript --type typescript-react

# Search for any keyboard event handlers that might interfere
echo "Searching for keyboard event handlers..."
rg "onKeyDown|onKeyPress|onKeyUp" --type typescript --type typescript-react

Length of output: 422


Script:

#!/bin/bash
# Search for shortcut definitions using j or k
echo "Searching for potential shortcut conflicts..."
rg -l "shortcut.*['\"]([jk])['\"]"

# Search for keyboard event handlers
echo "Searching for keyboard event handlers..."
rg "onKeyDown|onKeyPress|onKeyUp"

# Search for files with .tsx or .ts extension that might contain shortcuts
echo "Searching TypeScript files..."
fd "\.(tsx|ts)$" -x rg -l "shortcut.*['\"]([jk])['\"]" {} \;

Length of output: 1158


Script:

#!/bin/bash
# Let's check the actual implementation of shortcuts in these files
echo "Content of Shortcuts.tsx:"
cat apps/webapp/app/components/Shortcuts.tsx

echo -e "\nContent of ListPagination.tsx:"
cat apps/webapp/app/components/ListPagination.tsx

echo -e "\nContent of primitives/Pagination.tsx:"
cat apps/webapp/app/components/primitives/Pagination.tsx

Length of output: 13459

apps/webapp/app/components/primitives/ShortcutKey.tsx (2)

7-9: LGTM! Clean type imports

The new type imports from the hooks directory align well with the shortcut improvements objective.


Line range hint 66-77: Great addition of the "mod" modifier for cross-platform support!

The addition of the "mod" modifier (⌘ on Mac, Ctrl on Windows) aligns perfectly with the PR's objective of improving shortcuts across platforms.

Let's verify the consistent usage of "mod" across the codebase:

✅ Verification successful

The "mod" modifier is being used consistently across the codebase

Based on the search results, I can confirm that:

  • The "meta" keyword only appears in the type definition and the switch case implementation, not in actual shortcut usage
  • All keyboard shortcuts across the codebase use "mod" for cross-platform modifier keys (e.g., modifiers: ["mod"])
  • The implementation is used consistently in various components like buttons, dialogs, and filters
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any remaining "meta" modifier usage that should be "mod"
rg -l '"meta"' --type=typescript --type=javascript

# Find all shortcut definitions to ensure consistent usage
ast-grep --pattern 'shortcut: { modifiers: [$$$] }'

Length of output: 141


Script:

#!/bin/bash
# Search for "meta" usage in all files (without file type restriction)
rg '"meta"'

# Search for shortcut definitions with a more flexible pattern
rg -A 2 'modifiers.*\[' 

# Search for keyboard shortcut related patterns
ast-grep --pattern 'shortcut = {
  $$$
}'

# Try alternative pattern for keyboard shortcuts
ast-grep --pattern 'const $_ = {
  modifiers: $_,
  $$$
}'

Length of output: 10566

apps/webapp/app/components/primitives/Switch.tsx (3)

11-12: Improved styling consistency using modern Tailwind utilities

The changes to use size-* utility and semantic color tokens improve maintainability and consistency.


18-19: Consistent styling pattern applied to small variant

Similar improvements applied to the small variant maintain consistency across variations.


41-41: Enhanced interactive states with better visual hierarchy

The switch background colors and hover states have been improved for better user feedback, using blue-500 for the active state and a subtle hover effect for the inactive state.

apps/webapp/app/routes/storybook.shortcuts/route.tsx (1)

34-34: LGTM: New variant addition for ShortcutKey

The addition of the "medium/bright" variant aligns with the PR objectives to improve the shortcuts panel visual presentation.

apps/webapp/app/components/Shortcuts.tsx (1)

15-139: Verify shortcut handling across different operating systems

The shortcuts implementation should be tested across different operating systems to ensure consistent behavior.

✅ Verification successful

Based on the search results, I can now provide a final response as we have found evidence of proper platform-specific shortcut handling in the codebase:

Shortcuts implementation correctly handles cross-platform compatibility

The codebase already implements proper platform-specific shortcut handling:

  • Uses useOperatingSystem hook to detect the platform
  • Handles Mac-specific modifiers (⌘, ⌥, ⇧, ⌃) vs Windows modifiers (Ctrl+, Alt+, Shift+)
  • Supports platform-specific shortcut definitions through mac and windows properties
  • Properly maps the "mod" key to ⌘ on Mac and Ctrl on Windows
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for platform-specific shortcut handling

# Look for platform-specific shortcut implementations
rg -l "useOperatingSystem|getPlatform|isMac|isWindows" --type typescript

# Check for modifier key handling
ast-grep --pattern 'shortcut = { modifiers: [$$$] }'

Length of output: 164


Script:

#!/bin/bash
# Search for shortcut-related code and platform-specific handling
rg -l "useOperatingSystem|getPlatform|isMac|isWindows"

# Look for shortcut implementations and modifier key handling
rg -A 5 "shortcut.*modifiers"

# Search for any platform-specific keyboard handling
rg -A 5 "(mac|windows|platform).*(key|shortcut|keyboard)"

Length of output: 80133


Script:

#!/bin/bash
# Search for keyboard/shortcut handling implementation
rg -A 5 "useShortcutKeys|handleShortcut" apps/webapp/app/hooks/useShortcutKeys.tsx

# Look for platform-specific modifier key handling
rg -A 5 "isMac|isWindows|platform" apps/webapp/app/hooks/useShortcutKeys.tsx apps/webapp/app/components/primitives/ShortcutKey.tsx

# Check for any keyboard event handling
rg -A 5 "keydown|keyup|keypress" apps/webapp/app/hooks/useShortcutKeys.tsx

Length of output: 5001

apps/webapp/app/components/runs/v3/BatchFilters.tsx (1)

403-403: LGTM: Improved cross-platform shortcut compatibility

The change from "meta" to "mod" modifier enhances cross-platform compatibility by automatically mapping to the appropriate key (Command on macOS, Control on Windows/Linux).

apps/webapp/app/routes/storybook.buttons/route.tsx (1)

Line range hint 73-85: LGTM: Consistent shortcut modifier updates

The shortcut modifiers have been consistently updated from "meta" to "mod" across all button variants in both small and medium sizes, maintaining a uniform cross-platform experience.

Also applies to: 196-208

apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.schedules.new/route.tsx (1)

396-396: LGTM: Consistent shortcut modifier update

The change from "meta" to "mod" aligns with the cross-platform compatibility improvements seen across other components.

apps/webapp/app/components/runs/v3/RunFilters.tsx (1)

Line range hint 807-811: LGTM! Keyboard shortcut improvements look good.

The changes consistently update the shortcuts across all ID filter dropdowns to use the "mod" modifier key with Enter, which aligns with the PR objectives of improving keyboard shortcuts. The enabledOnInputElements: true ensures the shortcuts work even when typing in input fields.

Let's verify that no other dropdowns in the file need similar shortcut updates:

Also applies to: 925-929, 1043-1047

✅ Verification successful

LGTM! The keyboard shortcut modifications are consistent with the codebase patterns.

After analyzing the codebase, I can confirm that:

  1. The changes to use mod+Enter with enabledOnInputElements: true in the ID filter dropdowns are consistent with other similar components in the codebase.
  2. The modifications align with the existing keyboard shortcut patterns used throughout the application, particularly in other filter and dialog components.
  3. No other dropdown components in the RunFilters.tsx file need similar updates, as all relevant components have been properly modified.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other potential dropdown components that might need shortcut updates
ast-grep --pattern 'shortcut = {
  $$$
}'

Length of output: 43


Script:

#!/bin/bash
# Let's try a different pattern to search for keyboard shortcut configurations
rg -U "modifiers.*key.*Enter" --type tsx

Length of output: 70


Script:

#!/bin/bash
# Search for any dropdown components that might have keyboard shortcuts
ast-grep --pattern 'Dropdown {
  $$$
}'

Length of output: 41


Script:

#!/bin/bash
# Search for shortcut configurations with a more flexible pattern
rg -U "shortcut.*=.*{" -A 5 --type tsx

Length of output: 132


Script:

#!/bin/bash
# Let's try searching with correct file extension and fixed regex
rg -U "modifiers.*key.*Enter" --type ts --type tsx

# Also search for shortcut configurations with proper regex
rg -U "shortcut\s*=\s*\{" -A 5 --type ts --type tsx

# Search for dropdown components in TypeScript/React files
rg -U "Dropdown" --type ts --type tsx

Length of output: 228


Script:

#!/bin/bash
# Search for keyboard shortcut configurations without file type restrictions
rg -U "modifiers.*key.*Enter"

# Search for shortcut configurations
rg -U "shortcut\s*=\s*\{"

Length of output: 22279

apps/webapp/app/components/runs/v3/RetryDeploymentIndexingDialog.tsx (1)

51-51: LGTM! Platform-agnostic shortcut modifier

The change from "meta" to "mod" improves cross-platform compatibility, making the shortcut work consistently across different operating systems (Command on Mac, Ctrl on Windows/Linux).

apps/webapp/app/components/ListPagination.tsx (2)

36-38: LGTM! Intuitive keyboard navigation

The addition of 'k' for "Next" navigation follows vim-style conventions, and the tooltip improves discoverability.


59-61: LGTM! Consistent navigation pattern

The 'j' shortcut for "Previous" complements the 'k' shortcut, creating a familiar vim-style navigation pattern.

apps/webapp/app/components/ErrorDisplay.tsx (1)

52-52: LGTM! Intuitive "go to" shortcut

The "mod + g" shortcut is a logical choice for navigation to homepage/destination, and the change to "mod" improves cross-platform compatibility.

Let's check for potential shortcut conflicts:

✅ Verification successful

No shortcut conflicts found with mod+g, change is safe

Based on the search results, the "mod+g" shortcut is only used once in the codebase (in ErrorDisplay.tsx) and doesn't conflict with any other keyboard shortcuts. The other "mod" shortcuts found are using different keys (primarily "enter"), making this a safe and unique shortcut choice for homepage navigation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other mod+g shortcuts in the codebase
rg -i "shortcut.*mod.*[\"']g[\"']" --type=typescript --type=javascript

Length of output: 111


Script:

#!/bin/bash
# Search for keyboard shortcuts in the codebase using ripgrep
# Note: Removing typescript/javascript type filtering as it's not supported
rg -i "shortcut.*mod.*[\"']g[\"']"

Length of output: 138


Script:

#!/bin/bash
# Search for any keyboard shortcuts to identify potential conflicts
rg -i "shortcut.*[\"']mod[\"'].*key"

Length of output: 1107


Script:

#!/bin/bash
# Find all TypeScript/JavaScript files that might contain shortcuts
fd "\.(ts|tsx|js|jsx)$" -x rg -i "shortcut.*key"

Length of output: 10763

</span>
);
}

function keyString(key: String, isMac: boolean, size: "small" | "medium") {
function keyString(key: String, isMac: boolean, variant: "small" | "medium" | "medium/bright") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix the String type to follow TypeScript best practices

The static analysis correctly identified the use of String instead of string.

-function keyString(key: String, isMac: boolean, variant: "small" | "medium" | "medium/bright") {
+function keyString(key: string, isMac: boolean, variant: "small" | "medium" | "medium/bright") {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function keyString(key: String, isMac: boolean, variant: "small" | "medium" | "medium/bright") {
function keyString(key: string, isMac: boolean, variant: "small" | "medium" | "medium/bright") {
🧰 Tools
🪛 Biome (1.9.4)

[error] 46-46: Don't use 'String' as a type.

Use lowercase primitives for consistency.
Safe fix: Use 'string' instead

(lint/complexity/noBannedTypes)

Comment on lines +291 to +302
if (shortcut && showTooltip) {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>{buttonContent}</TooltipTrigger>
<TooltipContent className="text-dimmed flex items-center gap-3 py-1.5 pl-2.5 pr-3 text-xs">
{tooltipDescription} {renderShortcutKey()}
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Handle undefined 'tooltipDescription' in tooltip rendering

In the ButtonContent component, when rendering the tooltip content, tooltipDescription may be undefined if not provided. To prevent displaying 'undefined' in the tooltip, consider providing a default value or conditionally rendering the tooltip content.

Modify the tooltip rendering logic as follows:

 <TooltipContent className="text-dimmed flex items-center gap-3 py-1.5 pl-2.5 pr-3 text-xs">
-  {tooltipDescription} {renderShortcutKey()}
+  {tooltipDescription && <span>{tooltipDescription}</span>} {renderShortcutKey()}
 </TooltipContent>

This change ensures that the tooltip content is only rendered when tooltipDescription is defined.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (shortcut && showTooltip) {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>{buttonContent}</TooltipTrigger>
<TooltipContent className="text-dimmed flex items-center gap-3 py-1.5 pl-2.5 pr-3 text-xs">
{tooltipDescription} {renderShortcutKey()}
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}
if (shortcut && showTooltip) {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>{buttonContent}</TooltipTrigger>
<TooltipContent className="text-dimmed flex items-center gap-3 py-1.5 pl-2.5 pr-3 text-xs">
{tooltipDescription && <span>{tooltipDescription}</span>} {renderShortcutKey()}
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}

Comment on lines +176 to +180
showTooltip?: boolean;
variant: keyof typeof variant;
shortcutPosition?: "before-trailing-icon" | "after-trailing-icon";
tooltipDescription?: string;
iconSpacing?: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ensure 'tooltipDescription' is provided when 'showTooltip' is true

When showTooltip is true, tooltipDescription is used to render the tooltip content. If tooltipDescription is undefined, it may result in displaying 'undefined' in the tooltip. Consider making tooltipDescription required when showTooltip is true to prevent this issue.

Apply this diff to update the type definition:

 export type ButtonContentPropsType = {
   // existing props
   showTooltip?: boolean;
-  tooltipDescription?: string;
+  tooltipDescription?: string;
 } & (
+  showTooltip extends true ? { tooltipDescription: string } : {}
 );

This change will enforce that tooltipDescription is provided whenever showTooltip is true.

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines 10 to 14
{ key: "f", modifiers: ["mod"] },
{ key: "k", modifiers: ["mod"] },
{ key: "del", modifiers: ["ctrl", "alt"] },
{ key: "enter", modifiers: ["meta"] },
{ key: "enter", modifiers: ["mod"] },
{ key: "enter", modifiers: ["mod"] },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove duplicate shortcut definition

There appears to be a duplicate definition for the enter key with the same modifiers.

  { key: "f", modifiers: ["mod"] },
  { key: "k", modifiers: ["mod"] },
  { key: "del", modifiers: ["ctrl", "alt"] },
- { key: "enter", modifiers: ["mod"] },
  { key: "enter", modifiers: ["mod"] },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{ key: "f", modifiers: ["mod"] },
{ key: "k", modifiers: ["mod"] },
{ key: "del", modifiers: ["ctrl", "alt"] },
{ key: "enter", modifiers: ["meta"] },
{ key: "enter", modifiers: ["mod"] },
{ key: "enter", modifiers: ["mod"] },
{ key: "f", modifiers: ["mod"] },
{ key: "k", modifiers: ["mod"] },
{ key: "del", modifiers: ["ctrl", "alt"] },
{ key: "enter", modifiers: ["mod"] },

Comment on lines +76 to +77
<ShortcutKey shortcut={{ key: "c" }} variant="medium/bright" />
</Shortcut>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Potential shortcut key conflict

The 'c' key is used for both "Bulk action: Cancel runs" in the Runs page section and "Context" in the Run page section. This might lead to confusion or unexpected behavior depending on the current page context.

Consider using different keys or adding modifiers to differentiate these actions.

Also applies to: 79-80, 97-98

Comment on lines +19 to +31
<Button
variant="small-menu-item"
LeadingIcon={Keyboard}
leadingIconClassName="text-blue-500"
data-action="shortcuts"
fullWidth
textAlignLeft
shortcut={{ modifiers: ["shift"], key: "?" }}
className="gap-x-0 pl-0.5"
iconSpacing="gap-x-0.5"
>
Shortcuts
</Button>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add aria-label to improve accessibility

The shortcuts button should have an aria-label for better screen reader support.

 <Button
   variant="small-menu-item"
   LeadingIcon={Keyboard}
   leadingIconClassName="text-blue-500"
   data-action="shortcuts"
+  aria-label="Open keyboard shortcuts panel"
   fullWidth
   textAlignLeft
   shortcut={{ modifiers: ["shift"], key: "?" }}
   className="gap-x-0 pl-0.5"
   iconSpacing="gap-x-0.5"
 >
   Shortcuts
 </Button>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Button
variant="small-menu-item"
LeadingIcon={Keyboard}
leadingIconClassName="text-blue-500"
data-action="shortcuts"
fullWidth
textAlignLeft
shortcut={{ modifiers: ["shift"], key: "?" }}
className="gap-x-0 pl-0.5"
iconSpacing="gap-x-0.5"
>
Shortcuts
</Button>
<Button
variant="small-menu-item"
LeadingIcon={Keyboard}
leadingIconClassName="text-blue-500"
data-action="shortcuts"
aria-label="Open keyboard shortcuts panel"
fullWidth
textAlignLeft
shortcut={{ modifiers: ["shift"], key: "?" }}
className="gap-x-0 pl-0.5"
iconSpacing="gap-x-0.5"
>
Shortcuts
</Button>

Copy link

pkg-pr-new bot commented Dec 17, 2024

@trigger.dev/build

npm i https://pkg.pr.new/triggerdotdev/trigger.dev/@trigger.dev/build@1573

trigger.dev

npm i https://pkg.pr.new/triggerdotdev/trigger.dev@1573

@trigger.dev/react-hooks

npm i https://pkg.pr.new/triggerdotdev/trigger.dev/@trigger.dev/react-hooks@1573

@trigger.dev/core

npm i https://pkg.pr.new/triggerdotdev/trigger.dev/@trigger.dev/core@1573

@trigger.dev/rsc

npm i https://pkg.pr.new/triggerdotdev/trigger.dev/@trigger.dev/rsc@1573

@trigger.dev/sdk

npm i https://pkg.pr.new/triggerdotdev/trigger.dev/@trigger.dev/sdk@1573

commit: ba16fcc

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
apps/webapp/app/components/primitives/ShortcutKey.tsx (1)

56-56: ⚠️ Potential issue

Use lowercase 'string' instead of 'String'.
This was flagged in a previous review as well. TypeScript best practices recommend using the primitive “string” rather than the wrapper type “String” to avoid potential pitfalls.

-function keyString(key: String, isMac: boolean, variant: "small" | "medium" | "medium/bright") {
+function keyString(key: string, isMac: boolean, variant: "small" | "medium" | "medium/bright") {
🧰 Tools
🪛 Biome (1.9.4)

[error] 56-56: Don't use 'String' as a type.

Use lowercase primitives for consistency.
Safe fix: Use 'string' instead

(lint/complexity/noBannedTypes)

🧹 Nitpick comments (2)
apps/webapp/app/components/primitives/ShortcutKey.tsx (1)

59-59: Tailwind class name usage.
Dynamically setting the icon class size (“w-2.5 h-4” vs. “w-3 h-5”) is a good pattern to ensure consistent styling across variants.

apps/webapp/app/assets/icons/KeyboardUpIcon.tsx (1)

1-17: Consider a more scalable architecture for icon components.

Given that we now have three nearly identical keyboard arrow icons (Up, Down, Right) with the only difference being the path data, this is a perfect opportunity to implement a more maintainable architecture.

Consider this approach:

  1. Create a shared base icon component as suggested earlier
  2. Create an enum or constant for different arrow directions
  3. Create a single KeyboardArrowIcon component that accepts a direction prop

Example implementation:

export enum ArrowDirection {
  UP = 'up',
  DOWN = 'down',
  RIGHT = 'right'
}

const ARROW_PATHS = {
  [ArrowDirection.UP]: "M11.1221 6.60947C11.5011...",
  [ArrowDirection.DOWN]: "M12.8779 16.3905C12.4989...",
  [ArrowDirection.RIGHT]: "M16.3905 11.1221C17.0854..."
};

interface KeyboardArrowIconProps {
  className?: string;
  direction: ArrowDirection;
}

export function KeyboardArrowIcon({ className, direction }: KeyboardArrowIconProps) {
  return (
    <BaseIcon 
      className={className}
      ariaLabel={`Keyboard ${direction} arrow`}
    >
      <path
        d={ARROW_PATHS[direction]}
        fill="currentColor"
      />
    </BaseIcon>
  );
}

This approach would:

  • Reduce code duplication
  • Make it easier to add new arrow directions
  • Maintain consistency across arrow icons
  • Improve maintainability
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 72d1381 and e4446b2.

📒 Files selected for processing (8)
  • apps/webapp/app/assets/icons/KeyboardDownIcon.tsx (1 hunks)
  • apps/webapp/app/assets/icons/KeyboardLeftIcon.tsx (1 hunks)
  • apps/webapp/app/assets/icons/KeyboardRightIcon.tsx (1 hunks)
  • apps/webapp/app/assets/icons/KeyboardUpIcon.tsx (1 hunks)
  • apps/webapp/app/assets/icons/KeyboardWindowsIcon.tsx (1 hunks)
  • apps/webapp/app/components/Shortcuts.tsx (1 hunks)
  • apps/webapp/app/components/primitives/ShortcutKey.tsx (2 hunks)
  • apps/webapp/app/routes/storybook.shortcuts/route.tsx (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/webapp/app/assets/icons/KeyboardWindowsIcon.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/webapp/app/routes/storybook.shortcuts/route.tsx
  • apps/webapp/app/components/Shortcuts.tsx
🧰 Additional context used
🪛 Biome (1.9.4)
apps/webapp/app/components/primitives/ShortcutKey.tsx

[error] 56-56: Don't use 'String' as a type.

Use lowercase primitives for consistency.
Safe fix: Use 'string' instead

(lint/complexity/noBannedTypes)

🔇 Additional comments (12)
apps/webapp/app/components/primitives/ShortcutKey.tsx (8)

1-5: Imports of new keyboard icons look good.
The imported files appear consistent in naming and usage, and each icon is likely being used in the relevant switch statements below.


10-11: Variants object and “medium” constant.
Declaring "medium" as a separate constant and then including it in the variants object is a neat approach that keeps your code DRY. The introduction of "medium/bright" also follows a straightforward pattern using the existing "medium" variant plus additional Tailwind classes. Everything here looks consistent and clear.

Also applies to: 15-17


22-30: ShortcutKeyDefinition refactor.
Defining separate windows/mac shortcut properties provides more flexibility. This is a clean approach for multi-platform support. Great job!


32-32: Prop consistency.
The updated prop type for “shortcut” (now using ShortcutKeyDefinition) aligns well with the multi-platform structure.


42-42: Deriving the character.
Using a helper function (keyString) to convert the raw key into an icon or string is a nice way to keep ShortcutKey clean and modular.


47-49: Rendering modifiers.
Splitting each modifier into its own ensures clarity and easy styling of individual segments. The approach is concise and maintains readability.

Also applies to: 51-51


63-67: Switching to icons vs. text for special keys.
Replacing arrow keys with brand-new icon components and returning textual fallback for “Enter”, “Esc”, etc. is a pleasing approach to keep the look consistent while preserving clarity. No issues here.

Also applies to: 69-75


81-98: Enhanced platform-conditional modifiers.
Using a single “mod” that translates into either Cmd or Ctrl is especially helpful for cross-platform consistency. Returning different JSX elements for Windows vs. Mac is done cleanly. Good work!

apps/webapp/app/assets/icons/KeyboardRightIcon.tsx (1)

1-17: Apply the same accessibility and reusability improvements.

This component has the same structure as KeyboardDownIcon and would benefit from the same improvements suggested in that review.

apps/webapp/app/assets/icons/KeyboardLeftIcon.tsx (3)

1-1: LGTM! Clean TypeScript props interface.

The component has a well-defined TypeScript interface with an optional className prop.


11-14: LGTM! Well-structured SVG path.

The path element is well-defined with a precise shape and uses currentColor for dynamic coloring.


1-17: Verify icon usage in the shortcut panel.

Since this icon is part of the keyboard shortcuts improvements, let's verify its integration.

✅ Verification successful

Icon is properly integrated in the keyboard shortcuts system

The KeyboardLeftIcon is correctly integrated into the ShortcutKey component and is used specifically for displaying the left arrow key (arrowleft) in keyboard shortcuts. The implementation is consistent with other directional keyboard icons (up, down, right) and follows the established pattern for keyboard shortcut visualization. The icon is rendered with appropriate sizing based on the variant (small: "w-2.5 h-4" or medium: "w-3 h-5").

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check how the KeyboardLeftIcon is used in the shortcut panel and related components

# Find files that import or use KeyboardLeftIcon
rg -l "KeyboardLeftIcon" --type tsx --type ts

# Look for shortcut panel related components that might use this icon
rg -l "shortcut.*panel|keyboard.*shortcut" --type tsx --type ts

# Check for any existing keyboard icon patterns
ast-grep --pattern 'import { $_ } from "$_/icons/Keyboard$_Icon"'

Length of output: 235


Script:

#!/bin/bash
# Let's try different search approaches without file type restrictions

# Find files that import or use KeyboardLeftIcon
rg -l "KeyboardLeftIcon"

# Look for shortcut panel related components
rg -l "shortcut.*panel|keyboard.*shortcut"

# Search for SVG path pattern specific to this icon
rg "7\.60947 12\.8779.*7\.60947 11\.1221"

# Look for files containing keyboard-related components
rg -l "keyboard|Keyboard" --type ts --type jsx --type tsx

Length of output: 632


Script:

#!/bin/bash
# Let's examine the ShortcutKey component that uses this icon
cat apps/webapp/app/components/primitives/ShortcutKey.tsx

# Also check the content of any test files related to shortcuts
fd "shortcut.*\.(test|spec)\.(ts|tsx)"

# Look for keyboard-related components without file type restrictions
rg -l "keyboard|Keyboard"

Length of output: 4487

Comment on lines +1 to +17
export function KeyboardDownIcon({ className }: { className?: string }) {
return (
<svg
className={className}
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12.8779 16.3905C12.4989 17.0854 11.5011 17.0854 11.1221 16.3905L6.80665 8.47885C6.44317 7.81248 6.92548 7 7.68454 7L16.3155 7C17.0745 7 17.5568 7.81248 17.1934 8.47885L12.8779 16.3905Z"
fill="currentColor"
/>
</svg>
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add accessibility attributes and consider component reusability.

While the implementation is clean, there are a few improvements that could enhance accessibility and maintainability:

  1. Add ARIA attributes for better accessibility
  2. Consider creating a base icon component to reduce duplication across similar icon components
 export function KeyboardDownIcon({ className }: { className?: string }) {
   return (
     <svg
       className={className}
       width="24"
       height="24"
       viewBox="0 0 24 24"
       fill="none"
       xmlns="http://www.w3.org/2000/svg"
+      role="img"
+      aria-label="Keyboard down arrow"
     >
       <path
         d="M12.8779 16.3905C12.4989 17.0854 11.5011 17.0854 11.1221 16.3905L6.80665 8.47885C6.44317 7.81248 6.92548 7 7.68454 7L16.3155 7C17.0745 7 17.5568 7.81248 17.1934 8.47885L12.8779 16.3905Z"
         fill="currentColor"
       />
     </svg>
   );
 }

Consider creating a base icon component:

interface BaseIconProps {
  className?: string;
  ariaLabel: string;
  children: React.ReactNode;
}

function BaseIcon({ className, ariaLabel, children }: BaseIconProps) {
  return (
    <svg
      className={className}
      width="24"
      height="24"
      viewBox="0 0 24 24"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
      role="img"
      aria-label={ariaLabel}
    >
      {children}
    </svg>
  );
}

Comment on lines +3 to +10
<svg
className={className}
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add ARIA attributes for better accessibility.

The SVG icon should include ARIA attributes to improve accessibility for screen readers.

Apply this diff:

 <svg
   className={className}
   width="24"
   height="24"
   viewBox="0 0 24 24"
   fill="none"
   xmlns="http://www.w3.org/2000/svg"
+  aria-hidden="true"
+  role="img"
+  aria-label="Left keyboard arrow"
 >

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (6)
apps/webapp/app/components/primitives/ShortcutKey.tsx (4)

20-20: Consider using a literal union type for better type safety

Instead of using keyof typeof variants, consider explicitly defining the variant types for better type safety and autocompletion.

-export type ShortcutKeyVariant = keyof typeof variants;
+export type ShortcutKeyVariant = "small" | "medium" | "medium/bright";

46-50: Consider memoizing modifier strings for better performance

The modifier strings are recalculated on every render. Consider memoizing them using useMemo if the component rerenders frequently.

+const memoizedModifiers = React.useMemo(
+  () =>
+    modifiers.map((k) => (
+      <span key={k}>
+        <span>{modifierString(k, isMac, variant)}</span>
+      </span>
+    )),
+  [modifiers, isMac, variant]
+);

 return (
   <span className={cn(variants[variant], className)}>
-    {modifiers.map((k) => (
-      <span key={k}>
-        <span>{modifierString(k, isMac, variant)}</span>
-      </span>
-    ))}
+    {memoizedModifiers}
     {character && <span>{character}</span>}
   </span>
 );

81-85: Extract shared variant type to avoid duplication

The variant type is duplicated in both helper functions. Consider extracting it to a shared type.

+type ShortcutKeyVariantType = "small" | "medium" | "medium/bright";

-function keyString(key: string, isMac: boolean, variant: "small" | "medium" | "medium/bright")
+function keyString(key: string, isMac: boolean, variant: ShortcutKeyVariantType)

-function modifierString(modifier: Modifier, isMac: boolean, variant: "small" | "medium" | "medium/bright")
+function modifierString(modifier: Modifier, isMac: boolean, variant: ShortcutKeyVariantType)

Also applies to: 56-56


88-99: Add exhaustive type checking for modifiers

Consider adding exhaustive type checking to ensure all modifier cases are handled.

 function modifierString(
   modifier: Modifier,
   isMac: boolean,
   variant: ShortcutKeyVariantType
 ): string | JSX.Element {
   const className = variant === "small" ? "w-2.5 h-4" : "w-3.5 h-5";

   switch (modifier) {
     case "alt":
       return isMac ? "⌥" : <span className="capitalize">Alt</span>;
     case "ctrl":
       return isMac ? "⌃" : <span className="capitalize">Ctrl</span>;
     case "meta":
       return isMac ? "⌘" : <KeyboardWindowsIcon className={className} />;
     case "shift":
       return "⇧";
     case "mod":
       return isMac ? "⌘" : <span className="capitalize">Ctrl</span>;
+    default: {
+      const exhaustiveCheck: never = modifier;
+      throw new Error(`Unhandled modifier case: ${exhaustiveCheck}`);
+    }
   }
 }
apps/webapp/app/components/Shortcuts.tsx (2)

63-68: Consider adding helper text for vim-style navigation

While 'j' and 'k' are common in vim-style navigation, consider adding helper text to make it more intuitive for users unfamiliar with this convention.

Add a small description like "(vim-style)" next to these shortcuts.


141-148: Enhance type safety for the Shortcut component

Consider using a more specific type for the children prop to ensure only valid shortcut-related components are passed.

-function Shortcut({ children, name }: { children: React.ReactNode; name: string }) {
+type ShortcutProps = {
+  children: React.ReactElement<typeof ShortcutKey> | React.ReactElement<typeof ShortcutKey>[];
+  name: string;
+};
+
+function Shortcut({ children, name }: ShortcutProps) {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4dcf218 and f8e97c6.

📒 Files selected for processing (2)
  • apps/webapp/app/components/Shortcuts.tsx (1 hunks)
  • apps/webapp/app/components/primitives/ShortcutKey.tsx (2 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
apps/webapp/app/components/primitives/ShortcutKey.tsx

[error] 56-56: Don't use 'String' as a type.

Use lowercase primitives for consistency.
Safe fix: Use 'string' instead

(lint/complexity/noBannedTypes)

🔇 Additional comments (4)
apps/webapp/app/components/primitives/ShortcutKey.tsx (1)

56-56: Fix the String type to follow TypeScript best practices

The primitive type should be lowercase for consistency.

-function keyString(key: String, isMac: boolean, variant: "small" | "medium" | "medium/bright") {
+function keyString(key: string, isMac: boolean, variant: "small" | "medium" | "medium/bright") {
🧰 Tools
🪛 Biome (1.9.4)

[error] 56-56: Don't use 'String' as a type.

Use lowercase primitives for consistency.
Safe fix: Use 'string' instead

(lint/complexity/noBannedTypes)

apps/webapp/app/components/Shortcuts.tsx (3)

19-31: Add aria-label to improve accessibility

The shortcuts button should have an aria-label for better screen reader support.


76-77: Potential shortcut key conflict with 'c'

The 'c' key is used for both "Bulk action: Cancel runs" and "Context", which might lead to confusion.

Also applies to: 97-98


15-139: Implementation aligns well with PR objectives

The code successfully implements:

  1. A new shortcut panel accessible via the Help & Feedback popover
  2. Pagination navigation using 'j' and 'k' keys

The overall structure is clean and well-organized.

Comment on lines +79 to +80
<ShortcutKey shortcut={{ key: "r" }} variant="medium/bright" />
</Shortcut>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Potential shortcut key conflict with 'r'

The 'r' key is used for both "Bulk action: Replay runs" and "Replay run", which might lead to confusion.

Consider adding modifiers (e.g., Shift or Alt) to differentiate these actions.

Also applies to: 88-89

Comment on lines +124 to +126
<Shortcut name="New schedule">
<ShortcutKey shortcut={{ key: "n" }} variant="medium/bright" />
</Shortcut>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Potential shortcut key conflict with 'n'

The 'n' key is used for both "New schedule" and "New alert". This could cause confusion when users try to create new items.

Consider:

  1. Adding page-specific modifiers
  2. Using different keys for each action
  3. Implementing a context-aware shortcut system

Also applies to: 130-132

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant