Skip to content
New issue

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

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

Already on GitHub? # to your account

3108 feature/ task list view all tasks in a team #3234

Merged
merged 17 commits into from
Nov 6, 2024

Conversation

NdekoCode
Copy link
Contributor

@NdekoCode NdekoCode commented Nov 6, 2024

Description

Please include a summary of the changes and the related issue.

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

Please add here videos or images of previous status

Current screenshots

Please add here videos or images of previous status

ndekocode-ever0teams-2024_11_06-18_12_27.webm

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced new components: TeamTask, AssigneeUser, DropdownMenuTask, FilterButton, StatusBadge, and TaskTable for enhanced task management and display.
  • Improvements

    • Updated layout and styling for various components, including MainLayout, AppSidebar, and dropdown menus for better user experience.
    • Enhanced state management for menus and tasks using Jotai, improving responsiveness and interactivity.
  • Bug Fixes

    • Adjusted overflow behaviors in several components to improve scrolling and visibility of content.
  • Localization

    • Updated sidebar terminology for clarity in the localization file.
  • Dependency Updates

    • Updated @tanstack/react-table to version ^8.20.5 for improved functionality.

Copy link
Contributor

coderabbitai bot commented Nov 6, 2024

Warning

Rate limit exceeded

@NdekoCode has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 10 minutes and 5 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between ccaef5b and 3c115a2.

Walkthrough

The pull request includes multiple changes across various files, focusing on code formatting, structural adjustments, and the introduction of new components. Key modifications include disabling the automatic removal of unused imports in the .vscode/settings.json, refactoring components for improved readability, and enhancing state management with new atoms in the Jotai store. Additionally, several new components related to task management, such as TeamTask, DropdownMenuTask, and StatusBadge, have been introduced to improve functionality and user experience.

Changes

File Change Summary
.vscode/settings.json Commented out "source.removeUnusedImports": "always" in editor.codeActionsOnSave.
apps/web/app/[locale]/layout.tsx Reformatted locales array and Props interface for consistency; condensed PostHogPageView import statement.
apps/web/app/[locale]/page-component.tsx Changed top-level <div> class from "h-screen" to "h-full min-h-screen"; wrapped conditional rendering in a fragment.
apps/web/app/[locale]/permissions/component.tsx Consolidated import statements; adjusted formatting for consistency.
apps/web/app/[locale]/profile/[memberId]/page.tsx Changed ResizablePanel class from !overflow-y-scroll to !overflow-y-auto.
apps/web/app/[locale]/team/tasks/page.tsx Added new component TeamTask for rendering team tasks.
apps/web/app/hooks/features/useAuthTeamTasks.ts Updated return object to include tasks.
apps/web/app/interfaces/ITask.ts Changed issueType property type from optional string to optional ITaskIssue.
apps/web/app/layout.tsx Simplified return statement to use a fragment instead of <html> and <body>.
apps/web/app/stores/menu.ts Introduced new atoms for menu state management: openMenusState, openMenusStateStorage, activeMenuIndexState, activeSubMenuIndexState.
apps/web/components/app-sidebar.tsx Removed useActiveTeam hook and related state; streamlined rendering logic for favorite tasks.
apps/web/components/nav-main.tsx Added state management for menu toggling with new functions for handling active menu states.
apps/web/components/pages/task/description-block/task-description-editor.tsx Made formatting adjustments; no functional changes.
apps/web/components/pages/task/details-section/blocks/task-main-info.tsx Reformatted imports and component structure for clarity.
apps/web/components/pages/team/tasks/AssigneeUser.tsx Added new component AssigneeUser for displaying assigned users.
apps/web/components/pages/team/tasks/DropdownMenuTask.tsx Introduced DropdownMenuTask component for task management dropdown.
apps/web/components/pages/team/tasks/FilterButton.tsx Added new FilterButton component for table column filtering.
apps/web/components/pages/team/tasks/StatusBadge.tsx Introduced StatusBadge component for displaying task status.
apps/web/components/pages/team/tasks/TaskTable.tsx Added TaskTable component for displaying a paginated list of tasks.
apps/web/components/pages/team/tasks/columns.tsx Defined column configurations for task table.
apps/web/components/pages/team/tasks/tasks-data-table.tsx Introduced TasksDataTable component for managing task data display.
apps/web/components/ui/sidebar.tsx Replaced SidebarTrigger with SidebarTriggerButton for sidebar toggling.
apps/web/lib/components/combobox/index.tsx Added Readonly utility type to CustomCombobox props; made formatting adjustments.
apps/web/lib/components/pagination.tsx Added optional className property to Paginate component.
apps/web/lib/components/svgs/app-logo.tsx Changed logo rendering from <img> to Image component from next/image.
apps/web/lib/components/time-picker/index.tsx Made formatting adjustments; updated type definitions for consistency.
apps/web/lib/features/activity/components/screenshot-details.tsx Changed CSS class from overflow-x-scroll to overflow-x-auto.
apps/web/lib/features/integrations/calendar/calendar-component.tsx Reformatted import statements; no functional changes.
apps/web/lib/features/task/daily-plan/future-tasks.tsx Reformatted imports and return statement for clarity.
apps/web/lib/features/task/daily-plan/outstanding-all.tsx Reformatted code for readability; no functional changes.
apps/web/lib/features/task/daily-plan/outstanding-date.tsx Reformatted imports and code structure for consistency.
apps/web/lib/features/task/daily-plan/past-tasks.tsx Simplified function signature; no functional changes.
apps/web/lib/features/task/task-status.tsx Updated dropdown styling; no functional changes.
apps/web/lib/features/team-members.tsx Changed parameter type to Readonly<TeamMembersProps>; updated class names for styling.
apps/web/lib/features/user-profile-plans.tsx Adjusted overflow class; minor formatting changes.
apps/web/lib/layout/main-layout.tsx Updated layout class names and default prop values for components.
apps/web/locales/en.json Updated string value for "MY_WORKS" from "My Works" to "My Work".
apps/web/package.json Updated @tanstack/react-table dependency version from ^8.10.7 to ^8.20.5.

Possibly related PRs

Suggested labels

WEB, feature, enhancement

Suggested reviewers

  • evereq
  • Cedric921

🐰 In the code, we hop and play,
With new tasks and features on display.
From sidebar tweaks to task tables bright,
Our app shines more, a true delight!
So let’s celebrate with a joyful cheer,
For every change brings us near! 🐇✨


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.

Copy link

socket-security bot commented Nov 6, 2024

🚨 Potential security issues detected. Learn more about Socket for GitHub ↗︎

To accept the risk, merge this PR and you will not be notified again.

Alert Package NoteCI
Critical CVE npm/xmldom@0.1.31 ⚠︎

View full report↗︎

Next steps

What is a critical CVE?

Contains a Critical Common Vulnerability and Exposure (CVE).

Remove or replace dependencies that include known critical CVEs. Consumers can use dependency overrides or npm audit fix --force to remove vulnerable dependencies.

Take a deeper look at the dependency

Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support [AT] socket [DOT] dev.

Remove the package

If you happen to install a dependency that Socket reports as Known Malware you should immediately remove it and select a different dependency. For other alert types, you may may wish to investigate alternative packages or consider if there are other ways to mitigate the specific risk posed by the dependency.

Mark a package as acceptable risk

To ignore an alert, reply with a comment starting with @SocketSecurity ignore followed by a space separated list of ecosystem/package-name@version specifiers. e.g. @SocketSecurity ignore npm/foo@1.0.0 or ignore all packages with @SocketSecurity ignore-all

  • @SocketSecurity ignore npm/xmldom@0.1.31

@NdekoCode NdekoCode marked this pull request as ready for review November 6, 2024 16:40
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: 19

🧹 Outside diff range and nitpick comments (44)
apps/web/app/stores/menu.ts (1)

4-4: Consider enhancing type safety and storage key management.

While the implementation is functional, there are opportunities for improvement:

  1. The type { [key: string]: boolean } could be more specific to prevent potential errors.
  2. The storage key should be namespaced to avoid conflicts.

Consider these improvements:

+// Define specific menu keys to enhance type safety
+type MenuKey = 'main' | 'tasks' | 'settings' | 'profile';
+type MenuState = { [K in MenuKey]?: boolean };
+
-export const openMenusState = atom<{ [key: string]: boolean }>({});
+export const openMenusState = atom<MenuState>({});
+
+// Use a namespaced storage key
-export const openMenusStateStorage = atomWithStorage<{ [key: string]: boolean }>('sidebar-open-menus', {});
+export const openMenusStateStorage = atomWithStorage<MenuState>('ever-teams:sidebar-open-menus', {});

Also applies to: 6-8

apps/web/components/pages/team/tasks/StatusBadge.tsx (3)

1-2: Remove unnecessary React import

Since React 17+, the React import is not required for JSX usage due to the new JSX transform.

import { cn } from '@/lib/utils';
-import React from 'react';

4-8: Enhance type safety and documentation

Consider the following improvements:

  1. Add JSDoc documentation to describe the component's purpose and props
  2. Make the color prop type-safe by using a union type of allowed colors
+/**
+ * A badge component that displays a status label with a count
+ */
 interface StatusBadgeProps {
+  /** The text label to display */
   label: string;
+  /** The count to display in parentheses */
   count: number;
-  color: string;
+  /** The background color class for the badge */
+  color: 'bg-gray-100' | 'bg-yellow-100' | 'bg-green-100' | 'bg-red-100';
 }

10-21: Enhance accessibility and performance

Consider the following improvements:

  1. Add proper ARIA attributes for better accessibility
  2. Memoize the component if it's used in lists
  3. Extract the base classes for reusability
-const StatusBadge: React.FC<StatusBadgeProps> = ({ label, count, color }) => {
+const baseClasses = 'gap-0.5 self-stretch py-1.5 justify-center md:px-3 px-2 flex items-center capitalize text-sm relative min-h-[26px] rounded-[40px]';
+
+const StatusBadge = React.memo(({ label, count, color }: StatusBadgeProps) => {
 	return (
 		<div
+			role="status"
+			aria-label={`${label} status with count ${count}`}
 			className={cn(
-				'gap-0.5 self-stretch py-1.5 justify-center md:px-3 px-2 flex items-center capitalize text-sm relative min-h-[26px] rounded-[40px]',
+				baseClasses,
 				color
 			)}
 		>
 			{label} ({count})
 		</div>
 	);
-};
+});
+
+StatusBadge.displayName = 'StatusBadge';
apps/web/components/pages/team/tasks/AssigneeUser.tsx (1)

5-6: Consider handling multiple assignees and simplify array access.

The component currently only displays the first assignee, which might be limiting. Also, users.at(0) could be simplified to users[0] for better readability.

-const employee = users && users.length > 0 ? users.at(0) : null;
+const employee = users?.[0] ?? null;

Consider adding support for multiple assignees if that's a requirement:

const AssigneeUser: FC<{ users: IEmployee[]; showAll?: boolean }> = ({ users, showAll }) => {
  if (!users?.length) {
    return <span className="text-xs font-medium text-indigo-950 dark:text-gray-200">No user assigned</span>;
  }
  
  return (
    <div className="flex items-center gap-1.5 h-full">
      {(showAll ? users : [users[0]]).map((employee) => (
        <div key={employee.id} className="flex items-center gap-2.5">
          {/* ... existing avatar and name rendering ... */}
        </div>
      ))}
      {!showAll && users.length > 1 && (
        <span className="text-xs text-gray-500">+{users.length - 1} more</span>
      )}
    </div>
  );
};
apps/web/components/pages/team/tasks/TaskTable.tsx (3)

1-8: Consider standardizing import paths for better maintainability.

The mix of relative (./columns) and absolute (@/app/hooks) imports could be standardized. Consider using absolute imports consistently throughout the file for better maintainability and easier refactoring.

-import { columns } from './columns';
-import { TasksDataTable } from './tasks-data-table';
+import { columns } from '@/app/components/pages/team/tasks/columns';
+import { TasksDataTable } from '@/app/components/pages/team/tasks/tasks-data-table';

14-29: Enhance component performance and accessibility.

A few suggestions to improve the implementation:

  1. Memoize the columns prop since it's likely static
  2. Add appropriate ARIA labels for accessibility
  3. Consider adding empty state handling when there are no tasks
+import { useMemo } from 'react';
+
 export function TaskTable() {
 	const { tasks } = useTeamTasks();
+	const memoizedColumns = useMemo(() => columns, []);
 
 	const { total, onPageChange, itemsPerPage, itemOffset, endOffset, setItemsPerPage, currentItems } =
 		usePagination<ITeamTask>(tasks);
+
+	if (currentItems.length === 0) {
+		return <div className="w-full text-center py-4">No tasks found</div>;
+	}
+
 	return (
-		<div className="w-full flex flex-col min-h-full">
-			<TasksDataTable columns={columns} className="border-none" data={currentItems} />
+		<div className="w-full flex flex-col min-h-full" role="region" aria-label="Team Tasks">
+			<TasksDataTable 
+				columns={memoizedColumns} 
+				className="border-none" 
+				data={currentItems}
+			/>

 			<Paginate
 				total={total}

1-30: Add JSDoc documentation for the component.

Since this is a new feature for task list view, adding comprehensive documentation would help other developers understand the component's purpose and usage.

+/**
+ * TaskTable Component
+ * 
+ * Displays a paginated table of team tasks with sorting and filtering capabilities.
+ * Integrates with the team's task management system and provides pagination controls.
+ * 
+ * @example
+ * ```tsx
+ * <TaskTable />
+ * ```
+ */
 export function TaskTable() {
apps/web/app/hooks/features/useAuthTeamTasks.ts (3)

16-28: Consider optimizing task filtering performance

The current implementation performs two separate iterations over the tasks array. Consider combining both filters into a single pass for better performance, especially with large task lists.

-const assignedTasks = useMemo(() => {
-  if (!user) return [];
-  return tasks.filter((task) => {
-    return task?.members.some((m) => m.userId === user.id);
-  });
-}, [tasks, user]);
-
-const unassignedTasks = useMemo(() => {
-  if (!user) return [];
-  return tasks.filter((task) => {
-    return !task?.members.some((m) => m.userId === user.id);
-  });
-}, [tasks, user]);
+const { assignedTasks, unassignedTasks } = useMemo(() => {
+  if (!user) return { assignedTasks: [], unassignedTasks: [] };
+  return tasks.reduce(
+    (acc, task) => {
+      const isAssigned = task?.members.some((m) => m.userId === user.id);
+      if (isAssigned) {
+        acc.assignedTasks.push(task);
+      } else {
+        acc.unassignedTasks.push(task);
+      }
+      return acc;
+    },
+    { assignedTasks: [], unassignedTasks: [] }
+  );
+}, [tasks, user]);

31-33: Simplify nested array mapping

The nested map operations can be flattened for better readability.

-const outStandingTasksCount = estimatedTotalTime(
-  outstandingPlans?.map((plan) => plan.tasks?.map((task) => task))
-).totalTasks;
+const outStandingTasksCount = estimatedTotalTime(
+  outstandingPlans?.flatMap((plan) => plan.tasks || [])
+).totalTasks;

35-35: Fix typo in variable name

The variable name contains an inconsistent capitalization.

-const todayTasksCOunt = getTotalTasks(todayPlan);
+const todayTasksCount = getTotalTasks(todayPlan);
apps/web/lib/features/activity/components/screenshot-details.tsx (1)

25-25: Improved scrolling behavior with overflow-x-auto

The change from overflow-x-scroll to overflow-x-auto is a good improvement as it:

  • Shows scrollbars only when necessary, reducing visual clutter
  • Follows web accessibility best practices by not forcing scrollbars
  • Maintains consistent behavior across different screen sizes and content lengths

Consider also adding scrollbar-gutter: stable to prevent layout shifts when the scrollbar appears:

-<div className="w-full p-4 overflow-x-auto">
+<div className="w-full p-4 overflow-x-auto scrollbar-gutter-stable">
apps/web/components/pages/team/tasks/FilterButton.tsx (2)

19-75: Consider extracting and standardizing the SVG icon.

The SVG implementation has inconsistent stroke colors (#282048 and #292D32) and could benefit from being extracted into a separate component.

Consider:

  1. Creating a separate FilterIcon component
  2. Standardizing the stroke color
  3. Making the color configurable via props
+// components/icons/FilterIcon.tsx
+interface FilterIconProps {
+  className?: string;
+  color?: string;
+}
+
+export const FilterIcon = ({ className, color = 'currentColor' }: FilterIconProps) => (
+  <svg
+    className={className}
+    width={14}
+    height={14}
+    viewBox="0 0 14 14"
+    fill="none"
+    xmlns="http://www.w3.org/2000/svg"
+  >
+    {/* SVG paths with standardized stroke={color} */}
+  </svg>
+);

// In FilterButton.tsx
-<svg className="w-4 h-4" ...>
+<FilterIcon className="w-4 h-4" />

14-97: Consider enhancing the filter functionality.

While the current implementation handles basic column visibility, consider adding these common table filter features:

  1. Persistence of filter state (e.g., using localStorage or URL params)
  2. Reset to default visibility
  3. Select/deselect all columns option

Example implementation of these features:

// Add these props to FilterButtonProps
interface FilterButtonProps<TData> {
  table: Table<TData>;
  persistKey?: string; // Optional key for storing state
  defaultVisible?: string[]; // Default visible columns
}

// Inside the component, add these features
const persistedState = persistKey 
  ? localStorage.getItem(persistKey)
  : null;

useEffect(() => {
  if (persistedState) {
    const visibleColumns = JSON.parse(persistedState);
    table.getAllColumns().forEach(column => {
      column.toggleVisibility(visibleColumns.includes(column.id));
    });
  }
}, []);

// Add these actions to DropdownMenuContent
<DropdownMenuContent>
  <DropdownMenuItem onSelect={() => {
    table.getAllColumns().forEach(column => {
      column.toggleVisibility(true);
    });
  }}>
    Show All
  </DropdownMenuItem>
  <DropdownMenuItem onSelect={() => {
    table.getAllColumns().forEach(column => {
      column.toggleVisibility(false);
    });
  }}>
    Hide All
  </DropdownMenuItem>
  <DropdownMenuSeparator />
  {/* Existing column checkboxes */}
</DropdownMenuContent>
apps/web/lib/components/pagination.tsx (1)

30-30: Consider documenting className usage and potential responsive conflicts

While the className implementation is correct, consider:

  1. Adding JSDoc comments to document the expected className format and usage
  2. Being cautious about potential conflicts between custom classes and the built-in responsive utilities (flex-col md:flex-row)

Add documentation above the Props type:

/**
 * Props for the Paginate component
 * @property {string} className - Optional CSS classes to override or extend the default styling.
 *                               Note: Be cautious with flex/responsive utilities as they might conflict with built-in styles.
 */
type Props = {
apps/web/components/pages/team/tasks/DropdownMenuTask.tsx (2)

16-25: Consider optimizing member lookup for better performance.

The current member lookup using array.find() has O(n) complexity. For better performance with large teams, consider using a Map or maintaining a lookup object.

const DropdownMenuTask: FC<{ task: ITeamTask }> = ({ task }) => {
	const { activeTeam } = useOrganizationTeams();
	const router = useRouter();
	const { user } = useAuthenticateUser();
-	const member = activeTeam?.members.find((m) => m?.employee?.user?.id === user?.id);
+	// Create a lookup map when team data changes
+	const memberMap = useMemo(() => {
+		const map = new Map();
+		activeTeam?.members.forEach((m) => {
+			if (m?.employee?.user?.id) {
+				map.set(m.employee.user.id, m);
+			}
+		});
+		return map;
+	}, [activeTeam?.members]);
+	const member = user?.id ? memberMap.get(user.id) : undefined;

38-64: Enhance button accessibility.

While the button includes a screen reader text, it could benefit from additional ARIA attributes for better accessibility.

<Button 
	variant="ghost" 
	className="h-8 w-8 p-0 dark:text-gray-200 text-[#292D32]"
+	aria-haspopup="true"
+	aria-expanded="false"
+	aria-label="Task options menu"
>
apps/web/lib/components/combobox/index.tsx (4)

36-39: Consider more descriptive state variable names.

The popoverWidth state could be renamed to triggerWidth or buttonWidth since it specifically stores the width of the trigger button.

-const [popoverWidth, setPopoverWidth] = React.useState<number | null>(null);
+const [triggerWidth, setTriggerWidth] = React.useState<number | null>(null);

41-48: Consider adding type safety to handleSelect function.

The currentValue parameter could be more strictly typed to match the return type of itemToValue.

-const handleSelect = (currentValue: string) => {
+const handleSelect = (currentValue: ReturnType<typeof itemToValue>) => {

50-54: Consider optimizing the width calculation effect.

The effect could be simplified by using a ResizeObserver for more efficient width tracking, especially useful if the button width changes dynamically.

 React.useEffect(() => {
+  const observer = new ResizeObserver((entries) => {
+    const [entry] = entries;
+    setPopoverWidth(entry.contentRect.width);
+  });
+
   if (triggerRef.current) {
-    setPopoverWidth(triggerRef.current.offsetWidth);
+    observer.observe(triggerRef.current);
   }
+
+  return () => observer.disconnect();
 }, [triggerRef.current]);

90-105: Consider enhancing keyboard navigation feedback.

While the component has good accessibility features, the CommandItem could benefit from more visible focus states for keyboard navigation.

 <CommandItem
   className={cn(
     'w-full dark:bg-dark--theme-light',
+    'focus:ring-2 focus:ring-offset-2 focus:ring-primary focus:outline-none',
     className
   )}
   key={itemToValue(item)}
   value={itemToValue(item)}
   onSelect={() => handleSelect(itemToValue(item))}
 >
apps/web/app/interfaces/ITask.ts (1)

Line range hint 119-124: Redundant type definitions for issue types.

There are two similar type definitions for issue types:

  1. ITaskIssue type
  2. IssueType enum

Consider consolidating these to avoid potential maintenance issues.

Consider using the enum as the type:

-export type ITaskIssue = 'Bug' | 'Task' | 'Story' | 'Epic';
+export type ITaskIssue = IssueType;

Also applies to: 126-131

apps/web/components/pages/team/tasks/columns.tsx (3)

102-109: Consider adding text truncation for long titles.

The title might overflow its container with long text. Consider adding text truncation.

 cell: ({ row }) => (
-  <div className="text-sm font-semibold text-indigo-950 dark:text-gray-200">{row.original.title}</div>
+  <div className="text-sm font-semibold text-indigo-950 dark:text-gray-200 truncate max-w-[300px]" title={row.original.title}>
+    {row.original.title}
+  </div>
 )

115-127: Consider extracting className configurations.

The hardcoded className values could be moved to a configuration object or CSS module for better maintainability.

const statusDropdownStyles = {
  wrapper: 'lg:max-w-[190px] w-full',
  status: 'text-xs py-1.5 w-full'
} as const;

// Then in the cell renderer
cell: ({ row }) => (
  <ActiveTaskStatusDropdown
    task={row.original}
    defaultValue={row.original.status}
    className={statusDropdownStyles.wrapper}
    taskStatusClassName={statusDropdownStyles.status}
  />
)

128-134: Consider adding error boundary for the action menu.

The DropdownMenuTask component might fail if the task data is malformed. Consider wrapping it in an error boundary.

import { ErrorBoundary } from '@/components/common/ErrorBoundary';

// In the cell renderer
cell: ({ row }) => (
  <ErrorBoundary fallback={<div>Failed to load actions</div>}>
    <DropdownMenuTask task={row.original} />
  </ErrorBoundary>
)
apps/web/lib/features/task/daily-plan/outstanding-date.tsx (2)

15-17: Consider adding proper typing for the profile prop.

Using any type reduces type safety. Consider defining a proper interface or type for the profile prop to improve type checking and code maintainability.

interface IOutstandingFilterDate {
-  profile: any;
+  profile: {
+    id: string;
+    // Add other required profile properties
+  };
}

110-112: Remove commented code.

The commented placeholder and "Plan tasks list" comment appear to be unnecessary. Consider removing them to maintain code cleanliness.

-                    {/* <>{provided.placeholder}</> */}
-                    {/* Plan tasks list */}
apps/web/lib/features/team-members.tsx (3)

96-96: Consider extracting repeated className into a constant.

The same className string "!overflow-x-auto !mx-0 px-1" is duplicated across multiple Container components. This could lead to maintenance issues if the styling needs to change.

Consider applying this refactor:

+ const CONTAINER_CLASSES = "!overflow-x-auto !mx-0 px-1";

// Then use it in all Container components like:
- <Container fullWidth={fullWidth} className="!overflow-x-auto !mx-0 px-1">
+ <Container fullWidth={fullWidth} className={CONTAINER_CLASSES}>

Also applies to: 113-113, 126-126, 149-149, 161-161


Line range hint 161-169: Consider removing redundant default case.

The default case duplicates the exact same logic as the IssuesView.CARDS case. This violates the DRY principle and could lead to maintenance issues.

Consider removing the default case and letting the CARDS case handle both scenarios:

- default:
-   teamMembersView = (
-     <Container fullWidth={fullWidth} className="!overflow-x-auto !mx-0 px-1">
-       <TeamMembersCardView
-         teamMembers={$members}
-         currentUser={currentUser}
-         publicTeam={publicTeam}
-         teamsFetching={teamsFetching}
-       />
-     </Container>
-   );

Line range hint 176-185: Consider improving the readability of sortByWorkStatus function.

The current implementation uses a long chain of conditions that's hard to read and maintain. Consider breaking it down into more readable parts.

Here's a suggested refactor:

const sortByWorkStatus = (user_a: OT_Member, user_b: OT_Member) => {
-  return user_a.timerStatus == 'running' ||
-    (user_a.timerStatus == 'online' && user_b.timerStatus != 'running') ||
-    (user_a.timerStatus == 'pause' && user_b.timerStatus !== 'running' && user_b.timerStatus !== 'online') ||
-    (user_a.timerStatus == 'idle' && user_b.timerStatus == 'suspended') ||
-    (user_a.timerStatus === undefined && user_b.timerStatus == 'suspended')
-    ? true
-    : false;
+  const statusPriority = {
+    'running': 1,
+    'online': 2,
+    'pause': 3,
+    'idle': 4,
+    'suspended': 5,
+    undefined: 4
+  };
+  return statusPriority[user_a.timerStatus] < statusPriority[user_b.timerStatus];
};

This approach:

  • Makes the priority order explicit and easy to modify
  • Reduces cognitive complexity
  • Is more maintainable
apps/web/lib/features/task/daily-plan/past-tasks.tsx (3)

17-26: Consider adding proper typing for the profile prop.

The profile prop is currently typed as any. Consider defining a proper interface or type for better type safety and code maintainability.

-export function PastTasks({ profile, currentTab = 'Past Tasks' }: { profile: any; currentTab?: FilterTabs }) {
+interface ProfileProps {
+  // Add relevant profile properties here
+  id: string;
+  // ... other properties
+}
+
+export function PastTasks({ profile, currentTab = 'Past Tasks' }: { profile: ProfileProps; currentTab?: FilterTabs }) {

28-71: Consider enhancing drag-and-drop accessibility.

The drag-and-drop functionality should include ARIA attributes and keyboard navigation support for better accessibility.

Consider adding aria labels and role attributes:

 <ul
   ref={provided.innerRef}
   {...provided.droppableProps}
+  role="list"
+  aria-label="Draggable task list"
   className={clsxm(
     // ... existing classes
   )}
 >

72-123: Consider extracting task rendering logic into separate components.

The task rendering logic contains complex conditional rendering with duplicate code between CARDS and TABLE views. Consider extracting this into separate components to improve maintainability and reduce code duplication.

Example refactor:

// TaskItem.tsx
interface TaskItemProps {
  task: Task;
  index: number;
  view: 'CARDS' | 'TABLE';
  plan: Plan;
  profile: ProfileProps;
  currentTab: FilterTabs;
}

const TaskItem = ({ task, index, view, plan, profile, currentTab }: TaskItemProps) => {
  return (
    <Draggable key={task.id} draggableId={task.id} index={index}>
      {(provided) => (
        <div
          ref={provided.innerRef}
          {...provided.draggableProps}
          {...provided.dragHandleProps}
          style={{
            ...provided.draggableProps.style,
            marginBottom: view === 'CARDS' ? 4 : 8
          }}
        >
          {view === 'CARDS' ? (
            <TaskCard
              // ... TaskCard props
            />
          ) : (
            <TaskBlockCard task={task} />
          )}
        </div>
      )}
    </Draggable>
  );
};
apps/web/components/nav-main.tsx (2)

41-64: Consider refactoring handleMenuToggle for better maintainability

While the implementation works, the handleMenuToggle function could be simplified and split for better maintainability and performance.

Consider this refactoring:

-const handleMenuToggle = (label: string, index: number) => {
-  setOpenMenus((prev) => ({
-    ...prev,
-    [label]: !prev[label]
-  }));
-
-  // Close all other sub-menus
-  setOpenMenus((prev) => {
-    const newState = { ...prev };
-    Object.keys(prev).forEach((key) => {
-      if (key !== label) {
-        newState[key] = false;
-      }
-    });
-    return newState;
-  });
-
-  setActiveMenuIndex(index);
-  setActiveSubMenuIndex(null);
-};
+const handleMenuToggle = (label: string, index: number) => {
+  setOpenMenus((prev) => {
+    const newState = Object.keys(prev).reduce((acc, key) => ({
+      ...acc,
+      [key]: key === label ? !prev[key] : false
+    }), {});
+    return newState;
+  });
+  
+  setActiveMenuIndex(index);
+  setActiveSubMenuIndex(null);
+};

This refactoring:

  1. Combines the two state updates into one
  2. Uses reduce for better readability
  3. Maintains the same functionality with less code

89-95: Simplify collapsed state rendering using component composition

The current implementation duplicates the collapsed state rendering logic. This can be simplified using component composition.

Consider extracting the icon rendering logic:

const MenuIcon = ({ icon: Icon, collapsed }: { icon: LucideIcon; collapsed: boolean }) => {
  if (collapsed) {
    return (
      <SidebarTriggerButton className="!p-0 !bg-inherit !text-inherit">
        <Icon />
      </SidebarTriggerButton>
    );
  }
  return <Icon />;
};

Then use it in both places:

-{state === 'collapsed' ? (
-  <SidebarTriggerButton className="!p-0 !bg-inherit !text-inherit">
-    <item.icon />
-  </SidebarTriggerButton>
-) : (
-  <item.icon />
-)}
+<MenuIcon icon={item.icon} collapsed={state === 'collapsed'} />

Also applies to: 119-125

apps/web/components/app-sidebar.tsx (3)

68-69: Consider memoizing the sorted tasks list.

The sort operation is performed on every render. Consider memoizing this operation using useMemo to optimize performance.

+ const sortedFavoriteTasks = useMemo(() => 
+   favoriteTasks.sort((a, b) => 
+     a.title.toLowerCase().localeCompare(b.title.toLowerCase())
+   ),
+   [favoriteTasks]
+ );

98-104: Add tooltip for truncated task titles.

The task title is truncated but users can't see the full text. Consider adding a tooltip.

 <span
   className={cn(
     '!font-light text-nowrap text-sm max-w-[100px] whitespace-nowrap text-ellipsis overflow-hidden'
   )}
+  title={task?.title}
 >
   {task?.title}
 </span>

155-162: Add tooltip for disabled create project button.

Users should understand why the create project button is disabled.

 <Button
   className="w-full text-xs mt-3 dark:text-white rounded-xl border-[0.0938rem]"
   variant="outline"
   disabled={!user?.isEmailVerified}
+  title={!user?.isEmailVerified ? t('common.VERIFY_EMAIL_TO_CREATE_PROJECT') : ''}
 >
   <PlusIcon className="w-4 h-4" />
   {t('common.CREATE_PROJECT')}
 </Button>
apps/web/lib/features/user-profile-plans.tsx (1)

447-449: Simplify the className template string.

The multi-line template string could be simplified for better readability.

-			className={`mb-6 flex ${
-				planMode === 'Future Tasks' ? 'justify-start' : 'justify-around'
-			}  items-center gap-5`}
+			className={`mb-6 flex items-center ${planMode === 'Future Tasks' ? 'justify-start gap-5' : 'justify-around gap-5'}`}
apps/web/components/ui/sidebar.tsx (2)

260-279: LGTM! Clean implementation of the new generic trigger button.

The new SidebarTriggerButton component follows the established patterns and provides a more flexible interface by accepting children for custom content.

Consider consolidating SidebarTrigger and SidebarTriggerButton into a single component since they share similar functionality. The existing SidebarTrigger could be implemented as a specialized version of SidebarTriggerButton.


280-281: Move the display name assignment.

The display name for SidebarTrigger should be moved before the SidebarTriggerButton definition to maintain a consistent code organization pattern.

apps/web/components/pages/team/tasks/tasks-data-table.tsx (3)

36-36: Use stable keys instead of index

Using indices as keys can lead to rendering issues in React. It's better to use a stable identifier like the status value.

Apply this change:

- key={index}
+ key={status}

47-54: Debounce search input to enhance performance

Consider debouncing the search input to prevent excessive re-renders and improve performance when filtering tasks.

You can implement debouncing like this:

+ import { useEffect, useState } from 'react';
+ import { debounce } from 'lodash';

  const [searchValue, setSearchValue] = useState('');

+ const debouncedSetFilter = useMemo(
+   () => debounce((value) => table.getColumn('title')?.setFilterValue(value), 300),
+   [table]
+ );

+ useEffect(() => {
+   debouncedSetFilter(searchValue);
+   return () => {
+     debouncedSetFilter.cancel();
+   };
+ }, [searchValue, debouncedSetFilter]);

  <Input
    placeholder="Search tasks..."
-   value={(table.getColumn('title')?.getFilterValue() as string) ?? ''}
-   onChange={(event) => table.getColumn('title')?.setFilterValue(event.target.value)}
+   value={searchValue}
+   onChange={(event) => setSearchValue(event.target.value)}
    className="max-w-sm pl-10 bg-transparent border-none placeholder:font-normal"
  />

147-170: Simplify getStatusColor function for maintainability

Refactor the getStatusColor function to use an object mapping. This improves readability and makes it easier to add or modify statuses in the future.

Apply this refactor:

- function getStatusColor(status: ITaskStatus) {
-   switch (status) {
-     case 'in-review':
-       return 'bg-[#f3d8b0]';
-     case 'backlog':
-       return 'bg-[#ffcc00]';
-     case 'open':
-       return 'bg-[#d6e4f9]';
-     case 'in-progress':
-       return 'bg-[#ece8fc]';
-     case 'ready-for-review':
-       return 'bg-[#f5f1cb]';
-     case 'blocked':
-       return 'bg-[#f5b8b8]';
-     case 'done':
-       return 'bg-[#4caf50] text-gray-100';
-     case 'completed':
-       return 'bg-[#d4efdf]';
-     case 'custom':
-       return 'bg-[#d4efdf]';
-     default:
-       return 'bg-gray-100 text-gray-800';
-   }
- }
+ const statusColors: Record<ITaskStatus, string> = {
+   'in-review': 'bg-[#f3d8b0]',
+   'backlog': 'bg-[#ffcc00]',
+   'open': 'bg-[#d6e4f9]',
+   'in-progress': 'bg-[#ece8fc]',
+   'ready-for-review': 'bg-[#f5f1cb]',
+   'blocked': 'bg-[#f5b8b8]',
+   'done': 'bg-[#4caf50] text-gray-100',
+   'completed': 'bg-[#d4efdf]',
+   'custom': 'bg-[#d4efdf]',
+ };
+
+ function getStatusColor(status: ITaskStatus) {
+   return statusColors[status] || 'bg-gray-100 text-gray-800';
+ }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between a48a46a and ccaef5b.

⛔ Files ignored due to path filters (2)
  • apps/web/public/assets/user-teams.png is excluded by !**/*.png
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (39)
  • .vscode/settings.json (1 hunks)
  • apps/web/app/[locale]/layout.tsx (3 hunks)
  • apps/web/app/[locale]/page-component.tsx (2 hunks)
  • apps/web/app/[locale]/permissions/component.tsx (2 hunks)
  • apps/web/app/[locale]/profile/[memberId]/page.tsx (1 hunks)
  • apps/web/app/[locale]/team/tasks/page.tsx (1 hunks)
  • apps/web/app/hooks/features/useAuthTeamTasks.ts (1 hunks)
  • apps/web/app/interfaces/ITask.ts (1 hunks)
  • apps/web/app/layout.tsx (1 hunks)
  • apps/web/app/stores/menu.ts (1 hunks)
  • apps/web/components/app-sidebar.tsx (3 hunks)
  • apps/web/components/nav-main.tsx (4 hunks)
  • apps/web/components/pages/task/description-block/task-description-editor.tsx (2 hunks)
  • apps/web/components/pages/task/details-section/blocks/task-main-info.tsx (2 hunks)
  • apps/web/components/pages/team/tasks/AssigneeUser.tsx (1 hunks)
  • apps/web/components/pages/team/tasks/DropdownMenuTask.tsx (1 hunks)
  • apps/web/components/pages/team/tasks/FilterButton.tsx (1 hunks)
  • apps/web/components/pages/team/tasks/StatusBadge.tsx (1 hunks)
  • apps/web/components/pages/team/tasks/TaskTable.tsx (1 hunks)
  • apps/web/components/pages/team/tasks/columns.tsx (1 hunks)
  • apps/web/components/pages/team/tasks/tasks-data-table.tsx (1 hunks)
  • apps/web/components/ui/sidebar.tsx (2 hunks)
  • apps/web/components/ui/table.tsx (4 hunks)
  • apps/web/lib/components/combobox/index.tsx (1 hunks)
  • apps/web/lib/components/pagination.tsx (1 hunks)
  • apps/web/lib/components/svgs/app-logo.tsx (1 hunks)
  • apps/web/lib/components/time-picker/index.tsx (1 hunks)
  • apps/web/lib/features/activity/components/screenshot-details.tsx (1 hunks)
  • apps/web/lib/features/integrations/calendar/calendar-component.tsx (1 hunks)
  • apps/web/lib/features/task/daily-plan/future-tasks.tsx (2 hunks)
  • apps/web/lib/features/task/daily-plan/outstanding-all.tsx (1 hunks)
  • apps/web/lib/features/task/daily-plan/outstanding-date.tsx (2 hunks)
  • apps/web/lib/features/task/daily-plan/past-tasks.tsx (2 hunks)
  • apps/web/lib/features/task/task-status.tsx (2 hunks)
  • apps/web/lib/features/team-members.tsx (6 hunks)
  • apps/web/lib/features/user-profile-plans.tsx (2 hunks)
  • apps/web/lib/layout/main-layout.tsx (1 hunks)
  • apps/web/locales/en.json (1 hunks)
  • apps/web/package.json (1 hunks)
✅ Files skipped from review due to trivial changes (8)
  • .vscode/settings.json
  • apps/web/app/[locale]/layout.tsx
  • apps/web/app/[locale]/profile/[memberId]/page.tsx
  • apps/web/components/pages/task/details-section/blocks/task-main-info.tsx
  • apps/web/lib/features/integrations/calendar/calendar-component.tsx
  • apps/web/lib/features/task/daily-plan/outstanding-all.tsx
  • apps/web/lib/features/task/task-status.tsx
  • apps/web/locales/en.json
🧰 Additional context used
🪛 Biome
apps/web/app/[locale]/page-component.tsx

[error] 123-123: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

apps/web/app/[locale]/permissions/component.tsx

[error] 29-29: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 45-45: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 51-51: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

apps/web/app/hooks/features/useAuthTeamTasks.ts

[error] 44-44: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

apps/web/components/pages/task/description-block/task-description-editor.tsx

[error] 41-41: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

apps/web/lib/components/time-picker/index.tsx

[error] 30-30: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

apps/web/lib/features/task/daily-plan/future-tasks.tsx

[error] 120-120: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

🔇 Additional comments (39)
apps/web/app/layout.tsx (1)

12-12: ⚠️ Potential issue

Critical: Restore HTML and body tags in root layout

The root layout must include html and body tags as per Next.js requirements. Removing these tags can break the application's HTML structure, affecting SEO, accessibility, and proper document rendering.

Apply this diff to restore the proper structure:

-return <>{children}</>;
+return (
+  <html lang="en">
+    <body>{children}</body>
+  </html>
+);

Let's verify if there are any other layout files that might be providing these tags:

apps/web/app/stores/menu.ts (2)

1-2: LGTM! Clean and well-organized imports.

The imports are correctly structured, following the pattern of importing core modules before utility modules.


7-8: LGTM! Well-structured active state management.

The use of nullable number types for menu indices is appropriate and provides clear inactive states.

apps/web/components/pages/team/tasks/AssigneeUser.tsx (2)

1-3: LGTM! Clean and well-organized imports.

The imports are properly structured and all are being utilized in the component.


28-28: LGTM! Clean export statement.

apps/web/app/[locale]/team/tasks/page.tsx (3)

1-13: LGTM! Well-organized imports.

The imports are properly organized and all dependencies are being used effectively in the component.


39-39: LGTM! Proper authentication implementation.

The component is correctly wrapped with authentication and includes a display name for better debugging.


29-37: Verify TaskTable configuration requirements.

The TaskTable component is rendered without any props. Please verify if it needs any configuration props for customization or pagination settings.

✅ Verification successful

Let me search for the TaskTable component definition to better understand its implementation.


Let me check the implementation of TaskTable component to understand its props requirements.


TaskTable component is correctly implemented without requiring props

The TaskTable component is self-contained and manages its own state through hooks:

  • Uses useTeamTasks hook to fetch and manage tasks data
  • Implements pagination using usePagination hook
  • Renders TasksDataTable with required props derived from internal state
  • Includes Paginate component with proper configuration

No additional configuration props are needed as the component handles all functionality internally.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for TaskTable component definition to check its props interface
ast-grep --pattern 'interface $TaskTableProps {
  $$$
}'

# Search for other TaskTable usages to see how it's configured elsewhere
rg -A 3 '<TaskTable'

Length of output: 303


Script:

#!/bin/bash
# Search for TaskTable component definition
ast-grep --pattern 'const TaskTable = $$$'

# Search for TaskTable component file
fd TaskTable

Length of output: 110


Script:

#!/bin/bash
# Check the TaskTable component implementation
cat apps/web/components/pages/team/tasks/TaskTable.tsx

Length of output: 1040

apps/web/app/hooks/features/useAuthTeamTasks.ts (2)

7-13: LGTM: Clean hook setup with proper state management

The hook initialization is well-structured with appropriate use of Jotai's state management.


56-62: LGTM: Clean return structure with new tasks property

The return object is well-organized and the addition of the tasks property is properly implemented.

apps/web/components/ui/table.tsx (8)

3-3: LGTM: Utility function import change is appropriate

The change to use cn from a centralized utils module is a good practice for maintaining consistent class name management across the application.


7-8: Improved table structure with responsive wrapper

The addition of a relative wrapper div with full width provides better control over table layout and responsiveness. The class merging is properly implemented using the new cn utility.


15-15: LGTM: Clear and explicit border styling

The border styling is now more explicitly defined using modern CSS selector syntax.


28-32: Enhanced footer styling with better visual hierarchy

The footer styling has been improved with:

  • Proper border handling
  • Subtle background color using opacity
  • Consistent font weight
  • Prevention of double borders

41-41: LGTM: Improved row interaction states

The row styling now includes proper state management for hover and selection, with smooth transitions.


52-55: LGTM: Well-structured heading cell styling

The heading cell styling provides good visual hierarchy with:

  • Consistent padding and alignment
  • Proper text styling for headers
  • Special handling for checkbox columns

64-64: LGTM: Clean and consistent cell styling

The cell styling maintains consistency with the table's design system.


71-71: LGTM: Appropriate caption styling

The caption styling properly integrates with the table's visual hierarchy.

apps/web/lib/layout/main-layout.tsx (1)

36-36: Verify overflow behavior with wide content.

The addition of overflow-x-hidden and min-w-fit improves layout stability, but please verify that no critical content gets clipped in various viewport sizes.

Let's check for potential overflow issues in the codebase:

✅ Verification successful

Based on the search results, I can now make a determination about the overflow behavior in the codebase:

No overflow issues with the updated layout class

The addition of overflow-x-hidden min-w-fit to the main layout's outer div is safe and consistent with the codebase's patterns:

  • The codebase already uses overflow-x-hidden in several container components to prevent unwanted horizontal scrolling
  • The min-w-fit ensures content won't be squeezed too narrow, working in tandem with the overflow control
  • Key scrollable areas like tables, grids and content sections have explicit overflow-x-auto where horizontal scrolling is needed
  • The layout change won't affect these intentionally scrollable areas since they have their own overflow controls
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Look for components or elements that might be affected by horizontal overflow

# Test 1: Search for wide elements or explicit width settings
rg -g '*.tsx' -g '*.jsx' -A 2 'w-\[.*px\]|width:|min-w-\[|max-w-\[|overflow-x-|scroll-x'

# Test 2: Search for horizontal scrolling containers that might be affected
rg -g '*.tsx' -g '*.jsx' -A 2 'overflow-x-scroll|overflow-x-auto'

# Test 3: Search for tables or grid layouts that might extend beyond viewport
rg -g '*.tsx' -g '*.jsx' -A 2 'table-|grid-cols-'

Length of output: 356998

apps/web/components/pages/team/tasks/FilterButton.tsx (1)

1-12: LGTM! Well-structured imports and type definitions.

The imports are properly organized and the generic type definition for FilterButtonProps follows TypeScript best practices.

apps/web/lib/components/pagination.tsx (3)

5-5: LGTM: Clean import of className utility

The addition of the cn utility import is appropriate for handling className merging.


13-13: LGTM: Well-typed className prop addition

The optional className prop is properly typed and integrates well with the existing Props type.


16-24: LGTM: Clean component signature update

The className prop is correctly added to the component's parameter destructuring.

apps/web/components/pages/team/tasks/DropdownMenuTask.tsx (2)

1-15: LGTM! Well-organized imports.

The imports are logically grouped and all dependencies are being used within the component.


92-92: LGTM! Proper component export.

The default export follows React component conventions.

apps/web/lib/components/combobox/index.tsx (2)

1-20: LGTM! Well-structured interface with comprehensive type definitions.

The interface is well-designed with clear property names and appropriate types. Good use of generics for type safety.


24-35: LGTM! Good use of Readonly type.

The addition of Readonly<ComboboxProps<T>> helps enforce immutability and prevents accidental prop mutations.

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

37-37: Type safety improvement for issueType property.

The change from string to ITaskIssue improves type safety by restricting values to predefined issue types.

Let's verify the impact of this type change:

✅ Verification successful

Let me verify the usage of issueType in the codebase to ensure there are no breaking changes.


Let me check the actual type definitions and usage to fully understand the change.


Type change is safe and consistent with codebase usage

The change from string to ITaskIssue in ITeamTask interface is safe because:

  1. All string literals used in the codebase for issueType match the ITaskIssue type values: 'Bug', 'Task', 'Story', 'Epic'
  2. The ICreateTask interface retains string type for issueType which is appropriate for input/creation scenarios
  3. The enum IssueType aligns with the ITaskIssue type values, providing type safety at runtime
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential breaking changes in issue type usage
# Look for direct string assignments to issueType that might break with the new type
rg -A 2 "issueType.*=.*['\"](Bug|Task|Story|Epic)['\"]" 

Length of output: 20959


Script:

#!/bin/bash
# Check for any direct string assignments to issueType that might break with the new type
rg "issueType\s*=\s*[^=]" --type ts

# Check the interface definition to understand the type change
rg "interface.*ITeamTask" -A 10

Length of output: 1512


Script:

#!/bin/bash
# Check the ITaskIssue type definition and related types
rg "type.*ITaskIssue|enum.*IssueType" -A 5

# Check the ICreateTask interface to understand the inconsistency mentioned
rg "interface.*ICreateTask" -A 15

Length of output: 4044

apps/web/components/pages/team/tasks/columns.tsx (1)

1-7: LGTM! Imports are clean and well-organized.

apps/web/lib/features/task/daily-plan/outstanding-date.tsx (2)

18-21: LGTM! Clean state management implementation.

The component properly initializes state using appropriate React hooks and follows best practices for state management.


25-27: Consider adding error handling for drag and drop operations.

The onDragEnd callback should include error handling to gracefully handle failed drag operations and provide user feedback.

<DragDropContext
  onDragEnd={(result) => {
+   try {
      handleDragAndDrop(result, outstandingTasks, setOutstandingTasks)
+   } catch (error) {
+     console.error('Failed to reorder task:', error);
+     // Consider adding a toast notification here
+   }
  }}
>
apps/web/package.json (1)

70-70: LGTM! Please verify testing with new components.

The update to @tanstack/react-table from ^8.10.7 to ^8.20.5 maintains major version compatibility while providing access to new features needed for the task list view components.

Please ensure the new version has been tested with the introduced components. Run the following to check for any potential breaking changes in the minor versions:

✅ Verification successful

Let me analyze the results and generate additional verification scripts to check the usage of @tanstack/react-table in the components.


Let me check the actual implementation details of these components to verify the usage of the updated library version.


Version update is safe to proceed

The update to @tanstack/react-table from ^8.10.7 to ^8.20.5 is verified to be compatible with the current implementation. The components are using standard table features (useReactTable, getCoreRowModel, getFilteredRowModel) that are stable across minor versions of v8.x.x.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for breaking changes in @tanstack/react-table between versions

# Test: Search for any migration guides or breaking changes in the repository
rg -i "breaking.*changes|migration.*guide" $(fd -t f . -E "node_modules" -E "dist" -E "build")

# Test: Check if the new components are importing any potentially renamed or moved exports
rg "@tanstack/react-table" $(fd "TaskTable|FilterButton" -t f)

Length of output: 92163


Script:

#!/bin/bash
# Check how @tanstack/react-table is being used in the components
ast-grep --pattern 'import { $_ } from "@tanstack/react-table"' apps/web/components/pages/team/tasks/TaskTable.tsx apps/web/components/pages/team/tasks/FilterButton.tsx

# Check for any table-related components that might be using the library
rg -l "Table|useReactTable|ColumnDef" apps/web/components/pages/team/tasks/

Length of output: 460


Script:

#!/bin/bash
# Check the implementation details of table components
rg -A 5 "@tanstack/react-table" apps/web/components/pages/team/tasks/tasks-data-table.tsx apps/web/components/pages/team/tasks/columns.tsx apps/web/components/pages/team/tasks/TaskTable.tsx

# Check for any specific features or APIs being used
rg "useReactTable|getCoreRowModel|getSortedRowModel|getFilteredRowModel" apps/web/components/pages/team/tasks/*.tsx

Length of output: 2596

apps/web/lib/features/team-members.tsx (1)

22-22: LGTM! Good type safety improvement.

The change to Readonly<TeamMembersProps> enforces immutability of props, which is a React best practice and helps prevent accidental mutations.

apps/web/lib/features/task/daily-plan/past-tasks.tsx (1)

Line range hint 1-14: LGTM! Import statements are well-organized.

The imports are logically grouped and include all necessary dependencies for the component's functionality.

apps/web/app/[locale]/page-component.tsx (1)

65-65: LGTM! Height class modification improves layout flexibility.

The change from h-screen to h-full min-h-screen is a good improvement that allows the container to grow with content while maintaining a minimum viewport height.

apps/web/lib/components/svgs/app-logo.tsx (1)

4-4: LGTM! Good use of Next.js Image component

Using next/image instead of the standard HTML img tag is a good practice as it provides automatic image optimization, lazy loading, and prevents layout shifts.

apps/web/components/nav-main.tsx (1)

2-2: LGTM: Clean state management implementation

The implementation of state management using Jotai atoms is well-structured and follows React best practices. The state variables are appropriately named and their purposes are clear.

Also applies to: 19-19, 37-39

apps/web/lib/features/user-profile-plans.tsx (1)

285-285: LGTM! Improved scrolling behavior.

The change from overflow-x-scroll to overflow-x-auto is a good improvement as it provides better UX by only showing scrollbars when necessary.

apps/web/components/ui/sidebar.tsx (1)

678-678: LGTM! Proper export of the new component.

The new component is correctly exported alongside other sidebar components.

Copy link

Report too large to display inline

View full report↗︎

@evereq evereq merged commit 25e31d8 into develop Nov 6, 2024
13 of 14 checks passed
@evereq evereq deleted the 3108-feature/-task-list-view-all-tasks-in-a-team branch November 6, 2024 18:07
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
2 participants