Skip to content

feat: Search bar in persons table#3169

Merged
mattinannt merged 9 commits intomainfrom
search-bar-in-persons-table
Sep 27, 2024
Merged

feat: Search bar in persons table#3169
mattinannt merged 9 commits intomainfrom
search-bar-in-persons-table

Conversation

@Dhruwang
Copy link
Member

@Dhruwang Dhruwang commented Sep 23, 2024

What does this PR do?

Fixes #3144

Screen-Recording-2024-09-23-at-4.38.10.PM.mp4

How should this be tested?

Test search functionality on persons page

Checklist

Required

  • Filled out the "How to test" section in this PR
  • Read How we Code at Formbricks
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand bits
  • Ran pnpm build
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues
  • First PR at Formbricks? Please sign the CLA! Without it we wont be able to merge it 🙏

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR
  • Updated the Formbricks Docs if changes were necessary

Summary by CodeRabbit

Release Notes

  • New Features
    • Introduced a new SearchBar component for improved search input handling across various sections.
    • Enhanced search functionality in the People module, allowing users to filter results based on search criteria.
    • Updated the PersonTable to support dynamic column rendering based on search input.
  • Improvements
    • Updated the PersonDataView component to simplify its interface and improve search input management.
    • Adjusted the number of items displayed per page from 50 to 30 for a more manageable view.
    • Enhanced the display of search results with highlighted text based on search criteria.
  • Bug Fixes
    • Resolved issues related to the previous pagination approach, ensuring smoother data retrieval.

@vercel
Copy link

vercel bot commented Sep 23, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
formbricks-cloud ⬜️ Ignored (Inspect) Visit Preview Sep 27, 2024 9:13am
formbricks-docs ⬜️ Ignored (Inspect) Visit Preview Sep 27, 2024 9:13am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 23, 2024

Walkthrough

The changes introduced in this pull request enhance the functionality of the people management module by adding a search feature. The SearchBar component replaces the SearchBox, and the PersonDataView component has been simplified to manage search input directly. The pagination system has shifted from a page-based to an offset-based approach, allowing for more efficient data fetching based on search criteria.

Changes

Files Change Summary
apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/templates/components/TemplateContainer.tsx
apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonDataView.tsx
- Replaced SearchBox with SearchBar for improved search functionality. Simplified PersonDataView by removing personCount and adjusting internal state management to utilize searchValue. Updated data fetching logic to use searchValue for querying persons.
apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonTable.tsx - Updated PersonTable to incorporate a search feature, adding searchValue and setSearchValue props. Introduced a SearchBar for user input, modifying the table's structure for better responsiveness.
apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonTableColumn.tsx - Modified generatePersonTableColumns to accept searchValue, enhancing the rendering of specific fields with HighlightedText based on search criteria.
apps/web/app/(app)/environments/[environmentId]/(people)/people/page.tsx - Removed getPersonCount import and adjusted PersonDataView props to only include environment, simplifying the data passed to it.
packages/lib/constants.ts - Updated the constant ITEMS_PER_PAGE from 50 to 30, affecting the number of items displayed per page.

Assessment against linked issues

Objective Addressed Explanation
Add a search bar to the People view (#3144)

Possibly related PRs

  • feat: Data table for persons #3154: The PersonTable.tsx component introduces a search feature that is directly related to the changes made in the TemplateContainer.tsx, where the SearchBox was replaced with the SearchBar.
  • fix: person loading skeleton #3160: The changes in PersonDataView.tsx enhance the data fetching logic, which may interact with the search functionality in TemplateContainer.tsx, as both components deal with displaying and managing person-related data.
  • fix: improved person fetching #3161: The modifications in PersonDataView.tsx streamline the fetching of person data, which is relevant to the overall data management and search capabilities being implemented in the related components.

Suggested labels

🙋🏻‍♂️help wanted, 🕹️ oss.gg, 🕹️ 50 points, 🕹️ Level 1

Suggested reviewers

  • jobenjada
  • gupta-piyush19

🐰 In the meadow where bunnies play,
A search bar blooms to light the way.
With highlighted text, we find our friends,
No more lost names, the searching ends!
Hopping through data, oh what a sight,
Thanks to these changes, all feels just right! 🌼


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between b839719 and 3ed9a12.

📒 Files selected for processing (1)
  • packages/lib/constants.ts (1 hunks)
🔇 Additional comments (1)
packages/lib/constants.ts (1)

77-77: Approve with clarification request: ITEMS_PER_PAGE reduction

The change from 50 to 30 items per page improves consistency with other pagination constants in the file (e.g., SURVEYS_PER_PAGE: 12, RESPONSES_PER_PAGE: 20). This could potentially improve initial load times for the persons table.

However, I have a few points to consider:

  1. Could you please clarify the rationale behind this specific change? Is it related to optimizing the display of search results mentioned in the PR objectives?

  2. Have you verified the impact of this change on:
    a) The overall user experience (e.g., frequency of pagination interactions)?
    b) Performance metrics (e.g., number of API calls, load times)?

  3. Ensure that this change is consistently applied across the codebase, especially in components that rely on this constant for pagination or data fetching.

To help verify the usage and impact of this change, you can run the following script:

This will help identify areas of the code that might need adjustment due to this change.


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.

@Dhruwang Dhruwang requested a review from jobenjada September 23, 2024 11:14
@github-actions github-actions bot added customer request enhancement New feature or request labels Sep 23, 2024
@github-actions
Copy link
Contributor

github-actions bot commented Sep 23, 2024

Thank you for following the naming conventions for pull request titles! 🙏

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

Outside diff range and nitpick comments (6)
packages/types/common.ts (1)

9-10: LGTM! Consider adding a type alias for consistency.

The addition of ZOptionalString is a valuable enhancement to the common types. It follows the established naming convention and is placed logically within the file.

For consistency with other schemas in this file, consider adding a type alias:

export type TOptionalString = z.infer<typeof ZOptionalString>;

This would align with the pattern used for TPlacement and TAllowedFileExtension.

apps/web/app/(app)/environments/[environmentId]/(people)/people/page.tsx (1)

Incomplete Removal of getPersonCount Import

The ITEMS_PER_PAGE import has been successfully removed. However, getPersonCount is still being used in the following files:

  • apps/web/app/(app)/environments/[environmentId]/(people)/people/actions.ts:

    • Imports: getPersonCount
    • Usage: getPersonCount(parsedInput.environmentId, parsedInput.searchValue);
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonDataView.tsx:

    • Utilizes getPersonCountAction

Please ensure that all usages of getPersonCount are addressed to complete the refactoring.

Analysis chain

Line range hint 1-8: Verify removal of imports and its implications

The AI summary mentions the removal of ITEMS_PER_PAGE and getPersonCount imports, which are not visible in the current code. This change aligns with the simplified props passed to PersonDataView.

Please confirm:

  1. These imports have indeed been removed.
  2. The pagination logic has been moved to the PersonDataView component or another part of the application.
  3. The person count is now being handled differently, possibly within PersonDataView.

To confirm the removal of imports, run:

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any remaining usage of ITEMS_PER_PAGE and getPersonCount
rg --type typescript 'ITEMS_PER_PAGE|getPersonCount' apps/web/app/\(app\)/environments/\[environmentId\]/\(people\)/people/

Length of output: 156


Script:

#!/bin/bash
# Check for any remaining usage of ITEMS_PER_PAGE and getPersonCount
rg 'ITEMS_PER_PAGE|getPersonCount' apps/web/app/\(app\)/environments/\[environmentId\]/\(people\)/people/

Length of output: 814

apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonTable.tsx (1)

156-163: LGTM: Search input field added.

The search input field is correctly implemented using the Input component, with the value and onChange props properly set to use searchValue and setSearchValue. The placement before the table is appropriate for user experience.

Consider adding an aria-label to the Input component for improved accessibility:

 <Input
   type="text"
   placeholder="Search"
   value={searchValue}
   onChange={(e) => setSearchValue(e.target.value)}
+  aria-label="Search persons"
 />
apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonDataView.tsx (1)

Line range hint 23-50: Refactor debouncedFetchData to avoid redefining it on every render.

Defining debouncedFetchData inside the useEffect causes a new debounced function to be created each time searchValue changes, which may prevent the debounce from working as intended. Consider moving debouncedFetchData outside of the useEffect and memoizing it to ensure consistent debounce behavior.

Apply this refactor:

-  useEffect(() => {
-    const fetchData = async () => {
-      setIsDataLoaded(false);
-      try {
-        const getPersonActionData = await getPersonsAction({
-          environmentId: environment.id,
-          offset: 0,
-          searchValue,
-        });
-        if (getPersonActionData?.data) {
-          setPersons(getPersonActionData.data);
-        }
-      } catch (error) {
-        console.error("Error fetching people data:", error);
-      } finally {
-        setIsDataLoaded(true);
-      }
-    };
-
-    const debouncedFetchData = debounce(fetchData, 300);
-    debouncedFetchData();
-
-    return () => {
-      debouncedFetchData.cancel();
-    };
-  }, [searchValue]);
+  const fetchData = useCallback(async () => {
+    setIsDataLoaded(false);
+    try {
+      const getPersonActionData = await getPersonsAction({
+        environmentId: environment.id,
+        offset: 0,
+        searchValue,
+      });
+      if (getPersonActionData?.data) {
+        setPersons(getPersonActionData.data);
+      }
+    } catch (error) {
+      console.error("Error fetching people data:", error);
+    } finally {
+      setIsDataLoaded(true);
+    }
+  }, [environment.id, searchValue]);
+
+  const debouncedFetchData = useMemo(
+    () => debounce(fetchData, 300),
+    [fetchData]
+  );
+
+  useEffect(() => {
+    debouncedFetchData();
+    return () => {
+      debouncedFetchData.cancel();
+    };
+  }, [debouncedFetchData]);

This refactor ensures that debouncedFetchData is memoized and isn't redefined on every render, allowing the debounce to function correctly.

packages/lib/person/service.ts (2)

99-99: Remove unnecessary type casting to 'Prisma.QueryMode'

The explicit casting as Prisma.QueryMode is unnecessary since the mode property accepts string literals 'default' and 'insensitive'. Removing the casts simplifies the code without affecting functionality.

Apply this diff to remove the unnecessary casts:

       contains: search,
-      mode: "insensitive" as Prisma.QueryMode,
+      mode: "insensitive",

Also applies to: 107-107, 115-115


93-119: Consider adding database indexes to improve search performance

Since you're adding search functionality on userId, attributes.value, and id, consider adding indexes on these fields to enhance query performance, especially with large datasets.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 25774f6 and 86887fe.

Files selected for processing (8)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/actions.ts (2 hunks)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonDataView.tsx (3 hunks)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonTable.tsx (5 hunks)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonTableColumn.tsx (4 hunks)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/page.tsx (1 hunks)
  • packages/lib/person/service.ts (4 hunks)
  • packages/types/common.ts (1 hunks)
  • packages/ui/HighlightedText/index.tsx (1 hunks)
Additional comments not posted (24)
packages/ui/HighlightedText/index.tsx (1)

1-4: LGTM: Well-defined interface

The HighlightedTextProps interface is clear, concise, and follows good naming conventions. Both value and searchValue properties are appropriately typed as strings.

packages/types/common.ts (1)

9-10: Approved: Beneficial addition to common types

The introduction of ZOptionalString is a valuable addition to the common types. It:

  1. Enhances the reusability of schemas across the project.
  2. Potentially supports the search functionality mentioned in the PR objectives.
  3. Maintains consistency with existing schemas.
  4. Is a non-breaking change that integrates well with the existing codebase.

This change is approved and should positively impact the project's type safety and development efficiency.

apps/web/app/(app)/environments/[environmentId]/(people)/people/page.tsx (2)

Line range hint 1-38: Summary: Changes align with PR objectives and improve code structure

The modifications in this file, particularly the simplification of the PersonDataView component usage, align well with the PR objectives of adding a search bar to the People view. By moving data management logic (likely including the new search functionality) into the PersonDataView component, the code becomes more modular and maintainable.

These changes suggest:

  1. Improved separation of concerns, with data fetching and management closer to where it's used.
  2. Potential performance improvements due to more localized state management.
  3. A more flexible structure that can accommodate the new search functionality.

To fully validate these changes:

  1. Ensure that the search functionality is properly implemented in the PersonDataView component.
  2. Verify that all existing functionality (pagination, displaying person count if applicable) still works correctly.
  3. Check for any performance improvements in the People view, especially with large datasets.

Run the following to check for search-related changes:

#!/bin/bash
# Search for new search-related code in PersonDataView and related components
rg --type typescript 'search|filter' apps/web/app/\(app\)/environments/\[environmentId\]/\(people\)/people/components/

32-32: Approve simplified PersonDataView props and verify data flow

The simplification of PersonDataView props is a good change. It suggests that the component is now more self-contained in terms of managing pagination and person count.

To ensure the change doesn't introduce any issues:

  1. Verify that pagination still works correctly in the UI.
  2. Check that the person count is still accurately displayed (if it's shown in the UI).
  3. Review the PersonDataView component to ensure it properly handles fetching and managing the data internally.

Run the following to inspect the PersonDataView component:

Verification successful

Verified: PersonDataView component correctly manages its data flow

The updated PersonDataView component now handles data fetching and pagination internally by only receiving the environment prop. This simplification aligns with modern React practices and maintains functionality without introducing issues.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Display the content of PersonDataView component
cat apps/web/app/\(app\)/environments/\[environmentId\]/\(people\)/people/components/PersonDataView.tsx

Length of output: 151


Script:

#!/bin/bash
# Find the PersonDataView.tsx file and display its content
file_path=$(fd "PersonDataView\.tsx$" . --type f)
if [ -n "$file_path" ]; then
  cat "$file_path"
else
  echo "PersonDataView.tsx not found."
fi

Length of output: 3824

apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonTableColumn.tsx (6)

7-7: LGTM: Import statement for HighlightedText

The import statement for the HighlightedText component is correctly placed and follows the existing import style. This component will be used to highlight search results in the table, which aligns with the PR objectives.


9-12: LGTM: Updated function signature

The function signature has been correctly updated to include the searchValue parameter. This change aligns with the PR objectives to implement a search feature in the persons table. The existing isExpanded parameter is retained, ensuring that the current functionality is preserved.


47-47: LGTM: Updated userColumn and userIdColumn rendering

The userColumn and userIdColumn have been updated to use the HighlightedText component for rendering. This change allows for highlighting of search results in these columns, which enhances the search functionality as per the PR objectives. The searchValue is correctly passed to the HighlightedText component in both cases.

Also applies to: 56-56


63-68: LGTM: Updated emailColumn rendering

The emailColumn has been updated to conditionally render the HighlightedText component. This change ensures that the email is highlighted only when it exists, which is a good practice for handling potentially undefined values. The searchValue is correctly passed to the HighlightedText component, aligning with the search functionality requirements.


84-85: LGTM: Updated attributesColumn rendering

The attributesColumn has been updated to use the HighlightedText component for rendering attribute values. This change allows for highlighting of search results in the attributes, which enhances the search functionality as per the PR objectives. The existing structure for rendering attributes is maintained, ensuring consistency with the current implementation.


Line range hint 1-94: Summary: Successful implementation of search functionality

The changes in this file successfully implement the search functionality for the persons table, aligning well with the PR objectives. The HighlightedText component is consistently used across different columns (user, userId, email, and attributes) to highlight search results. The function signature has been appropriately updated to include the searchValue parameter.

These changes enhance the user experience by allowing easy location of specific individuals within the application, addressing the issue described in #3144. The implementation is consistent and follows good practices, maintaining existing functionality while adding the new search feature.

apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonTable.tsx (5)

22-22: LGTM: Input component import added.

The import of the Input component is correctly added, which is necessary for the new search functionality implemented in this component.


33-34: LGTM: Search-related props added to PersonTableProps.

The searchValue and setSearchValue props are correctly added to the PersonTableProps interface. These props are essential for managing the search state and functionality, aligning with the PR objective.


44-45: LGTM: Search props added to PersonTable component.

The searchValue and setSearchValue props are correctly destructured from the component's props, corresponding to the interface changes. This allows the search functionality to be controlled from the parent component.


54-57: LGTM: searchValue added as dependency to columns useMemo.

The searchValue is correctly added as a dependency to the columns useMemo hook. This ensures that the columns are recalculated when the search value changes, which is necessary for features like highlighting search results in the table.


Line range hint 1-265: Overall implementation of search functionality looks good.

The changes made to the PersonTable component successfully implement the search functionality as described in the PR objectives. The new props, interface changes, and the addition of the search input field are all correctly implemented and work together cohesively.

The changes align well with the AI-generated summary and address the issue #3144 by adding a search bar to the People view, making it easier for users to find specific individuals.

Great job on this implementation! The only suggestion is a minor accessibility improvement for the search input field.

apps/web/app/(app)/environments/[environmentId]/(people)/people/actions.ts (8)

8-8: Import getPersonCount aligns with new functionality.

The added import of getPersonCount from @formbricks/lib/person/service is appropriate for the new action introduced later in the code.


13-14: Updated schema includes offset and optional searchValue.

The ZGetPersonsAction schema now includes an offset and an optional searchValue, which aligns with the updated pagination and search functionalities.


26-27: Updated getPeople function call with new parameters.

The getPeople function is now called with parsedInput.environmentId, parsedInput.offset, and parsedInput.searchValue, matching the updated signature and supporting the new search and pagination features.


29-32: New schema ZGetPersonCountAction correctly defines input parameters.

The schema includes environmentId and an optional searchValue, which are necessary for retrieving the count of persons based on the search criteria.


34-44: New action getPersonCountAction is properly implemented.

The action includes authorization checks and calls getPersonCount with the appropriate parameters. This implementation correctly adds the functionality to retrieve the total count of persons based on the environmentId and searchValue.


14-14: Sanitize searchValue to prevent injection attacks.

While using searchValue in database queries, ensure it's properly sanitized to prevent SQL injection or other types of injection attacks.

[security]

Verify that getPeople and getPersonCount handle searchValue securely, or sanitize it before use.

Also applies to: 31-31


37-41: Authorization checks are consistent with existing actions.

The authorization logic in getPersonCountAction mirrors that of getPersonsAction, ensuring that only authorized users can access the person count.


26-26: Verify consistent usage of service functions.

Ensure that the updated service functions getPeople and getPersonCount are consistently used throughout the codebase, and any deprecated functions are removed.

Run the following script to check for deprecated service function usage:

Also applies to: 43-43

packages/lib/person/service.ts (1)

5-5: Import of optional validators is appropriate

The import statement correctly brings in ZOptionalNumber and ZOptionalString for validating optional parameters.

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 (1)
packages/lib/person/service.ts (1)

Impact of Pagination Changes Detected in route.ts

  • apps/web/app/api/v1/management/people/route.ts is still using the old getPeople signature with only environmentId.
Analysis chain

Line range hint 122-148: Verify the impact of pagination changes on the codebase.

The shift from page-based to offset-based pagination may affect other parts of the application that rely on the previous pagination method. Ensure that all components interacting with getPeople are updated accordingly.

Run the following script to identify usages of getPeople:

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all usages of 'getPeople' in the codebase to verify pagination changes.

# Test: Search for 'getPeople('. Expect: Update calls to match the new signature.
rg --type ts --type js -A 2 'getPeople\('

Length of output: 657

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 86887fe and eb5edb1.

Files selected for processing (3)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/actions.ts (2 hunks)
  • packages/lib/person/service.ts (4 hunks)
  • packages/ui/HighlightedText/index.tsx (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/actions.ts
  • packages/ui/HighlightedText/index.tsx
Additional comments not posted (4)
packages/lib/person/service.ts (4)

93-119: LGTM! The past review comment has been addressed.

The function correctly handles the search parameter by conditionally including the OR clause only when search is provided. The mode: "insensitive" option is used without type casting.


122-131: LGTM! The past review comment has been addressed.

The function correctly uses the buildPersonWhereClause function to construct the where clause based on the searchValue parameter. The offset parameter is used for pagination instead of the previous page parameter.


143-143: LGTM! The past review comment has been addressed.

The cache key correctly defaults searchValue to an empty string when it's undefined to ensure consistent cache keys.


Line range hint 151-173: LGTM! The past review comment has been addressed.

The function correctly uses the buildPersonWhereClause function to construct the where clause based on the searchValue parameter. The cache key correctly defaults searchValue to an empty string when it's undefined to ensure consistent cache keys.

Copy link
Member

@jobenjada jobenjada left a comment

Choose a reason for hiding this comment

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

Hey Dhru!

Thanks for the PR.

Please make the following changes:

  1. (For all data tables) - Default full width
image Increase the width of the last column (Attributes) to fill the width of the page
  1. Replace the Search bar with the one from the Survey page (make it a component first):
image

And since you're on it, pls replace this one with it as well
image

  1. Address the code rabbit suggestions (if you didn't do that yet)

Rest seems good :)

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 (4)
packages/ui/SearchBar/index.tsx (2)

15-25: LGTM: Component structure and styling are well-implemented.

The JSX structure is clean, and Tailwind CSS classes are used effectively for styling. The input field is correctly implemented as a controlled component with proper event handling.

Consider adding an aria-label to the input field for improved accessibility. You can add it like this:

 <input
   type="text"
   className="ml-2 w-full border-none bg-transparent placeholder:text-sm focus:outline-none"
   placeholder={placeholder}
   value={value}
   onChange={(e) => onChange(e.target.value)}
+  aria-label="Search"
 />

1-27: Great job on implementing the SearchBar component!

The component is well-structured, follows React and TypeScript best practices, and aligns perfectly with the PR objectives of adding search functionality to the persons table. It's designed to be reusable and easily integrated into the existing UI.

For future enhancements, consider adding debounce functionality to the onChange handler. This can help reduce unnecessary API calls if the search is performed on each keystroke. Here's an example of how you could implement this:

import { debounce } from 'lodash';
import React, { useCallback } from 'react';

// ... (rest of the imports and interface)

export const SearchBar: React.FC<SearchBarProps> = ({
  value,
  onChange,
  placeholder = "Search by survey name",
}) => {
  const debouncedOnChange = useCallback(
    debounce((value: string) => onChange(value), 300),
    [onChange]
  );

  return (
    // ... (rest of the JSX)
    <input
      // ... (other props)
      onChange={(e) => debouncedOnChange(e.target.value)}
    />
    // ... (rest of the JSX)
  );
};

This enhancement would improve performance by reducing the frequency of search operations, especially useful when integrated with API calls.

packages/ui/DataTable/components/SelectionColumn.tsx (1)

Inconsistent Function Declaration Style Detected

Multiple TypeScript files in the codebase still use standard function declarations. To maintain consistency, consider refactoring these to arrow functions across the codebase.

Analysis chain

Line range hint 6-31: LGTM! Consider verifying consistency across the codebase.

The change from a standard function declaration to a constant arrow function is correct and doesn't affect the functionality. This aligns with modern JavaScript/TypeScript practices.

To ensure consistency across the codebase, you may want to verify if similar changes have been made to other exported functions. Run the following script to check for any remaining standard function declarations in TypeScript files:

If the script returns many results, consider creating a separate issue to track the refactoring of other functions for consistency.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for standard function declarations in TypeScript files

# Test: Search for standard function declarations. Expect: No or few occurrences.
rg --type typescript 'export function' -g '!*.d.ts'

Length of output: 88


Script:

#!/bin/bash
# Description: Check for standard function declarations in TypeScript files

# Test: Search for standard function declarations. Expect: No or few occurrences.
rg --type ts 'export function' -g '!*.d.ts'

Length of output: 4814

packages/ui/SurveysList/components/SurveyFilters.tsx (1)

139-139: LGTM: SearchBar component implemented correctly

The SearchBar component is well-integrated into the existing structure, replacing the manual search input implementation. This change improves code readability and maintainability.

For consistency with other state variables, consider renaming 'name' to 'searchValue' or similar. This would make it clearer that this state is specifically for the search functionality.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between eb5edb1 and 80d861c.

Files selected for processing (8)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/templates/components/TemplateContainer.tsx (2 hunks)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonTable.tsx (6 hunks)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonTableColumn.tsx (4 hunks)
  • apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/components/ResponseTable.tsx (1 hunks)
  • packages/ui/DataTable/components/SelectionColumn.tsx (2 hunks)
  • packages/ui/SearchBar/index.tsx (1 hunks)
  • packages/ui/SearchBox/index.tsx (0 hunks)
  • packages/ui/SurveysList/components/SurveyFilters.tsx (3 hunks)
Files not reviewed due to no reviewable changes (1)
  • packages/ui/SearchBox/index.tsx
Files skipped from review as they are similar to previous changes (1)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonTableColumn.tsx
Additional comments not posted (16)
packages/ui/SearchBar/index.tsx (2)

1-8: LGTM: Imports and interface declaration are well-structured.

The imports are appropriate, and the SearchBarProps interface is well-defined using TypeScript, ensuring type safety for the component's props.


10-14: LGTM: Component declaration and props destructuring are well-implemented.

The SearchBar component is correctly declared as a functional component with proper TypeScript typing. The props destructuring with a default value for the placeholder prop is a good practice.

apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/templates/components/TemplateContainer.tsx (3)

11-11: LGTM: Import statement updated correctly.

The import statement for SearchBar has been added correctly, aligning with the component replacement mentioned in the summary.


Line range hint 1-78: Overall, the changes look good and align with the PR objectives.

The implementation of the SearchBar component contributes to the goal of adding search functionality, improving user experience in finding specific entries. The changes are minimal and focused, which is good for maintainability. Make sure to test the search functionality thoroughly on the persons page as mentioned in the PR summary.


42-46: Verify the impact of removed props on SearchBar.

The SearchBar component is correctly implemented with simplified props. The onChange handler simplification improves readability. However, please verify that the removal of autoFocus, className, type, and name props doesn't negatively impact the component's behavior or styling.

To ensure the SearchBar component works as expected without the removed props, please run the following verification:

packages/ui/SurveysList/components/SurveyFilters.tsx (3)

Line range hint 1-11: LGTM: SearchBar component import added

The addition of the SearchBar component import on line 10 aligns well with the PR objective of implementing a search feature. The rest of the imports remain unchanged and relevant to the component's functionality.


Line range hint 1-235: Summary: Search feature successfully implemented with room for optimization

The PR successfully implements the search feature in the SurveyFilters component, meeting the main objective. The changes are well-integrated and improve the component's functionality. Consider the suggested optimizations to enhance performance and maintainability as the component grows.

Overall, good job on implementing the search feature!


Line range hint 46-235: Consider performance optimizations and code organization improvements

The SurveyFilters component handles multiple functionalities effectively. However, consider the following suggestions for improvement:

  1. Memoization: The filter option arrays (creatorOptions, statusOptions, etc.) could be memoized to prevent unnecessary re-renders.
  2. Custom hooks: Consider extracting some logic (e.g., filter handling) into custom hooks for better code organization and reusability.
  3. Prop drilling: As the component grows, you might want to consider using React Context or a state management library to avoid prop drilling.

To ensure the component performs well with large datasets, please run the following performance test:

apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonTable.tsx (7)

22-22: LGTM: SearchBar component import added.

The SearchBar component has been correctly imported, which aligns with the PR objective of adding search functionality to the persons table.


33-34: LGTM: PersonTableProps interface updated with search-related props.

The addition of searchValue and setSearchValue props to the PersonTableProps interface is appropriate for implementing the search functionality. The types are correctly defined, and the naming convention follows React best practices.


44-45: LGTM: PersonTable component updated with search-related props.

The searchValue and setSearchValue props have been correctly added to the PersonTable component's parameter list, consistent with the interface update and necessary for implementing the search functionality.


54-57: LGTM: columns useMemo hook updated with searchValue dependency.

The columns useMemo hook has been correctly updated to include searchValue as a dependency. This ensures that the columns are recalculated when the search value changes, which is essential for the search functionality. The use of useMemo here is appropriate for optimizing performance.


155-156: LGTM: SearchBar component added to the JSX.

The SearchBar component has been correctly implemented in the JSX. It's appropriately placed at the top of the table and receives the necessary searchValue and setSearchValue props. The placeholder text "Search person" is suitable for the context.


170-226: LGTM: Table structure and styling improved.

The table structure and styling have been enhanced to improve visual appearance and responsiveness. The use of flexbox, truncation, and group hover effects contributes to a better user experience. These changes align well with the overall objective of improving the persons table.


Line range hint 1-250: Overall implementation looks great and aligns with PR objectives.

The changes successfully implement the search functionality for the persons table, addressing the requirements outlined in issue #3144. Key points:

  1. The SearchBar component is properly integrated.
  2. Necessary props and state management for search are implemented.
  3. The table structure and styling have been improved for better user experience.
  4. The code maintains good readability and follows React best practices.

These changes should significantly enhance the user's ability to locate specific individuals within the application, meeting the primary objective of the PR.

apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/components/ResponseTable.tsx (1)

181-181: Simplified table width handling, but verify layout impact

The changes to the Table component props simplify the width handling:

  1. Adding "w-full" class ensures the table takes up the full width of its container, improving responsiveness.
  2. Removing the width property from the style prop eliminates the dynamic width calculation.
  3. Retaining tableLayout: "fixed" is good for performance and consistent column widths.

These changes align with responsive design practices and may improve maintainability. However:

Please verify that removing the dynamic width calculation (table.getCenterTotalSize()) doesn't negatively impact the table's layout or functionality, especially for tables with many columns or on different screen sizes. Run the following script to check for any width-related properties or methods used elsewhere in the component:

If the script returns any results, consider whether those instances need to be updated to maintain consistent behavior with this change.

@jobenjada jobenjada self-requested a review September 24, 2024 13:20
Copy link
Contributor

@gupta-piyush19 gupta-piyush19 left a comment

Choose a reason for hiding this comment

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

Thanks, @Dhruwang, for the changes.
The code looks really good; just one small change is requested. Can you please take a look at it? 🙌

Comment on lines +77 to +92
useEffect(() => {
const calculateHasMore = async () => {
try {
const personCount = await getPersonCountAction({
environmentId: environment.id,
searchValue,
});
if (personCount && typeof personCount.data === "number") {
setHasMore(personCount.data > persons.length);
}
} catch (error) {
console.error("Error calculating has more:", error);
}
};
calculateHasMore();
}, [persons.length]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we determine hasMore similar to what we do in responses? apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/components/ResponsePage.tsx

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 (1)
apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonDataView.tsx (1)

36-38: Consider standardizing the approach for determining hasMore.

Regarding the suggestion to determine hasMore similar to the ResponsePage component:

The current implementation, which sets hasMore to false when fewer than 50 items are returned, is a valid approach. However, to ensure consistency across the application, it might be beneficial to standardize this logic.

@gupta-piyush19 Could you provide more details about the approach used in the ResponsePage component? This would help us evaluate if we should align the implementations for better consistency across the application.

Also applies to: 66-68

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 3cf6905 and 3580fa0.

📒 Files selected for processing (5)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/templates/components/TemplateContainer.tsx (2 hunks)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/actions.ts (2 hunks)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonDataView.tsx (2 hunks)
  • packages/ui/SearchBar/index.tsx (1 hunks)
  • packages/ui/SurveysList/components/SurveyFilters.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/templates/components/TemplateContainer.tsx
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/actions.ts
  • packages/ui/SearchBar/index.tsx
  • packages/ui/SurveysList/components/SurveyFilters.tsx
🔇 Additional comments (8)
apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonDataView.tsx (8)

5-5: LGTM: Debounce import added for search optimization.

The addition of debounce from lodash is a good practice for optimizing search functionality by reducing the frequency of API calls.


15-15: LGTM: Component props simplified.

The removal of personCount and itemsPerPage props aligns with the shift to an offset-based approach for data fetching and pagination. This simplification improves the component's interface.


20-20: LGTM: Search state added.

The addition of searchValue state is appropriate for implementing the search feature. Initializing it with an empty string is the correct approach for a search input.


24-38: LGTM: Data fetching logic updated for search and offset-based pagination.

The changes to the fetchData function appropriately incorporate the new search feature and offset-based pagination. Setting isDataLoaded to false at the start of the fetch is good for UI feedback. The logic for determining hasMore based on the number of results returned is correct.

Ensure that searchValue is properly sanitized or escaped within getPersonsAction to prevent potential injection attacks, as mentioned in a previous review comment.


46-52: LGTM: Debounce implemented correctly for search optimization.

The implementation of debounce for the fetchData function is well done:

  • The 300ms delay is a good balance between responsiveness and reducing API calls.
  • Cancelling the debounced function in the effect cleanup prevents potential memory leaks.

This optimization will help improve the search feature's performance.


58-69: LGTM: fetchNextPage function updated for offset-based pagination and search.

The fetchNextPage function has been correctly updated to use the offset-based approach and incorporate the searchValue. The logic for updating persons and hasMore is appropriate.

As mentioned earlier, ensure that searchValue is properly sanitized or escaped within getPersonsAction to prevent potential injection attacks.


99-100: LGTM: Search-related props added to PersonTable.

The addition of searchValue and setSearchValue as props to the PersonTable component is appropriate for managing the search input within that component.


22-52: Past issue resolved: searchValue included in useEffect dependency array.

The previous review comment suggesting to include searchValue in the dependency array of the useEffect has been addressed in the current implementation. The useEffect now correctly depends on searchValue, ensuring that the effect runs when the search value changes.

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 (1)
apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonDataView.tsx (1)

25-39: Good updates to data fetching logic, with a minor suggestion.

The changes to the fetchData function are well-implemented:

  1. Setting isDataLoaded to false at the start provides better UI feedback.
  2. Using offset: 0 indicates a shift to offset-based pagination, which is more suitable for search scenarios.
  3. Including searchValue in the API call enables efficient server-side searching.
  4. The new logic for setting hasMore is more accurate and considers the search context.

Consider extracting the itemsPerPage check into a constant for better readability:

const isLastPage = personData && personData.length < itemsPerPage;
if (isLastPage) {
  setHasMore(false);
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 3580fa0 and b839719.

📒 Files selected for processing (6)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/templates/components/TemplateContainer.tsx (2 hunks)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonDataView.tsx (2 hunks)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonTable.tsx (6 hunks)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonTableColumn.tsx (4 hunks)
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/page.tsx (1 hunks)
  • apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/components/ResponseTable.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/templates/components/TemplateContainer.tsx
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonTable.tsx
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonTableColumn.tsx
  • apps/web/app/(app)/environments/[environmentId]/(people)/people/page.tsx
  • apps/web/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/components/ResponseTable.tsx
🔇 Additional comments (7)
apps/web/app/(app)/environments/[environmentId]/(people)/people/components/PersonDataView.tsx (7)

5-5: Good addition of debounce import.

The introduction of debounce from lodash is a positive change. It will help optimize performance, especially for search functionality, by reducing the frequency of potentially expensive operations like API calls.


16-16: Appropriate removal of personCount prop.

The removal of the personCount prop from the component's parameters aligns well with the shift towards a more dynamic, search-based approach for fetching and displaying person data. This change simplifies the component's interface and reduces its dependencies on pre-calculated data.


21-21: Good addition of searchValue state.

The introduction of the searchValue state is a key component for implementing the search functionality. This state will effectively manage the current search input from the user, enabling dynamic filtering of person data.


47-53: Excellent implementation of debounced search and effect cleanup.

The changes to the effect hook are well-implemented and show attention to performance and best practices:

  1. Using a debounced version of fetchData optimizes search performance by reducing unnecessary API calls.
  2. The cleanup function that cancels the debounced function prevents memory leaks and ensures that stale API calls are avoided.
  3. Adding searchValue to the effect's dependency array ensures that the effect runs appropriately when the search input changes.

These changes collectively contribute to a more efficient and responsive search experience.


58-74: Well-implemented updates to fetchNextPage function.

The changes to the fetchNextPage function are appropriate and align well with the new search and pagination approach:

  1. Including searchValue in the API call ensures that subsequent data fetches are consistent with the current search context.
  2. Using persons.length as the offset is the correct approach for the new offset-based pagination system.

These changes contribute to a seamless and consistent data loading experience, especially in the context of search functionality.


100-101: Appropriate addition of search-related props to PersonTable.

The addition of searchValue and setSearchValue as props to the PersonTable component is a good change:

  1. It allows the PersonTable component to manage and display the search input directly.
  2. This change is consistent with the new search functionality implemented in the parent component.
  3. It promotes a clear flow of data and user interactions between parent and child components.

This update enhances the modularity and reusability of the PersonTable component.


Line range hint 1-104: Excellent implementation of search functionality and pagination improvements.

The changes to the PersonDataView component successfully address the PR objectives and enhance the overall functionality:

  1. The addition of search functionality aligns perfectly with the goal of adding a search bar to the People view, addressing issue #3144.
  2. The shift to offset-based pagination is more suitable for search scenarios and improves data fetching efficiency.
  3. Implementation of debouncing for search input optimizes performance by reducing unnecessary API calls.
  4. The component now manages search state and passes it appropriately to child components, promoting a clear data flow.

These improvements collectively enhance the user experience by making it easier to locate specific individuals within the application, as outlined in the PR objectives.

Copy link
Contributor

@gupta-piyush19 gupta-piyush19 left a comment

Choose a reason for hiding this comment

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

LGTM 🚀

@mattinannt mattinannt dismissed jobenjada’s stale review September 27, 2024 09:15

change requests have been addressed

@mattinannt mattinannt added this pull request to the merge queue Sep 27, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Sep 27, 2024
@mattinannt mattinannt added this pull request to the merge queue Sep 27, 2024
Merged via the queue into main with commit 861d399 Sep 27, 2024
@mattinannt mattinannt deleted the search-bar-in-persons-table branch September 27, 2024 09:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

customer request enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Add a search bar to the People view

4 participants