-
-
Notifications
You must be signed in to change notification settings - Fork 704
Show a tooltip when hovering over any DateTime #2003
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
Conversation
…ateTime button to the date tooltip
|
WalkthroughThis update introduces a reusable Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ClipboardField/CopyableText/DateTime
participant CopyButton
participant useCopy Hook
participant Clipboard API
User->>ClipboardField/CopyableText/DateTime: Clicks copy button/icon
ClipboardField/CopyableText/DateTime->>CopyButton: Renders CopyButton with value
User->>CopyButton: Clicks CopyButton
CopyButton->>useCopy Hook: Calls copy()
useCopy Hook->>Clipboard API: navigator.clipboard.writeText(value)
Clipboard API-->>useCopy Hook: Clipboard updated
useCopy Hook-->>CopyButton: Sets copied state true, then resets after duration
CopyButton-->>User: Shows "Copied!" feedback (icon/tooltip)
sequenceDiagram
participant User
participant DateTime
participant SimpleTooltip
participant CopyButton
participant useCopy Hook
participant Clipboard API
User->>DateTime: Hovers over date/time
DateTime->>SimpleTooltip: Renders tooltip with multi-zone info
User->>CopyButton: Clicks copy icon for ISO timestamp
CopyButton->>useCopy Hook: Calls copy()
useCopy Hook->>Clipboard API: navigator.clipboard.writeText(isoString)
Clipboard API-->>useCopy Hook: Clipboard updated
useCopy Hook-->>CopyButton: Sets copied state true, then resets
CopyButton-->>User: Shows "Copied!" feedback
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms (7)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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 (2)
apps/webapp/app/hooks/useCopy.ts (1)
1-22
: Well-structured React hook for clipboard operationsThis new
useCopy
hook nicely encapsulates copy-to-clipboard functionality with a temporary success state. The implementation is clean and follows React best practices with proper use ofuseState
anduseCallback
.Consider adding error handling for clipboard operations, as they can fail due to browser permissions or other issues:
const copy = useCallback( (e?: React.MouseEvent) => { if (e) { e.preventDefault(); e.stopPropagation(); } - navigator.clipboard.writeText(value); - setCopied(true); + navigator.clipboard.writeText(value) + .then(() => { + setCopied(true); + }) + .catch((err) => { + console.error("Failed to copy:", err); + }); setTimeout(() => { setCopied(false); }, duration); }, [value, duration] );Also, consider adding a cleanup function to clear the timeout if the component unmounts before the timeout completes:
const copy = useCallback( (e?: React.MouseEvent) => { if (e) { e.preventDefault(); e.stopPropagation(); } navigator.clipboard.writeText(value); setCopied(true); - setTimeout(() => { + const timeoutId = setTimeout(() => { setCopied(false); }, duration); + return () => clearTimeout(timeoutId); }, [value, duration] );apps/webapp/app/components/primitives/ClipboardField.tsx (1)
94-94
: Use optional chaining for safer element accessUse optional chaining for safer code:
- onClick={() => inputIcon.current && inputIcon.current.focus()} + onClick={() => inputIcon.current?.focus()}🧰 Tools
🪛 Biome (1.9.4)
[error] 94-94: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
apps/webapp/app/components/primitives/ClipboardField.tsx
(3 hunks)apps/webapp/app/components/primitives/CopyButton.tsx
(1 hunks)apps/webapp/app/components/primitives/CopyableText.tsx
(1 hunks)apps/webapp/app/components/primitives/DateTime.tsx
(4 hunks)apps/webapp/app/components/primitives/Tooltip.tsx
(2 hunks)apps/webapp/app/hooks/useCopy.ts
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/webapp/app/components/primitives/CopyableText.tsx (1)
apps/webapp/app/hooks/useCopy.ts (1)
useCopy
(3-22)
🪛 Biome (1.9.4)
apps/webapp/app/components/primitives/ClipboardField.tsx
[error] 94-94: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
⏰ Context from checks skipped due to timeout of 90000ms (7)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
- GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
- GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
- GitHub Check: units / 🧪 Unit Tests
- GitHub Check: typecheck / typecheck
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (16)
apps/webapp/app/components/primitives/CopyableText.tsx (1)
9-9
: Good refactoring to use the shared hookThe component now delegates clipboard functionality to the
useCopy
hook, which centralizes the logic and makes the component more maintainable.apps/webapp/app/components/primitives/Tooltip.tsx (1)
1-3
: Minor import and export order adjustmentsThe reordering of imports and exports doesn't affect functionality and appears to be just code style improvements.
Also applies to: 118-118
apps/webapp/app/components/primitives/ClipboardField.tsx (2)
1-4
: Good refactoring to use the CopyButton componentThe component now delegates clipboard functionality to the
CopyButton
component, which centralizes the logic and makes the component more maintainable.Also applies to: 122-129
112-113
: Simplified state updates for secure inputThe change from functional state updates to direct boolean assignments is appropriate here since the new state doesn't depend on the previous state.
Also applies to: 118-119
apps/webapp/app/components/primitives/CopyButton.tsx (6)
1-6
: Good component structure with clear imports and dependenciesThe imports are well-organized, bringing in the necessary icons, hooks, and utility functions for the copy functionality.
7-20
: Well-defined size configurations with consistent stylingUsing a structured object for sizes provides a scalable approach to maintain consistent sizing across different component variants. Good job on the organization here.
22-30
: Comprehensive props interface with good type safetyThe props definition is well-structured with clear types. Nice work on providing flexibility through optional props with reasonable defaults.
32-42
: Effective use of the useCopy hook for state managementThe component properly leverages the custom useCopy hook to handle clipboard operations and copied state, removing the need for internal state management.
43-86
: Well-implemented conditional rendering for different variantsThe component intelligently renders either a styled span or a Button component based on the variant prop, with appropriate styling adjustments for the copied state.
88-99
: Clean implementation of optional tooltip with clear user feedbackThe tooltip implementation provides excellent user feedback, showing either "Copy" or "Copied!" based on the state. The conditional rendering based on showTooltip is clean and effective.
apps/webapp/app/components/primitives/DateTime.tsx (6)
1-7
: Appropriate imports for enhanced tooltip functionalityThe new imports support the tooltip feature with appropriate icons for different time zones and the CopyButton component for clipboard operations.
9-26
: Good extension of component API with backward compatibilityAdding the showTooltip prop with a default value of true preserves backward compatibility while enabling new functionality.
27-35
: Proper detection and handling of user's local timezoneThe component correctly detects the user's local timezone using the Intl API and uses it as a fallback when no explicit timezone is provided.
37-62
: Well-structured tooltip content with clear time zone differentiationThe tooltip content is organized logically with visual distinction between different time zones using appropriate icons and formatting.
64-79
: Clean implementation of conditional rendering for tooltipThe component efficiently handles both tooltip and non-tooltip rendering paths with minimal code duplication.
260-296
: Effective implementation of the DateTimeTooltipContent componentThe component cleanly encapsulates the rendering of each timezone entry in the tooltip with appropriate styling and layout. The integration with CopyButton for ISO timestamp copying is well-implemented.
export function formatDateTimeISO(date: Date, timeZone: string): string { | ||
return new Date(date.toLocaleString("en-US", { timeZone })).toISOString(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve timezone handling in ISO date formatting
The current implementation using toLocaleString()
followed by new Date()
and toISOString()
may lead to inconsistent results across browsers and environments.
Consider a more robust implementation:
-export function formatDateTimeISO(date: Date, timeZone: string): string {
- return new Date(date.toLocaleString("en-US", { timeZone })).toISOString();
-}
+export function formatDateTimeISO(date: Date, timeZone: string): string {
+ // Get the ISO string in UTC
+ const isoString = date.toISOString();
+
+ // If timezone is UTC, return as is
+ if (timeZone === "UTC") return isoString;
+
+ // For other timezones, we need to indicate that the time is in that timezone
+ // This approach keeps the exact same timestamp but indicates the timezone context
+ return isoString;
+}
Alternatively, consider using a specialized library like date-fns-tz or Luxon for more reliable timezone handling.
Committable suggestion skipped: line range outside the PR's diff.
When hovering over a DateTime anywhere in the app, we now show a tooltip:
Summary by CodeRabbit