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

we should not plan the same task twice #3244

Merged
merged 2 commits into from
Nov 8, 2024

Conversation

CREDO23
Copy link
Contributor

@CREDO23 CREDO23 commented Nov 8, 2024

Description

Fix #3117

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings

Previous screenshots

Loom

Current screenshots

loom

Summary by CodeRabbit

  • New Features

    • Introduced functionality to remove duplicate tasks in daily plans, ensuring task uniqueness.
    • Enhanced date selection in the Create Daily Plan modal by preventing selection of already booked dates for specific tasks.
    • Added flexibility to the dropdown menu components with new properties for styling and content rendering.
  • Bug Fixes

    • Improved task management logic to eliminate duplicate entries when creating or updating daily plans.

@CREDO23 CREDO23 self-assigned this Nov 8, 2024
@CREDO23 CREDO23 linked an issue Nov 8, 2024 that may be closed by this pull request
Copy link
Contributor

coderabbitai bot commented Nov 8, 2024

Walkthrough

This pull request introduces a new utility function, removeDuplicateItems, which is added to the task management logic within the useDailyPlan hook. This function ensures that tasks in daily plans are unique by filtering out duplicates based on their id. Additionally, the CreateDailyPlanFormModal component is updated to enhance date selection by preventing the selection of dates that are already booked for specific tasks. The overall structure of the components remains unchanged, focusing on improving task and date management.

Changes

File Path Change Summary
apps/web/app/hooks/features/useDailyPlan.ts Added removeDuplicateItems utility function to ensure unique tasks in daily plans.
apps/web/app/utils/remove-duplicate-item.ts Introduced removeDuplicateItems function to filter duplicates based on id.
apps/web/lib/features/daily-plan/create-daily-plan-form-modal.tsx Added existingTaskPlanDates variable and updated CustomCalendar to prevent selecting booked dates.
apps/web/components/ui/dropdown-menu.tsx Updated DropdownMenuSubContent and DropdownMenuContent to include className and children props.

Assessment against linked issues

Objective Addressed Explanation
Task cannot be planned multiple times for the same date (#3117)

Possibly related PRs

Suggested reviewers

  • evereq
  • Cedric921

Poem

In a garden of plans, tasks bloom bright,
With duplicates gone, all feels just right.
Dates now protected, no overlaps in sight,
A hop and a skip, our work takes flight! 🐇✨


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 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.

@CREDO23 CREDO23 force-pushed the 3117-bug-planned--task-was-planned-two-times branch from e711e5a to 641f3a0 Compare November 8, 2024 04:15
@CREDO23 CREDO23 requested review from evereq and Cedric921 November 8, 2024 04:17
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

🧹 Outside diff range and nitpick comments (5)
apps/web/app/utils/remove-duplicate-item.ts (2)

1-8: Improve TypeScript documentation.

The JSDoc comments should be enhanced to better reflect the TypeScript types and business context.

 /**
- * A dynamic function that removes duplicates from an array of items.
+ * Removes duplicate items from an array by comparing their IDs.
  *
- * @param {any[]} items - The items to check against.
+ * @template TItem - Type of items with an 'id' property
+ * @param {TItem[]} items - Array of items to deduplicate
  *
- * @returns {any[]} - The array of items without duplicates.
+ * @returns {TItem[]} Array of items with duplicates removed
  */

9-22: Implementation looks good, but consider additional validations.

The function efficiently removes duplicates using Set, but consider adding input validation for empty or invalid IDs.

 export const removeDuplicateItems = <TItem extends { id: string }>(items?: TItem[]): TItem[] => {
+  if (!items?.length) return [];
+
   const seenIds = new Set<string>();
 
-  return items
-    ? items.filter((item) => {
+  return items.filter((item) => {
+        if (!item.id.trim()) {
+          throw new Error('Invalid item ID');
+        }
         if (seenIds.has(item.id)) {
           return false;
         } else {
           seenIds.add(item.id);
           return true;
         }
-      })
-    : [];
+      });
 };
apps/web/lib/features/daily-plan/create-daily-plan-form-modal.tsx (2)

253-253: Consider enhancing the UX by distinguishing between different types of disabled dates.

While the implementation correctly prevents selecting dates where the task is already planned, it might be helpful to visually distinguish between dates disabled due to being in the past versus dates disabled due to existing task plans.

Consider adding a new modifier for task-specific disabled dates:

-disabled={[{ from: new Date(1970, 1, 1), to: yesterdayDate }, ...existingTaskPlanDates]}
+disabled={[{ from: new Date(1970, 1, 1), to: yesterdayDate }]}
+modifiers={{
+  booked: existingPlanDates,
+  taskPlanned: existingTaskPlanDates
+}}
+modifiersClassNames={{
+  booked: 'bg-primary text-white',
+  taskPlanned: 'bg-red-200 text-gray-500 cursor-not-allowed',
+  today: clsxm('border-2 !border-yellow-700 rounded')
+}}

48-54: Architectural approach effectively solves the duplicate task planning issue.

The solution elegantly prevents duplicate task planning through a combination of:

  1. Efficient filtering of existing plans
  2. Proper state management with useMemo
  3. Clean integration with the calendar component

The implementation is maintainable and follows React best practices.

Consider documenting this behavior in the component's documentation or README to make it clear that tasks cannot be planned multiple times for the same date.

Also applies to: 238-244, 253-253

apps/web/app/hooks/features/useDailyPlan.ts (1)

124-124: Add error handling for duplicate removal.

While the state updates are consistent, consider adding try-catch blocks around the removeDuplicateItems calls to handle potential errors gracefully.

Example implementation:

-return { ...res.data, tasks: removeDuplicateItems(res.data.tasks) };
+try {
+  return { ...res.data, tasks: removeDuplicateItems(res.data.tasks) };
+} catch (error) {
+  console.error('Error removing duplicate tasks:', error);
+  return res.data; // Fallback to original data
+}

Also applies to: 137-140, 144-147

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3740f52 and 641f3a0.

📒 Files selected for processing (3)
  • apps/web/app/hooks/features/useDailyPlan.ts (3 hunks)
  • apps/web/app/utils/remove-duplicate-item.ts (1 hunks)
  • apps/web/lib/features/daily-plan/create-daily-plan-form-modal.tsx (4 hunks)
🔇 Additional comments (7)
apps/web/app/utils/remove-duplicate-item.ts (1)

9-22: Consider architectural improvements for task date validation.

While this utility effectively removes duplicate tasks by ID, it doesn't address the core issue of preventing the same task from being planned on the same date. Consider extending the uniqueness check to include the date.

Let's verify how this utility is being used in the daily plan context:

apps/web/lib/features/daily-plan/create-daily-plan-form-modal.tsx (2)

238-244: LGTM! Props update is clean and well-typed.

The addition of existingTaskPlanDates to the CustomCalendar props maintains consistency with the existing implementation.


48-54: LGTM! Implementation effectively prevents duplicate task planning.

The existingTaskPlanDates implementation correctly identifies dates where a task is already planned, using efficient filtering and proper memoization.

Let's verify the task filtering logic:

✅ Verification successful

Let me gather more context about the task planning implementation to ensure consistency.


Let me try again with corrected commands:


Implementation is correct and consistent with the codebase

The verification confirms that:

  1. The task filtering logic in existingTaskPlanDates is consistent with other task-related filtering implementations across the codebase
  2. The CustomCalendar component correctly receives and uses existingTaskPlanDates to prevent duplicate task planning
  3. The implementation aligns with other task planning checks in the codebase, particularly in add-task-estimation-hours-modal.tsx and plan-day-badge.ts
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the task filtering logic is consistent across the codebase
# Look for other implementations that might conflict with this approach

# Search for similar task filtering patterns
rg -A 3 "plan.tasks?.some\(\(task\)"

Length of output: 517


Script:

#!/bin/bash
# Check for any other implementations related to task planning dates
rg -A 5 "task.*plan.*date" --type typescript

# Look for the CustomCalendar component usage
ast-grep --pattern 'CustomCalendar $$$'

# Check for other date-related filtering in daily plans
rg -A 5 "profileDailyPlans.*filter" --type typescript

Length of output: 214


Script:

#!/bin/bash
# Check for any other implementations related to task planning dates
rg -A 5 "task.*plan.*date"

# Look for the CustomCalendar component usage
rg -A 5 "<CustomCalendar"

# Check for other date-related filtering in daily plans
rg -A 5 "profileDailyPlans.*filter"

# Look for task filtering implementations
rg -A 5 "tasks\?\.some"

Length of output: 6789

apps/web/app/hooks/features/useDailyPlan.ts (4)

30-30: LGTM: Appropriate utility import for duplicate removal.

The import of removeDuplicateItems aligns with the PR's objective of preventing duplicate task planning.


124-124: LGTM: Comprehensive duplicate task removal implementation.

The code consistently applies removeDuplicateItems across all state updates:

  1. When updating existing plans
  2. When creating new plans
  3. When updating employee plans

This ensures no duplicate tasks can exist in any plan state.

Also applies to: 137-140, 144-147


124-124: Verify duplicate handling across time periods.

Please verify that duplicate task prevention works correctly in these scenarios:

  1. Moving tasks between plans (today → future, past → today)
  2. Adding tasks to outstanding plans
  3. Bulk operations (removeManyTaskPlans)

Let's check for potential task movement operations:

Also applies to: 137-140, 144-147

✅ Verification successful

Let me gather more information about the duplicate handling implementation.


Let me check the implementation of task plan updates and bulk operations to complete the verification.


Based on the gathered information, I can now provide the final response:

Duplicate handling is properly implemented across all operations

The codebase consistently handles duplicates through:

  1. A generic removeDuplicateItems utility that filters by task ID
  2. This utility is applied to all task plan operations:
    • After fetching plans
    • When adding tasks to plans
    • During bulk operations
  3. The implementation uses a Set for efficient duplicate detection

The duplicate prevention is correctly implemented at the data transformation layer, ensuring consistency across all time periods and operations.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for task movement operations
rg -g "*.ts" -g "*.js" "moveTask|transferTask|addTaskTo.*Plan"

Length of output: 2971


Script:

#!/bin/bash
# Search for duplicate handling functions and their implementations
rg -g "*.ts" -g "*.js" "removeDuplicate" -A 5

# Also check the interface definitions for task plans
ast-grep --pattern 'interface $_ {
  $$$
  tasks: $_
  $$$
}'

Length of output: 3245


Script:

#!/bin/bash
# Check the implementation of task plan updates and bulk operations
rg -g "*.ts" "removeManyTaskFromPlans|updateDailyPlan" -B 2 -A 5

# Also check the task plan interfaces
ast-grep --pattern 'interface IDailyPlan {
  $$$
}'

Length of output: 5180


124-124: Consider adding server-side validation.

While client-side duplicate removal is implemented, consider adding server-side validation in the API to ensure data integrity even if the client-side validation is bypassed.

Let's check if the API already has duplicate validation:

Also applies to: 137-140, 144-147

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

🧹 Outside diff range and nitpick comments (1)
apps/web/components/ui/dropdown-menu.tsx (1)

Line range hint 61-74: Avoid using type assertion to any

Similar to the DropdownMenuSubContent, using {...(props as any)} here bypasses TypeScript's type checking.

-      {...(props as any)}
+      {...props}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 641f3a0 and 2612b2f.

📒 Files selected for processing (1)
  • apps/web/components/ui/dropdown-menu.tsx (2 hunks)
🔇 Additional comments (1)
apps/web/components/ui/dropdown-menu.tsx (1)

Line range hint 42-74: Verify relationship to PR objectives

The changes to these dropdown components appear unrelated to the PR's objective of preventing task duplication. While these components might be used in the task planning interface, the type changes don't directly contribute to preventing duplicate task planning.

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

Successfully merging this pull request may close these issues.

[Bug] Planned | task was planned two times
2 participants