Skip to content

[WEB-3374]feat: added merge date display #7141

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

Open
wants to merge 3 commits into
base: preview
Choose a base branch
from

Conversation

vamsikrishnamathala
Copy link
Member

@vamsikrishnamathala vamsikrishnamathala commented May 30, 2025

Description

This PR merge start date and due date into a single component in work items, cycles and modules list.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Screenshots and Media (if applicable)

Date type Preview
Single Date image
Dates in same month image
Dates in different months image
Dates in different years image

Summary by CodeRabbit

  • New Features

    • Introduced a merged date range display for selecting and viewing start and end dates as a single element in various components.
    • Added a clear (reset) button to the date range picker, allowing users to quickly remove selected dates.
  • Improvements

    • Consolidated separate start and due date pickers into a unified date range picker in issue and sub-issue properties, providing a streamlined user experience.
    • Enhanced date formatting for merged date ranges to display concise, human-readable strings.
  • Bug Fixes

    • Removed unused icons and imports for improved performance and maintainability.

Copy link
Contributor

coderabbitai bot commented May 30, 2025

Walkthrough

The changes introduce a new MergedDateDisplay component and enhance the DateRangeDropdown to support merged date display and a clearable date range. Multiple components are refactored to use these new features, consolidating date handling and display logic for improved consistency and maintainability.

Changes

Files/Groups Change Summary
web/core/components/dropdowns/merged-date.tsx Added new MergedDateDisplay component for concise, merged date range display.
web/core/components/dropdowns/date-range.tsx Enhanced DateRangeDropdown with mergeDates, isClearable, and clearIconClassName props; refactored UI.
web/core/components/dropdowns/index.ts Exported MergedDateDisplay via index.
web/core/components/cycles/analytics-sidebar/sidebar-header.tsx Added mergeDates prop to DateRangeDropdown; removed unused imports.
web/core/components/cycles/list/cycle-list-item-action.tsx Replaced inline date formatting with MergedDateDisplay; added mergeDates to dropdown.
web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/properties.tsx Replaced single date picker with merged date range dropdown; split update handlers.
web/core/components/issues/issue-layouts/properties/all-properties.tsx Unified start and due date into a single merged date range dropdown; refactored related logic and imports.
web/core/components/modules/module-list-item-action.tsx Added mergeDates prop to DateRangeDropdown.
packages/utils/src/datetime.ts Added formatDateRange utility function for context-aware date range formatting.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UIComponent
    participant DateRangeDropdown
    participant MergedDateDisplay

    User->>UIComponent: Interacts with date field
    UIComponent->>DateRangeDropdown: Render with mergeDates/isClearable
    DateRangeDropdown->>MergedDateDisplay: Display merged date range
    User->>DateRangeDropdown: Selects or clears date range
    DateRangeDropdown->>UIComponent: onSelect callback with new/empty range
Loading

Suggested labels

🌟improvement

Suggested reviewers

  • prateekshourya29
  • anmolsinghbhatia

Poem

In the warren where code and dates entwine,
A rabbit merged two fields into one line.
With a hop and a click, dates now appear—
Merged and clear, with a button to clear!
No more confusion, the range is in sight,
Thanks to this change, the future is bright!
🐇✨


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4836bc2 and e97edc1.

📒 Files selected for processing (1)
  • web/core/components/cycles/list/cycle-list-item-action.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/core/components/cycles/list/cycle-list-item-action.tsx
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Analyze (javascript)
✨ Finishing Touches
  • 📝 Generate Docstrings

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.

❤️ 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need 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)

  • @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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @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

makeplane bot commented May 30, 2025

Pull Request Linked with Plane Work Items

Comment Automatically Generated by Plane

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: 0

🧹 Nitpick comments (2)
web/core/components/dropdowns/merged-date.tsx (1)

28-72: Consider adding validation for date order and edge cases.

The formatting logic is solid, but there are a few edge cases to consider:

  1. Date order validation: The component doesn't validate if startDate is before endDate
  2. Same date scenario: When both dates are identical, it could show just one date instead of "Jan 24 - 24, 2025"
 const formatDateRange = (): string => {
   // If no dates are provided
   if (!parsedStartDate && !parsedEndDate) {
     return "";
   }

   // If only start date is provided
   if (parsedStartDate && !parsedEndDate) {
     return format(parsedStartDate, "MMM dd, yyyy");
   }

   // If only end date is provided
   if (!parsedStartDate && parsedEndDate) {
     return format(parsedEndDate, "MMM dd, yyyy");
   }

   // If both dates are provided
   if (parsedStartDate && parsedEndDate) {
+    // Handle same date scenario
+    if (parsedStartDate.getTime() === parsedEndDate.getTime()) {
+      return format(parsedStartDate, "MMM dd, yyyy");
+    }
+
     const startYear = parsedStartDate.getFullYear();
     const startMonth = parsedStartDate.getMonth();
     const endYear = parsedEndDate.getFullYear();
     const endMonth = parsedEndDate.getMonth();
     
     // Rest of the logic...
   }
 };
web/core/components/dropdowns/date-range.tsx (1)

195-204: Consider accessibility improvements for the clear button.

The clear functionality works well, but could benefit from accessibility enhancements:

 {isClearable && !disabled && hasDisplayedDates && (
   <X
     className={cn("h-2.5 w-2.5 flex-shrink-0 cursor-pointer", clearIconClassName)}
+    role="button"
+    aria-label="Clear date range"
+    tabIndex={0}
     onClick={(e) => {
       e.stopPropagation();
       e.preventDefault();
       clearDates();
     }}
+    onKeyDown={(e) => {
+      if (e.key === 'Enter' || e.key === ' ') {
+        e.stopPropagation();
+        e.preventDefault();
+        clearDates();
+      }
+    }}
   />
 )}

Also applies to: 228-237

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4a97d7c and 1e43af5.

📒 Files selected for processing (8)
  • web/core/components/cycles/analytics-sidebar/sidebar-header.tsx (2 hunks)
  • web/core/components/cycles/list/cycle-list-item-action.tsx (3 hunks)
  • web/core/components/dropdowns/date-range.tsx (6 hunks)
  • web/core/components/dropdowns/index.ts (1 hunks)
  • web/core/components/dropdowns/merged-date.tsx (1 hunks)
  • web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/properties.tsx (3 hunks)
  • web/core/components/issues/issue-layouts/properties/all-properties.tsx (3 hunks)
  • web/core/components/modules/module-list-item-action.tsx (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
web/core/components/cycles/list/cycle-list-item-action.tsx (1)
web/core/components/dropdowns/merged-date.tsx (1)
  • MergedDateDisplay (20-81)
web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/properties.tsx (3)
web/core/store/router.store.ts (2)
  • workspaceSlug (69-71)
  • issueId (149-151)
web/helpers/date-time.helper.ts (2)
  • renderFormattedPayloadDate (58-68)
  • getDate (277-293)
web/core/components/dropdowns/date-range.tsx (1)
  • DateRangeDropdown (63-285)
web/core/components/dropdowns/date-range.tsx (1)
web/core/components/dropdowns/merged-date.tsx (1)
  • MergedDateDisplay (20-81)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (20)
web/core/components/modules/module-list-item-action.tsx (1)

161-161: LGTM! Consistent implementation of merged dates feature.

The addition of the mergeDates prop to DateRangeDropdown is correctly implemented and consistent with the pattern used across other components in this PR.

web/core/components/dropdowns/index.ts (1)

6-6: LGTM! Necessary export for the new component.

The export statement correctly makes the MergedDateDisplay component available for use across the application.

web/core/components/cycles/list/cycle-list-item-action.tsx (3)

25-25: LGTM! Proper import for the new component.

The import statement correctly brings in the MergedDateDisplay component needed for the refactoring.


233-233: Excellent refactoring! Replaced inline formatting with reusable component.

The replacement of inline date formatting with the MergedDateDisplay component improves code maintainability and ensures consistent date formatting across the application. The component receives the correct startDate and endDate props.


270-270: LGTM! Consistent implementation of merged dates feature.

The addition of the mergeDates prop to DateRangeDropdown maintains consistency with the pattern implemented across other components in this PR.

web/core/components/cycles/analytics-sidebar/sidebar-header.tsx (3)

6-6: Good cleanup! Removed unused imports.

Cleaning up unused imports improves code maintainability and reduces bundle size.


11-11: Good cleanup! Removed unused imports.

Removing unused imports helps keep the codebase clean and maintainable.


233-233: LGTM! Consistent implementation of merged dates feature.

The addition of the mergeDates prop to DateRangeDropdown is correctly implemented and consistent with the pattern used across other components in this PR.

web/core/components/dropdowns/merged-date.tsx (1)

20-81: Excellent implementation with comprehensive date formatting logic!

The MergedDateDisplay component provides a clean and well-structured approach to displaying date ranges with smart formatting based on the relationship between start and end dates. The logic correctly handles all major scenarios and provides intuitive date displays.

web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/properties.tsx (4)

7-7: Clean import updates for the new component.

The import statement correctly adds DateRangeDropdown to replace the previous date handling approach.


39-53: Well-structured date handlers with proper validation.

The separate handlers for start and target dates are cleanly implemented with appropriate null checking and date formatting. The use of renderFormattedPayloadDate ensures consistent date format for API calls.


107-134: Excellent integration of merged date functionality.

The implementation successfully consolidates start and due date handling into a single component with several good practices:

  • Proper use of WithDisplayPropertiesHOC with multiple display property keys
  • Correct date range construction from issue properties
  • Appropriate button variant selection based on date presence
  • Good event propagation handling

The mergeDates prop and isClearable feature enhance the user experience significantly.


114-121:

✅ Verification successful

Verify the onSelect handler behavior with the DateRangeDropdown.

The onSelect handler assumes that the range object may have undefined values for from and to, but it's worth verifying that the DateRangeDropdown component handles partial selections correctly.


🏁 Script executed:

#!/bin/bash
# Description: Verify DateRangeDropdown onSelect behavior and type safety

# Search for DateRangeDropdown implementation to understand onSelect callback signature
ast-grep --pattern $'export const DateRangeDropdown: React.FC<Props> = (props) => {
  $$$
  onSelect: (range: DateRange | undefined) => void;
  $$$
}'

# Check for other usages of DateRangeDropdown onSelect to ensure consistency
rg -A 5 -B 2 "onSelect.*range"

Length of output: 2535


🏁 Script executed:

#!/bin/bash
# Inspect DateRange type definition
rg -nE "export (?:type|interface) DateRange" web/core/components/dropdowns/date-range.tsx
rg -nE -A3 -B3 "export (?:type|interface) DateRange" web/core/components/dropdowns/date-range.tsx

# Find where and how onSelect is invoked inside DateRangeDropdown
rg -n "props.onSelect" -n web/core/components/dropdowns/date-range.tsx
rg -n "onSelect\(" -n web/core/components/dropdowns/date-range.tsx

Length of output: 811


🏁 Script executed:

#!/bin/bash
# Locate DateRange type/interface in the dropdown component
rg -n "type DateRange" -n web/core/components/dropdowns/date-range.tsx
rg -n "interface DateRange" -n web/core/components/dropdowns/date-range.tsx

# Show the beginning of the file to inspect Props and onSelect invocation
sed -n '1,200p' web/core/components/dropdowns/date-range.tsx

Length of output: 6044


🏁 Script executed:

#!/bin/bash
# Locate Calendar usage to see onSelect handling inside DateRangeDropdown
rg -n "<Calendar" -n web/core/components/dropdowns/date-range.tsx

# Print lines around Calendar and apply/cancel buttons
sed -n '200,400p' web/core/components/dropdowns/date-range.tsx

Length of output: 3181


No issues found with DateRangeDropdown’s onSelect handling

The DateRangeDropdown simply forwards the DateRange | undefined value it receives from the underlying Calendar to its onSelect prop, and your handler correctly maps range?.from and range?.to (falling back to null) for both full and partial selections. No further changes are needed here.

web/core/components/issues/issue-layouts/properties/all-properties.tsx (3)

8-8: Clean import refactoring removes unused dependencies.

The import updates correctly remove unused icons (CalendarClock) and add the new DateRangeDropdown component while maintaining all necessary dependencies.

Also applies to: 24-24


307-337: Excellent consolidation of date handling logic.

The refactoring successfully merges separate start and due date dropdowns into a unified DateRangeDropdown with several improvements:

  • Maintains existing handleStartDate and handleTargetDate functions for proper event tracking
  • Correctly constructs date range from issue properties
  • Preserves button styling logic based on date presence
  • Retains existing conditional styling for overdue dates
  • Adds clearable functionality for better UX

The implementation maintains backward compatibility while providing enhanced functionality.


315-322:

✅ Verification successful

Verify date range selection behavior maintains existing functionality.

The unified date range selection approach looks correct, but ensure that the event tracking for individual date changes still works as expected since the events are captured separately in handleStartDate and handleTargetDate.


🏁 Script executed:

#!/bin/bash
# Description: Verify that date tracking events are still properly captured

# Search for ISSUE_UPDATED event usage in date handlers
rg -A 10 -B 5 "ISSUE_UPDATED.*start_date|ISSUE_UPDATED.*target_date"

# Check for any other date-related event tracking patterns
rg -A 5 "changed_property.*date"

Length of output: 2603


Date range selection: individual change events intact
Verified that both start_date and target_date analytics events are still emitted:

• web/core/components/issues/issue-layouts/properties/all-properties.tsx – changed_property: "start_date"
• web/core/components/issues/issue-layouts/properties/all-properties.tsx – changed_property: "target_date"

No further changes needed.

web/core/components/dropdowns/date-range.tsx (4)

34-41: Well-designed new props enhance component flexibility.

The addition of clearIconClassName, isClearable, and mergeDates props provides excellent configurability while maintaining backward compatibility through sensible defaults.

Also applies to: 72-79


132-139: Clean implementation of clear functionality.

The clearDates function and hasDisplayedDates variable provide a straightforward way to reset the date range with proper state management and callback invocation.


176-239: Excellent implementation of conditional rendering logic.

The merged vs separate date display logic is well-structured with:

  • Clean conditional rendering based on mergeDates prop
  • Proper integration of MergedDateDisplay component
  • Consistent clear icon placement for both modes
  • Good event propagation handling for clear actions
  • Proper placeholder handling

The implementation maintains the original functionality while adding the new merged display option seamlessly.


166-169: Improved tooltip content formatting.

The tooltip content now correctly handles empty states by omitting placeholder text and only showing the dash separator when both dates are present, which provides a cleaner user experience.

{cycleDetails.start_date && <span>{format(parseISO(cycleDetails.start_date), "MMM dd, yyyy")}</span>}
<ArrowRight className="h-3 w-3 flex-shrink-0 my-auto" />
{cycleDetails.end_date && <span>{format(parseISO(cycleDetails.end_date), "MMM dd, yyyy")}</span>}
<MergedDateDisplay startDate={cycleDetails.start_date} endDate={cycleDetails.end_date} className="" />
Copy link
Member

Choose a reason for hiding this comment

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

Could you remove this className if it's not being used.

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: 1

🧹 Nitpick comments (1)
packages/utils/src/datetime.ts (1)

337-343: Enhance JSDoc documentation with validation behavior.

The documentation is excellent but should mention the validation behavior and error handling.

/**
 * Formats merged date range display with smart formatting
+ * Returns empty string for invalid dates or when no valid dates are provided
 * - Single date: "Jan 24, 2025"
 * - Same year, same month: "Jan 24 - 28, 2025"
 * - Same year, different month: "Jan 24 - Feb 6, 2025"
 * - Different year: "Dec 28, 2024 - Jan 4, 2025"
+ * @param parsedStartDate - Start date (can be null/undefined)
+ * @param parsedEndDate - End date (can be null/undefined)
+ * @returns Formatted date range string or empty string if invalid
 */
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1e43af5 and 4836bc2.

📒 Files selected for processing (2)
  • packages/utils/src/datetime.ts (1 hunks)
  • web/core/components/dropdowns/merged-date.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/core/components/dropdowns/merged-date.tsx
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Analyze (python)

Comment on lines +344 to +391
export const formatDateRange = (
parsedStartDate: Date | null | undefined,
parsedEndDate: Date | null | undefined
): string => {
// If no dates are provided
if (!parsedStartDate && !parsedEndDate) {
return "";
}

// If only start date is provided
if (parsedStartDate && !parsedEndDate) {
return format(parsedStartDate, "MMM dd, yyyy");
}

// If only end date is provided
if (!parsedStartDate && parsedEndDate) {
return format(parsedEndDate, "MMM dd, yyyy");
}

// If both dates are provided
if (parsedStartDate && parsedEndDate) {
const startYear = parsedStartDate.getFullYear();
const startMonth = parsedStartDate.getMonth();
const endYear = parsedEndDate.getFullYear();
const endMonth = parsedEndDate.getMonth();

// Same year, same month
if (startYear === endYear && startMonth === endMonth) {
const startDay = format(parsedStartDate, "dd");
const endDay = format(parsedEndDate, "dd");
return `${format(parsedStartDate, "MMM")} ${startDay} - ${endDay}, ${startYear}`;
}

// Same year, different month
if (startYear === endYear) {
const startFormatted = format(parsedStartDate, "MMM dd");
const endFormatted = format(parsedEndDate, "MMM dd");
return `${startFormatted} - ${endFormatted}, ${startYear}`;
}

// Different year
const startFormatted = format(parsedStartDate, "MMM dd, yyyy");
const endFormatted = format(parsedEndDate, "MMM dd, yyyy");
return `${startFormatted} - ${endFormatted}`;
}

return "";
};
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 input validation and error handling for robust date formatting.

The function logic is well-structured, but it lacks critical input validation that could lead to runtime errors.

Consider these improvements:

export const formatDateRange = (
  parsedStartDate: Date | null | undefined,
  parsedEndDate: Date | null | undefined
): string => {
+  // Validate input dates
+  const isStartValid = parsedStartDate && isValid(parsedStartDate);
+  const isEndValid = parsedEndDate && isValid(parsedEndDate);
+
  // If no dates are provided
-  if (!parsedStartDate && !parsedEndDate) {
+  if (!isStartValid && !isEndValid) {
    return "";
  }

  // If only start date is provided
-  if (parsedStartDate && !parsedEndDate) {
+  if (isStartValid && !isEndValid) {
+    try {
      return format(parsedStartDate, "MMM dd, yyyy");
+    } catch (e) {
+      return "";
+    }
  }

  // If only end date is provided
-  if (!parsedStartDate && parsedEndDate) {
+  if (!isStartValid && isEndValid) {
+    try {
      return format(parsedEndDate, "MMM dd, yyyy");
+    } catch (e) {
+      return "";
+    }
  }

  // If both dates are provided
-  if (parsedStartDate && parsedEndDate) {
+  if (isStartValid && isEndValid) {
+    try {
      const startYear = parsedStartDate.getFullYear();
      const startMonth = parsedStartDate.getMonth();
      const endYear = parsedEndDate.getFullYear();
      const endMonth = parsedEndDate.getMonth();

      // Same year, same month
      if (startYear === endYear && startMonth === endMonth) {
        const startDay = format(parsedStartDate, "dd");
        const endDay = format(parsedEndDate, "dd");
        return `${format(parsedStartDate, "MMM")} ${startDay} - ${endDay}, ${startYear}`;
      }

      // Same year, different month
      if (startYear === endYear) {
        const startFormatted = format(parsedStartDate, "MMM dd");
        const endFormatted = format(parsedEndDate, "MMM dd");
        return `${startFormatted} - ${endFormatted}, ${startYear}`;
      }

      // Different year
      const startFormatted = format(parsedStartDate, "MMM dd, yyyy");
      const endFormatted = format(parsedEndDate, "MMM dd, yyyy");
      return `${startFormatted} - ${endFormatted}`;
+    } catch (e) {
+      return "";
+    }
  }

  return "";
};

Additionally, consider adding date order validation if the business logic requires start date to be before end date.

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

🤖 Prompt for AI Agents
In packages/utils/src/datetime.ts around lines 344 to 391, the formatDateRange
function lacks input validation and error handling which may cause runtime
errors. Add checks to ensure parsedStartDate and parsedEndDate are valid Date
objects before formatting. Also, implement validation to confirm that if both
dates are provided, the start date is not after the end date, and handle invalid
inputs gracefully by returning an empty string or an appropriate message.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🌟enhancement New feature or request ready to merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants