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

[Feature] Add time limits report filters #3392

Merged
merged 2 commits into from
Dec 8, 2024

Conversation

CREDO23
Copy link
Contributor

@CREDO23 CREDO23 commented Dec 4, 2024

Description

Fixes #3163
Fixes #3164

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

Current screenshots

Loom

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced DataTableWeeklyLimits with dynamic header titles and optional header display.
    • Upgraded GroupBySelect to a multi-select dropdown with improved selection rules.
    • Introduced TimeReportTableByMember for detailed employee-specific reporting.
    • Added flexible grouping options in WeeklyLimitReport for better data organization.
    • Improved usePagination hook to allow external modification of item offset.
  • Bug Fixes

    • Improved handling of grouping logic and state management in various components.
  • Documentation

    • Updated interfaces to include new properties and enhance clarity in data structures.

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

coderabbitai bot commented Dec 4, 2024

Walkthrough

The pull request introduces significant modifications across several components related to the Weekly Limit Report. Key changes include the renaming of properties in data types, the enhancement of dropdown functionality to support multi-selection, and the introduction of new components for improved reporting capabilities. Additionally, the grouping logic for report data has been updated to accommodate dynamic filtering and grouping options, allowing for more flexible data presentation.

Changes

File Path Change Summary
apps/web/app/[locale]/reports/weekly-limit/components/data-table.tsx Updated WeeklyLimitTableDataType by renaming member to indexValue. Expanded props for DataTableWeeklyLimits to include indexTitle (string) and showHeader (optional boolean). Modified rendering logic for headers.
apps/web/app/[locale]/reports/weekly-limit/components/group-by-select.tsx Changed GroupBySelect from single-select to multi-select dropdown. Updated onChange and defaultValue props to accept arrays. Implemented selection rules for options. Updated rendering logic using Listbox component.
apps/web/app/[locale]/reports/weekly-limit/components/time-report-table.tsx Enhanced TimeReportTable and added TimeReportTableByMember. Updated props interface, added new properties, and simplified header rendering. Introduced groupDataByEmployee function for employee-specific reporting.
apps/web/app/[locale]/reports/weekly-limit/page.tsx Changed groupBy state from string to array. Updated filtering logic and rendering based on new grouping structure. Adjusted GroupBySelect prop from defaultValue to defaultValues.
apps/web/app/hooks/features/usePagination.ts Added setItemOffset to the return object of usePagination hook.
apps/web/app/interfaces/ITimeLimits.ts Introduced new interface ITimeLimitReportByEmployee with properties for employee-specific reporting.

Assessment against linked issues

Objective Addressed Explanation
Filters for Date and Members are available (3163)
Multiple filters can be applied simultaneously (3163)
Grouping options for Date, Week, and Member are available (3164)
Up to two categories can be selected for grouping simultaneously (3164)
Report data reorganizes immediately when grouping is applied or changed (3164)

Possibly related issues

Possibly related PRs

Suggested reviewers

  • evereq

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.

warning "@nx/eslint-plugin-nx > @nx/[email protected]" has unmet peer dependency "nx@>= 14.1 <= 16".
warning " > [email protected]" has unmet peer dependency "@types/node@".
warning "@nx/next > @babel/[email protected]" has unmet peer dependency "@babel/core@^7.0.0-0".
warning "@nx/next > @nx/[email protected]" has unmet peer dependency "nx@>= 15 <= 17".
warning "@nx/next > [email protected]" has unmet peer dependency "webpack@^5.1.0".
warning "@nx/next > [email protected]" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning "@nx/next > @babel/plugin-proposal-decorators > @babel/[email protected]" has unmet peer dependency "@babel/core@^7.0.0".
warning "@nx/next > @babel/plugin-proposal-decorators > @babel/[email protected]" has unmet peer dependency "@babel/core@^7.0.0".
warning "@nx/next > @babel/plugin-proposal-decorators > @babel/[email protected]" has unmet peer dependency "@babel/core@^7.0.0-0".
warning "@nx/next > @nx/js > [email protected]" has unmet peer dependency "@types/node@
".
warning "@nx/next > @nx/react > [email protected]" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".


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 marked this pull request as ready for review December 5, 2024 08:50
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: 3

🧹 Outside diff range and nitpick comments (7)
apps/web/app/[locale]/reports/weekly-limit/components/group-by-select.tsx (2)

89-92: Ensure disabled options are visually distinctive

When an option is disabled to prevent users from deselecting the last remaining option, make sure it's visually apparent. This enhances usability by signaling to users why the option cannot be interacted with.

Consider adding styles to the disabled options:

<Listbox.Option
  disabled={selected.includes(option) && selected.length == 1}
+ className={({ active, disabled }) =>
+   `relative cursor-default select-none py-2 pl-10 pr-4 ${
+     active ? 'bg-primary/10 text-primary' : 'text-gray-900'
+   } ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`
+ }
  value={option}
>

71-72: Simplify translation key generation

The casting to DottedLanguageObjectStringPaths may be unnecessary. You can streamline the code by ensuring the translation keys match the expected format.

Apply this diff to simplify:

{t(
-  `common.${(option == 'date' ? 'date' : option).toUpperCase()}` as DottedLanguageObjectStringPaths
+  `common.${option.toUpperCase()}`
)}
apps/web/app/[locale]/reports/weekly-limit/components/time-report-table.tsx (1)

122-150: Optimize 'groupDataByEmployee' function for performance

Consider optimizing the groupDataByEmployee function. Using a reducer or more efficient data structures can improve performance, especially with large datasets.

Example using a reducer:

export function groupDataByEmployee(data: ITimeLimitReport[]): ITimeLimitReportByEmployee[] {
-  const grouped = new Map<string, ITimeLimitReportByEmployee>();
-  data.forEach((day) => {
-    // existing logic
-  });
-  return Array.from(grouped.values());
+  const grouped = data.reduce((acc, day) => {
+    day.employees.forEach((emp) => {
+      const empId = emp.employee.id;
+      if (!acc[empId]) {
+        acc[empId] = {
+          employee: emp.employee,
+          reports: [],
+        };
+      }
+      acc[empId].reports.push({
+        date: day.date,
+        duration: emp.duration,
+        durationPercentage: emp.durationPercentage,
+        limit: emp.limit,
+      });
+    });
+    return acc;
+  }, {} as { [key: string]: ITimeLimitReportByEmployee });
+  return Object.values(grouped);
}
apps/web/app/[locale]/reports/weekly-limit/page.tsx (2)

67-68: Consolidate 'duration' and 'displayMode' calculations

Both duration and displayMode are derived from groupBy in a similar way. Consider consolidating them to simplify state management.

Apply this diff:

-const duration = useMemo(() => groupBy.find((el) => el == 'date' || el == 'week') ?? 'date', [groupBy]);
-const displayMode = (groupBy.find((el) => el === 'date' || el === 'week') ?? 'date') as 'week' | 'date';
+const [displayMode] = useMemo(() => {
+  const mode = groupBy.find((el) => el === 'date' || el === 'week') ?? 'date';
+  return [mode as 'week' | 'date'];
+}, [groupBy]);
+const duration = displayMode;

188-189: Offer assistance to improve pagination

The TODO comment suggests improving pagination for filtered data. I can help implement a solution to ensure pagination works correctly with the current filters.

Would you like assistance in updating the pagination logic to align with the filtered and grouped data?

apps/web/app/[locale]/reports/weekly-limit/components/data-table.tsx (2)

78-80: Consider adding aria-label for better accessibility

While the column definition changes look good, consider adding an aria-label to improve accessibility when the header text changes dynamically.

-			header: () => <div className="">{indexTitle}</div>,
+			header: () => <div className="" aria-label={`Column header for ${indexTitle}`}>{indexTitle}</div>,

149-168: Consider accessibility impact when headers are hidden

While the conditional header rendering works well, hiding table headers might affect screen reader users. Consider adding appropriate ARIA attributes to maintain table semantics when headers are hidden.

-						{showHeader && (
+						{showHeader ? (
							<TableHeader>
								{table.getHeaderGroups().map((headerGroup) => (
									<TableRow key={headerGroup.id}>
										{headerGroup.headers.map((header) => {
											return (
												<TableHead className=" capitalize" key={header.id}>
													{header.isPlaceholder
														? null
														: flexRender(
																header.column.columnDef.header,
																header.getContext()
															)}
												</TableHead>
											);
										})}
									</TableRow>
								))}
							</TableHeader>
+						) : (
+							<thead className="sr-only" aria-hidden="false">
+								{table.getHeaderGroups().map((headerGroup) => (
+									<tr key={headerGroup.id}>
+										{headerGroup.headers.map((header) => (
+											<th key={header.id}>
+												{header.isPlaceholder
+													? null
+													: flexRender(
+															header.column.columnDef.header,
+															header.getContext()
+														)}
+											</th>
+										))}
+									</tr>
+								))}
+							</thead>
						)}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 88fc30c and c7ddf91.

📒 Files selected for processing (6)
  • apps/web/app/[locale]/reports/weekly-limit/components/data-table.tsx (5 hunks)
  • apps/web/app/[locale]/reports/weekly-limit/components/group-by-select.tsx (1 hunks)
  • apps/web/app/[locale]/reports/weekly-limit/components/time-report-table.tsx (3 hunks)
  • apps/web/app/[locale]/reports/weekly-limit/page.tsx (7 hunks)
  • apps/web/app/hooks/features/usePagination.ts (1 hunks)
  • apps/web/app/interfaces/ITimeLimits.ts (1 hunks)
🔇 Additional comments (7)
apps/web/app/[locale]/reports/weekly-limit/components/time-report-table.tsx (1)

98-100: Review date formatting for week display

In the indexValue, when displayMode is 'week', the date range is formatted using item.date and moment(item.date).endOf('week').format('YYYY-MM-DD'). Ensure this correctly represents the week's start and end dates according to your locale settings.

apps/web/app/[locale]/reports/weekly-limit/page.tsx (1)

154-158: Review necessity of additional filtering on 'currentItems'

The filter applied on currentItems for displayMode === 'week' may be redundant if the data fetched already respects the duration. Verify if this filtering is necessary.

apps/web/app/interfaces/ITimeLimits.ts (1)

26-34: Approved: New interface 'ITimeLimitReportByEmployee'

The ITimeLimitReportByEmployee interface is well-defined and integrates seamlessly with existing structures.

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

24-25: Verify the necessity of exposing 'setItemOffset'

Adding setItemOffset to the returned object exposes internal state. Ensure this is required and won't introduce unintended side effects. If necessary, document its intended usage.

apps/web/app/[locale]/reports/weekly-limit/components/data-table.tsx (3)

44-49: LGTM! Props changes enhance component flexibility

The new props indexTitle and showHeader are well-designed additions that support the filtering and grouping requirements. The types are properly defined, and default values are handled correctly.


126-126: LGTM! Table configuration is properly set up


25-25: Verify type changes across dependent components

The rename from member to indexValue makes the type more flexible for different grouping options, which aligns with the filtering requirements. However, we should ensure all consumers of this type are updated.

✅ Verification successful

Type change from member to indexValue is safe

The rename from member to indexValue in WeeklyLimitTableDataType is safe. The search results show that while member is used in various contexts (MembersSelect component, groupBy options), there are no direct references to the old property name member within WeeklyLimitTableDataType. The change makes the type more generic to support different grouping options while maintaining backward compatibility.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining usage of the old property name 'member' in WeeklyLimitTableDataType
rg -l "WeeklyLimitTableDataType.*member" --type typescript

Length of output: 95


Script:

#!/bin/bash
# Search for any remaining usage of 'member' property in TypeScript/TSX files
rg -l "member.*WeeklyLimitTableDataType|WeeklyLimitTableDataType.*member" "*.ts" "*.tsx"

# Also search for any direct usage of 'member' in weekly-limit related files
fd -e ts -e tsx weekly-limit --exec rg -l "member"

Length of output: 232


Script:

#!/bin/bash
# Search for WeeklyLimitTableDataType usage
rg "WeeklyLimitTableDataType" --type=tsx --type=ts

# Search for member property in weekly-limit directory
rg "member" apps/web/app/\[locale\]/reports/weekly-limit/

Length of output: 2446

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 (4)
apps/web/app/[locale]/reports/weekly-limit/components/time-report-table.tsx (2)

58-111: Consider performance optimizations and code reusability.

While the implementation is functionally correct, consider these improvements:

  1. Extract date formatting logic to a utility function for reusability
  2. Memoize the data mapping function to optimize performance with large datasets

Example implementation:

+ const formatWeekRange = (date: string) => 
+   `${date} - ${moment(date).endOf('week').format('YYYY-MM-DD')}`;

+ const useMemoizedReportData = (reports: any[], displayMode: string) => 
+   useMemo(() => reports?.map((item) => {
+     const limit = item.limit || organizationLimits[displayMode] || DEFAULT_WORK_HOURS_PER_DAY;
+     const percentageUsed = (item.duration / limit) * 100;
+     const remaining = limit - item.duration;
+     return {
+       indexValue: displayMode === 'week' ? formatWeekRange(item.date) : item.date,
+       limit,
+       percentageUsed,
+       timeSpent: item.duration,
+       remaining
+     };
+   }), [reports, displayMode]);

113-150: Add error handling for edge cases.

The grouping logic is efficient, but consider adding error handling for:

  • Empty data array
  • Missing employee information
  • Invalid date formats

Example implementation:

 export function groupDataByEmployee(data: ITimeLimitReport[]): ITimeLimitReportByEmployee[] {
+  if (!Array.isArray(data) || data.length === 0) {
+    return [];
+  }
   const grouped = new Map<string, ITimeLimitReportByEmployee>();

   data.forEach((day) => {
+    if (!day?.date || !Array.isArray(day.employees)) {
+      console.warn('Invalid data format encountered:', day);
+      return;
+    }
     const date = day.date;
     day.employees.forEach((emp) => {
+      if (!emp?.employee?.id) {
+        console.warn('Invalid employee data:', emp);
+        return;
+      }
       // ... rest of the implementation
     });
   });
apps/web/app/[locale]/reports/weekly-limit/page.tsx (2)

87-94: Simplify duration mapping.

The duration mapping can be simplified to avoid the ternary operator.

-duration: duration == 'date' ? 'day' : duration,
+const durationMap = { date: 'day', week: 'week' };
+duration: durationMap[duration] || 'day',

188-189: Address the TODO comment for pagination improvement.

The comment indicates that pagination needs improvement for filtered data. This is important for proper data handling.

Would you like me to help implement the pagination logic for filtered data or create a GitHub issue to track this task?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between c7ddf91 and b28a255.

📒 Files selected for processing (2)
  • apps/web/app/[locale]/reports/weekly-limit/components/time-report-table.tsx (3 hunks)
  • apps/web/app/[locale]/reports/weekly-limit/page.tsx (7 hunks)
🧰 Additional context used
📓 Learnings (1)
apps/web/app/[locale]/reports/weekly-limit/page.tsx (1)
Learnt from: CREDO23
PR: ever-co/ever-teams#3392
File: apps/web/app/[locale]/reports/weekly-limit/components/group-by-select.tsx:42-51
Timestamp: 2024-12-05T09:04:08.049Z
Learning: In the `GroupBySelect` component (`apps/web/app/[locale]/reports/weekly-limit/components/group-by-select.tsx`), only one option can be selected at a time; two options cannot be selected simultaneously.
🔇 Additional comments (2)
apps/web/app/[locale]/reports/weekly-limit/components/time-report-table.tsx (2)

1-11: LGTM! Well-structured interfaces with clear type definitions.

The props interface is well-defined with appropriate types, and the displayMode values are consistently using lowercase.


Line range hint 26-56: LGTM! Clean implementation with proper calculations.

The component effectively:

  • Handles time limit calculations
  • Maps employee data correctly
  • Uses proper TypeScript types

@CREDO23 CREDO23 requested review from evereq and Cedric921 December 5, 2024 09:33
@evereq evereq merged commit 94ec0de into develop Dec 8, 2024
13 checks passed
@evereq evereq deleted the 3164-feature-reports--group-weekly-limit-report branch December 8, 2024 17:23
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.

[Feature] Reports | Group Weekly Limit report [Feature] Reports | Filter Weekly Limit report
3 participants