Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: Add filtering and sorting on userTag screens (GSoC) #2398

Merged

Conversation

meetulr
Copy link

@meetulr meetulr commented Nov 2, 2024

What kind of change does this PR introduce?

Adds filtering and sorting for userTag, refactors and addresses minor issues.

Issue Number:

Fixes #2395

Did you add tests for your changes?

Yes

Demo

filterAndSort.mp4

Additional Context

talawa-api issue: PalisadoesFoundation/talawa-api#2630

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Added search functionality for tags based on user input, allowing filtering by name.
    • Introduced sorting capabilities for tags, enabling users to sort by latest or oldest first.
    • Enhanced user interface with prompts for entering tag names in multiple languages.
    • Improved loading and display of tags with breadcrumb navigation for ancestor tags.
  • Bug Fixes

    • Improved error handling for tag assignments and creation processes.
  • Tests

    • Expanded test coverage to include scenarios for searching and sorting tags, as well as error handling during tag creation.
  • Documentation

    • Updated interfaces to include new properties for parent and ancestor tags.

Copy link

coderabbitai bot commented Nov 2, 2024

Walkthrough

The changes in this pull request primarily involve enhancements to the translation files for multiple languages, adding a new key for user prompts related to tag management. Additionally, modifications to various GraphQL queries have been made to support filtering and sorting of user tags. The UI components have been updated to include search functionality and improved layouts for tag management. CSS adjustments have been made to enhance loading states and user interface elements. Overall, these changes aim to improve user interaction and experience within the tag management features.

Changes

File Change Summary
public/locales/en/translation.json Added "enterTagName": "Enter Tag Name" in organizationTags.
public/locales/fr/translation.json Added "enterTagName": "Entrez le nom de l'étiquette" in organizationTags and corrected punctuation.
public/locales/hi/translation.json Added "enterTagName": "टैग का नाम दर्ज करें" in organizationTags.
public/locales/sp/translation.json Added "enterTagName": "Ingrese el nombre de la etiqueta" in organizationTags.
public/locales/zh/translation.json Added "enterTagName": "输入标签名称" in organizationTags and updated "addChildTag" with a trailing comma.
src/GraphQl/Queries/OrganizationQueries.ts Updated ORGANIZATION_USER_TAGS_LIST query to include $where and $sortedBy parameters.
src/GraphQl/Queries/userTagQueries.ts Added $where and $sortedBy parameters to several queries; removed USER_TAG_ANCESTORS.
src/components/AddPeopleToTag/AddPeopleToTag.module.css Changed .scrollContainer height to fixed; added .loadingDiv class.
src/components/AddPeopleToTag/AddPeopleToTag.test.tsx Enhanced tests with new caching and search functionality checks.
src/components/AddPeopleToTag/AddPeopleToTag.tsx Introduced search functionality for members by first and last names.
src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts Updated mocks with new filtering criteria for user tags.
src/components/TagActions/TagActions.module.css Changed .scrollContainer height to fixed; added .loadingDiv class.
src/components/TagActions/TagActions.test.tsx Added tests for tag search functionality and enhanced error handling checks.
src/components/TagActions/TagActions.tsx Introduced tagSearchName state for searching tags; updated loading states.
src/components/TagActions/TagActionsMocks.ts Enhanced mock data with filtering capabilities for user tags.
src/components/TagNode.tsx Added comment for Istanbul coverage tool in loadMoreSubTags.
src/screens/ManageTag/ManageTag.test.tsx Removed outdated tests; added new tests for searching and sorting tags.
src/screens/ManageTag/ManageTag.tsx Added state variables for search inputs and sorting; updated query logic for assigned members.
src/screens/ManageTag/ManageTagMocks.ts Expanded mock data for assigned members with filtering and sorting criteria.
src/screens/OrganizationTags/OrganizationTags.test.tsx Updated test names and added tests for searching and sorting tags.
src/screens/OrganizationTags/OrganizationTags.tsx Introduced tagSearchName and tagSortOrder states; updated query logic for tags.
src/screens/OrganizationTags/OrganizationTagsMocks.ts Enhanced mock data with filtering and sorting capabilities.
src/screens/SubTags/SubTags.test.tsx Updated tests for searching and sorting tags; modified cache configuration.
src/screens/SubTags/SubTags.tsx Added search and sorting functionality for sub-tags.
src/screens/SubTags/SubTagsMocks.ts Updated mock data for sub-tags with new filtering and sorting criteria.
src/utils/interfaces.ts Updated interfaces to include parentTag and ancestorTags properties.
src/utils/organizationTagsUtils.ts Added new type SortedByType for sorting functionality.

Assessment against linked issues

Objective Addressed Explanation
Implement filtering and sorting for user tags (2395)
Improve user experience in tag management (2395)
Clean up code related to tag management (2395)

Possibly related PRs

Suggested reviewers

  • pranshugupta54
  • palisadoes
  • AVtheking
  • gautam-divyanshu

Poem

In the garden of tags we hop,
Searching for names that never stop.
With filters and sorts, oh what a sight,
Managing tags feels just right!
So enter your name, don't delay,
For tagging fun is here to stay! 🐇✨


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.

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

github-actions bot commented Nov 2, 2024

Our Pull Request Approval Process

We have these basic policies to make the approval process smoother for our volunteer team.

Testing Your Code

Please make sure your code passes all tests. Our test code coverage system will fail if these conditions occur:

  1. The overall code coverage drops below the target threshold of the repository
  2. Any file in the pull request has code coverage levels below the repository threshold
  3. Merge conflicts

The process helps maintain the overall reliability of the code base and is a prerequisite for getting your PR approved. Assigned reviewers regularly review the PR queue and tend to focus on PRs that are passing.

Reviewers

Do not assign reviewers. Our Queue Monitors will review your PR and assign them.
When your PR has been assigned reviewers contact them to get your code reviewed and approved via:

  1. comments in this PR or
  2. our slack channel

Reviewing Your Code

Your reviewer(s) will have the following roles:

  1. arbitrators of future discussions with other contributors about the validity of your changes
  2. point of contact for evaluating the validity of your work
  3. person who verifies matching issues by others that should be closed.
  4. person who gives general guidance in fixing your tests

CONTRIBUTING.md

Read our CONTRIBUTING.md file. Most importantly:

  1. PRs with issues not assigned to you will be closed by the reviewer
  2. Fix the first comment in the PR so that each issue listed automatically closes

Other

  1. 🎯 Please be considerate of our volunteers' time. Contacting the person who assigned the reviewers is not advised unless they ask for your input. Do not @ the person who did the assignment otherwise.
  2. Read the CONTRIBUTING.md file make

@meetulr meetulr requested a review from palisadoes as a code owner November 2, 2024 03:30
Copy link

@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 (33)
src/utils/organizationTagsUtils.ts (1)

47-48: Enhance the type documentation.

The type implementation looks good and aligns with the PR objectives. Consider improving the comment to be more descriptive.

-// the sortedByType
+// Defines the sorting order for tag-related operations
src/GraphQl/Queries/userTagQueries.ts (2)

67-68: LGTM: Comprehensive filtering and sorting for child tags

The implementation properly handles pagination, filtering, and sorting for child tags.

Consider implementing field-level permissions or using GraphQL aliases if different components need different subsets of this data to optimize response size.

Also applies to: 72-79


Line range hint 1-152: Update query documentation to reflect new parameters

The queries have good basic documentation, but it should be updated to include information about the new filtering and sorting parameters.

Example documentation update for the first query:

 /**
  * GraphQL query to retrieve organization members assigned a certain tag.
  *
  * @param id - The ID of the tag that is assigned.
+ * @param where - Filter criteria for assigned users
+ * @param sortedBy - Sorting criteria for assigned users
  * @returns The list of organization members.
  */
src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts (2)

165-258: Consider adding more comprehensive test cases.

While the current test cases cover basic filtering scenarios, consider adding:

  1. Combined firstName AND lastName filters
  2. Edge cases with special characters
  3. Case sensitivity scenarios

Example addition:

{
  request: {
    query: USER_TAGS_MEMBERS_TO_ASSIGN_TO,
    variables: {
      id: '1',
      first: TAGS_QUERY_DATA_CHUNK_SIZE,
      where: {
        firstName: { starts_with: 'John' },
        lastName: { starts_with: 'Doe' },
      },
    },
  },
  result: {
    data: {
      getUsersToAssignTo: {
        // ... result structure
      }
    }
  }
}

Line range hint 1-294: Consider implementing a mock data generator utility.

The mock data follows a consistent pattern but requires manual maintenance. Consider creating a utility function to generate mock data, which would:

  1. Reduce duplication
  2. Make it easier to add new test cases
  3. Ensure consistency in mock data structure

Example:

function generateMockResponse(filters: {
  firstName?: string;
  lastName?: string;
}, pagination?: {
  after?: string;
  hasNextPage: boolean;
}) {
  // Generate mock response based on filters and pagination
}
src/screens/ManageTag/ManageTagMocks.ts (2)

172-221: Consider adding edge case search scenarios.

The mock effectively tests basic search functionality. Consider adding test cases for:

  • Case sensitivity
  • Special characters
  • Empty result sets

Mock structure needs adjustment to match the GraphQL schema

The mock structure has some discrepancies with the actual GraphQL query:

  • The query name in the schema is UserTagDetails, but the mock uses a different structure
  • The query uses getUserTag(id: $id) as the resolver, but the mock shows getAssignedUsers
  • The ancestorTags field in the mock is not present in the actual query definition
🔗 Analysis chain

Line range hint 9-121: LGTM! Verify query structure matches the API schema.

The mock correctly implements filtering and sorting with appropriate default values. The pagination structure is well-maintained.


The previous pattern might have been too strict. Let's try a broader search to find the query definition and related schema types to verify the mock structure.


The actual query shows different input types than initially assumed. Let's verify the complete structure including the input types to ensure the mock aligns with the schema.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify that the mock structure matches the actual GraphQL schema
# Look for the query definition to ensure alignment

ast-grep --pattern 'export const USER_TAGS_ASSIGNED_MEMBERS = gql`
  query $_($where: $_) {
    getAssignedUsers(where: $where) {
      $$$
    }
  }
`'

Length of output: 154


Script:

#!/bin/bash
# Search for the GraphQL query definition with a more flexible pattern
rg -U "USER_TAGS_ASSIGNED_MEMBERS.*=.*gql" -A 20

# Also search for any GraphQL type definitions that might help verify the schema
rg -U "input.*UserFilter|type.*User.*{|interface.*User.*{" -A 10

Length of output: 1593


Script:

#!/bin/bash
# Let's fix the regex and search for type definitions
rg -U "input.*UserTagUsersAssignedToWhereInput|input.*UserTagUsersAssignedToSortedByInput" -A 5

# Also get the complete query definition to verify the response structure
rg -U "USER_TAGS_ASSIGNED_MEMBERS.*=.*gql" -A 30

Length of output: 2021

src/GraphQl/Queries/OrganizationQueries.ts (1)

92-103: Add JSDoc documentation for the new parameters.

Other queries in this file have detailed JSDoc documentation. Please maintain consistency by documenting the new where and sortedBy parameters.

Add documentation like this:

/**
 * GraphQL query to retrieve the list of user tags belonging to an organization.
 *
 * @param id - ID of the organization.
 * @param first - Number of tags to retrieve "after" (if provided) a certain tag.
 * @param after - Id of the last tag on the current page.
 * @param last - Number of tags to retrieve "before" (if provided) a certain tag.
 * @param before - Id of the first tag on the current page.
 * @param where - Filter conditions for user tags.
 * @param sortedBy - Sorting criteria for user tags.
 * @returns The list of organizations based on the applied filters.
 */
src/components/AddPeopleToTag/AddPeopleToTag.test.tsx (4)

66-91: LGTM! Consider adding documentation for the merge logic.

The cache configuration with type policies is well-implemented. The merge function correctly handles the concatenation of edges while preserving other fields.

Consider adding comments to explain the merge logic:

 const cache = new InMemoryCache({
   typePolicies: {
     Query: {
       fields: {
         getUserTag: {
+          // Merge function concatenates edges from existing and incoming data
+          // while preserving other fields to support infinite scroll
           merge(existing = {}, incoming) {
             const merged = {
               ...existing,
               ...incoming,
               usersToAssignTo: {

177-208: Fix typo and improve test description.

The test implementation is good, but there are some minor improvements needed:

-  test('searchs for tags where the firstName matches the provided firstName search input', async () => {
+  test('searches and filters members by firstName input', async () => {

210-241: Fix typo and improve test description.

Similar improvement needed for the lastName search test:

-  test('searchs for tags where the lastName matches the provided lastName search input', async () => {
+  test('searches and filters members by lastName input', async () => {

Line range hint 1-24: Consider adding more edge case tests.

The test coverage is good, but consider adding these test cases to improve robustness:

  1. Test search with special characters in names
  2. Test search with empty/whitespace input
  3. Test infinite scroll when there are no more results
  4. Test error handling for network failures during search
  5. Test concurrent searches (typing fast in both firstName and lastName fields)

Would you like me to help implement any of these test cases?

src/screens/SubTags/SubTags.test.tsx (1)

239-258: Consider adding edge cases to search test.

The current test effectively verifies basic search functionality. Consider adding test cases for:

  • Empty search results
  • Special characters in search
  • Case sensitivity
src/components/TagActions/TagActions.test.tsx (1)

202-221: Fix typo in test name and consider adding edge cases.

The test effectively verifies the search functionality, but has a few areas for improvement:

  1. Fix the grammatical error in the test name from "searchs" to "searches"
  2. Consider adding edge cases to strengthen test coverage:
    • Empty search input
    • Search with no matching results

Apply this diff to fix the typo:

-  test('searchs for tags where the name matches the provided search input', async () => {
+  test('searches for tags where the name matches the provided search input', async () => {
src/utils/interfaces.ts (2)

215-215: LGTM! Consider adding JSDoc comments.

The addition of parentTag and ancestorTags establishes a proper hierarchical structure for tags. This will effectively support the filtering and sorting functionality mentioned in the PR objectives.

Consider adding JSDoc comments to document the hierarchical relationship:

/**
 * Represents a user tag with hierarchical structure.
 * @property parentTag - Direct parent tag reference
 * @property ancestorTags - Array of all ancestor tags in hierarchical order
 */

Also applies to: 222-225


275-278: LGTM! Consider extracting common types.

The addition of ancestorTags maintains consistency across tag-related interfaces.

Consider extracting the common ancestorTags type to reduce duplication:

interface AncestorTag {
  _id: string;
  name: string;
}

interface BaseTagInterface {
  ancestorTags: AncestorTag[];
}

interface InterfaceQueryUserTagsAssignedMembers extends BaseTagInterface {
  name: string;
  usersAssignedTo: InterfaceTagMembersData;
}
src/screens/OrganizationTags/OrganizationTagsMocks.ts (2)

12-13: Enhance test coverage with diverse mock data scenarios.

While the mock data structure is consistent, consider adding more diverse test cases:

  • Tags with different parent-child relationships
  • Tags with varying depths of ancestor hierarchies
  • Edge cases for filtering (e.g., special characters, empty names)

Also applies to: 26-33, 41-48, 56-63, 71-78, 86-93, 101-108, 116-123, 131-138, 146-153, 161-168, 193-194, 207-214, 222-229


Line range hint 1-426: Consider implementing a mock data generator.

Given the repetitive nature of the mock data and the need to maintain consistency across different scenarios, consider implementing a mock data generator function. This would:

  • Reduce duplication and make updates easier
  • Ensure consistency in test data
  • Make it easier to add new test cases
  • Help maintain the relationship between parent and child tags

Example structure:

interface TagGeneratorOptions {
  prefix?: string;
  count?: number;
  sortOrder?: 'ASCENDING' | 'DESCENDING';
  parentTagId?: string;
}

function generateTagMocks(options: TagGeneratorOptions) {
  // Generate mock data based on options
}

Would you like me to help create this generator function?

src/components/TagActions/TagActions.tsx (1)

310-321: Enhance search input accessibility and semantics

A few suggestions to improve the search implementation:

  1. Add aria-label to the search input for better screen reader support
  2. Update the input's id to reflect its purpose (currently "userName" for tag search)
  3. Consider using a button element for the search icon to make it keyboard accessible
 <div className="mt-3 position-relative">
-  <i className="fa fa-search position-absolute text-body-tertiary end-0 top-50 translate-middle" />
+  <button
+    className="fa fa-search position-absolute text-body-tertiary end-0 top-50 translate-middle border-0 bg-transparent"
+    aria-label={t('search')}
+    onClick={() => {/* Optional: implement search on click */}}
+  />
   <Form.Control
     type="text"
-    id="userName"
+    id="tagSearch"
     className="bg-light"
     placeholder={tCommon('searchByName')}
     onChange={(e) => setTagSearchName(e.target.value.trim())}
     data-testid="searchByName"
     autoComplete="off"
+    aria-label={tCommon('searchByName')}
   />
 </div>
src/screens/SubTags/SubTagsMocks.ts (3)

Line range hint 1-13: Consider adding TypeScript interfaces for mock data structure.

The mock setup would benefit from TypeScript interfaces defining the expected shape of the query variables and responses. This would make the mocks more maintainable and catch potential structure mismatches early.


Line range hint 14-221: Consider extracting repeated mock data structures into helper functions.

The mock data contains repeated structures for nodes that could be generated using helper functions. This would make the mocks more maintainable and reduce the chance of inconsistencies.

Example helper function:

const createMockSubTag = (id: string, name: string, options?: {
  usersCount?: number,
  childTagsCount?: number,
  ancestors?: Array<{_id: string, name: string}>
}) => ({
  node: {
    _id: id,
    name,
    usersAssignedTo: { totalCount: options?.usersCount ?? 0 },
    childTags: { totalCount: options?.childTagsCount ?? 0 },
    ancestorTags: options?.ancestors ?? []
  },
  cursor: id
});

Line range hint 489-502: Consider adding more error scenarios.

The error mocks could be expanded to cover:

  • Network errors
  • Validation errors with specific error messages
  • Error cases for mutations
  • Error cases for pagination
src/components/AddPeopleToTag/AddPeopleToTag.tsx (2)

57-87: LGTM! Consider adding type annotations for useState.

The search state implementation and reset logic look good. For better type safety, consider explicitly typing the state variables.

-  const [memberToAssignToSearchFirstName, setMemberToAssignToSearchFirstName] =
-    useState('');
+  const [memberToAssignToSearchFirstName, setMemberToAssignToSearchFirstName] =
+    useState<string>('');
-  const [memberToAssignToSearchLastName, setMemberToAssignToSearchLastName] =
-    useState('');
+  const [memberToAssignToSearchLastName, setMemberToAssignToSearchLastName] =
+    useState<string>('');

274-296: Enhance accessibility for the remove member button.

While the UI implementation looks good, the remove member button could be more accessible.

-                    <i
-                      className={`${styles.removeFilterIcon} fa fa-times ms-2 text-body-tertiary`}
-                      onClick={() => removeMember(member._id)}
-                      data-testid="clearSelectedMember"
-                    />
+                    <button
+                      type="button"
+                      className={`${styles.removeFilterIcon} btn btn-link border-0 p-0 ms-2`}
+                      onClick={() => removeMember(member._id)}
+                      data-testid="clearSelectedMember"
+                      aria-label={`Remove ${member.firstName} ${member.lastName}`}
+                    >
+                      <i className="fa fa-times text-body-tertiary" />
+                    </button>
src/screens/OrganizationTags/OrganizationTags.tsx (2)

124-126: Consider adding dependency array conditions to useEffect.

The current implementation will trigger a refetch on every component mount. Consider adding relevant dependencies to prevent unnecessary refetches.

  useEffect(() => {
    orgUserTagsRefetch();
-  }, []);
+  }, [orgUserTagsRefetch]);

134-137: Consider enhancing tag name validation.

While checking for empty strings is good, consider adding:

  • Maximum length validation
  • Special character restrictions
  • Duplicate tag name validation
src/screens/ManageTag/ManageTag.test.tsx (2)

327-346: Enhance search test coverage and fix grammatical error.

  1. The test name contains a grammatical error: "searchs" should be "searches"
  2. Consider adding negative test cases:
    • Search with no matches
    • Search with empty string
    • Search with special characters

Apply this diff to fix the grammar and improve the test description:

-  test('searchs for tags where the name matches the provided search input', async () => {
+  test('searches for tags where the name matches the provided search input', async () => {

327-403: Consider restructuring tests for better maintainability.

While the tests cover the core functionality well, consider these architectural improvements:

  1. Create a test-utils.ts file to store common helper functions for:

    • Sort button interactions
    • Search input interactions
    • Common assertions
  2. Group related tests using describe blocks for:

    • Search functionality
    • Sort functionality
    • Combined search and sort scenarios

This will improve test maintainability and make it easier to add more test cases in the future.

src/screens/SubTags/SubTags.tsx (2)

310-322: Add aria-labels to dropdown items for better accessibility

 <Dropdown.Item
   data-testid="latest"
+  aria-label={tCommon('Latest')}
   onClick={() => setTagSortOrder('DESCENDING')}
 >
   {tCommon('Latest')}
 </Dropdown.Item>
 <Dropdown.Item
   data-testid="oldest"
+  aria-label={tCommon('Oldest')}
   onClick={() => setTagSortOrder('ASCENDING')}
 >
   {tCommon('Oldest')}
 </Dropdown.Item>

Line range hint 144-154: Use translation key for error message

The error message should use the translation system for consistency and internationalization support.

 <h6 className="fw-bold text-danger text-center">
-  Error occured while loading sub tags
+  {t('errorLoadingSubTags')}
 </h6>

Don't forget to add the translation key to your translation files.

src/components/TagActions/TagActionsMocks.ts (1)

249-321: LGTM: Search mock provides good test coverage.

The new mock entry effectively demonstrates tag hierarchy and relationships. However, consider adding a test case for a search term that yields no results to ensure proper handling of empty states.

Add another mock entry with a search term that returns no results:

{
  request: {
    query: ORGANIZATION_USER_TAGS_LIST,
    variables: {
      id: '123',
      first: TAGS_QUERY_DATA_CHUNK_SIZE,
      where: { name: { starts_with: 'nonexistent' } },
    },
  },
  result: {
    data: {
      organizations: [{
        userTags: {
          edges: [],
          pageInfo: {
            hasNextPage: false,
            hasPreviousPage: false,
            startCursor: null,
            endCursor: null
          },
          totalCount: 0
        }
      }]
    }
  }
}
src/screens/ManageTag/ManageTag.tsx (2)

251-251: Internationalize the error message

The error message "Error occured while loading assigned users" is hardcoded in English. To support internationalization, consider using the t function from useTranslation.

Update the code as follows:

<h6 className="fw-bold text-danger text-center">
-  Error occured while loading assigned users
+  {t('errorLoadingAssignedUsers')}
</h6>

Ensure the translation key errorLoadingAssignedUsers is added to your localization files.


365-366: Avoid redundant trimming of search input

Currently, the search input is trimmed both in the onChange handler and in the useEffect. Trimming in both places is unnecessary.

Choose one place to trim the input. For example, you could remove the .trim() in the onChange handler:

onChange={(e) =>
-  setAssignedMemberSearchInput(e.target.value.trim())
+  setAssignedMemberSearchInput(e.target.value)
}

Alternatively, if you prefer to trim in the onChange handler, you can remove the .trim() in the useEffect.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7501e34 and cbe81df.

📒 Files selected for processing (27)
  • public/locales/en/translation.json (1 hunks)
  • public/locales/fr/translation.json (1 hunks)
  • public/locales/hi/translation.json (1 hunks)
  • public/locales/sp/translation.json (1 hunks)
  • public/locales/zh/translation.json (1 hunks)
  • src/GraphQl/Queries/OrganizationQueries.ts (1 hunks)
  • src/GraphQl/Queries/userTagQueries.ts (8 hunks)
  • src/components/AddPeopleToTag/AddPeopleToTag.module.css (2 hunks)
  • src/components/AddPeopleToTag/AddPeopleToTag.test.tsx (6 hunks)
  • src/components/AddPeopleToTag/AddPeopleToTag.tsx (6 hunks)
  • src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts (4 hunks)
  • src/components/TagActions/TagActions.module.css (2 hunks)
  • src/components/TagActions/TagActions.test.tsx (2 hunks)
  • src/components/TagActions/TagActions.tsx (8 hunks)
  • src/components/TagActions/TagActionsMocks.ts (21 hunks)
  • src/components/TagActions/TagNode.tsx (1 hunks)
  • src/screens/ManageTag/ManageTag.test.tsx (2 hunks)
  • src/screens/ManageTag/ManageTag.tsx (13 hunks)
  • src/screens/ManageTag/ManageTagMocks.ts (6 hunks)
  • src/screens/OrganizationTags/OrganizationTags.test.tsx (3 hunks)
  • src/screens/OrganizationTags/OrganizationTags.tsx (11 hunks)
  • src/screens/OrganizationTags/OrganizationTagsMocks.ts (6 hunks)
  • src/screens/SubTags/SubTags.test.tsx (4 hunks)
  • src/screens/SubTags/SubTags.tsx (10 hunks)
  • src/screens/SubTags/SubTagsMocks.ts (18 hunks)
  • src/utils/interfaces.ts (2 hunks)
  • src/utils/organizationTagsUtils.ts (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • src/components/AddPeopleToTag/AddPeopleToTag.module.css
  • src/components/TagActions/TagActions.module.css
  • src/components/TagActions/TagNode.tsx
🧰 Additional context used
📓 Learnings (6)
src/components/AddPeopleToTag/AddPeopleToTag.tsx (1)
Learnt from: meetulr
PR: PalisadoesFoundation/talawa-admin#2387
File: src/components/AddPeopleToTag/AddPeopleToTag.tsx:78-104
Timestamp: 2024-10-30T15:46:05.784Z
Learning: In `src/components/AddPeopleToTag/AddPeopleToTag.tsx`, and similar components, the team prefers to keep the current implementation of the `updateQuery` logic in infinite scroll functionality consistent across all screens.
src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts (2)
Learnt from: meetulr
PR: PalisadoesFoundation/talawa-admin#2387
File: src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts:16-16
Timestamp: 2024-10-30T12:37:36.856Z
Learning: When renaming GraphQL fields in this codebase, aliases are used to map old field names to new ones. It's acceptable for `getUserTag` to appear as long as it's properly aliased.
Learnt from: meetulr
PR: PalisadoesFoundation/talawa-admin#2355
File: src/screens/ManageTag/ManageTagMocks.ts:187-269
Timestamp: 2024-10-25T19:31:37.405Z
Learning: In `src/screens/ManageTag/ManageTagMocks.ts`, when mocking data for `USER_TAGS_ASSIGNED_MEMBERS` and `USER_TAGS_MEMBERS_TO_ASSIGN_TO`, it's acceptable for user IDs to overlap because the queries serve different purposes and the overlapping IDs can represent realistic scenarios in tests.
src/components/TagActions/TagActions.test.tsx (1)
Learnt from: meetulr
PR: PalisadoesFoundation/talawa-admin#2362
File: src/components/TagActions/TagActions.test.tsx:251-274
Timestamp: 2024-10-28T06:33:09.726Z
Learning: In `TagActions.test.tsx`, negative test cases for tag operations can be deferred and added later if necessary, according to the team's plan.
src/screens/ManageTag/ManageTag.tsx (1)
Learnt from: meetulr
PR: PalisadoesFoundation/talawa-admin#2387
File: src/screens/ManageTag/ManageTag.tsx:113-147
Timestamp: 2024-10-30T13:29:28.310Z
Learning: In the `src/screens/ManageTag/ManageTag.tsx` file, the `InfiniteScroll` component uses the `loadMoreAssignedMembers` function efficiently, and additional error handling is unnecessary.
src/screens/ManageTag/ManageTagMocks.ts (2)
Learnt from: meetulr
PR: PalisadoesFoundation/talawa-admin#2355
File: src/screens/ManageTag/ManageTagMocks.ts:187-269
Timestamp: 2024-10-25T19:31:37.405Z
Learning: In `src/screens/ManageTag/ManageTagMocks.ts`, when mocking data for `USER_TAGS_ASSIGNED_MEMBERS` and `USER_TAGS_MEMBERS_TO_ASSIGN_TO`, it's acceptable for user IDs to overlap because the queries serve different purposes and the overlapping IDs can represent realistic scenarios in tests.
Learnt from: meetulr
PR: PalisadoesFoundation/talawa-admin#2387
File: src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts:16-16
Timestamp: 2024-10-30T12:37:36.856Z
Learning: When renaming GraphQL fields in this codebase, aliases are used to map old field names to new ones. It's acceptable for `getUserTag` to appear as long as it's properly aliased.
src/screens/OrganizationTags/OrganizationTags.tsx (1)
Learnt from: meetulr
PR: PalisadoesFoundation/talawa-admin#2387
File: src/screens/OrganizationTags/OrganizationTags.tsx:350-376
Timestamp: 2024-10-30T13:18:56.627Z
Learning: In the `src/screens/OrganizationTags/OrganizationTags.tsx` file, the `OrganizationTags` component uses chunk size with the `InfiniteScroll` component and an outer parent div for handling data loading and scrolling.
🪛 Biome
src/components/TagActions/TagActions.tsx

[error] 367-367: 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)


[error] 378-378: 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 (38)
src/utils/organizationTagsUtils.ts (1)

47-49: Verify consistent usage of SortedByType.

Let's ensure the new type is being used consistently across components.

✅ Verification successful

SortedByType is consistently used across the codebase

The type is properly imported and utilized in all relevant components:

  • OrganizationTags.tsx: Used for tagSortOrder state
  • SubTags.tsx: Used for tagSortOrder state
  • ManageTag.tsx: Used for assignedMemberSortOrder state

All literal string usages of 'ASCENDING' and 'DESCENDING' are properly typed with SortedByType, including mock data in respective *Mocks.ts files.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the usage of SortedByType across the codebase
# Expected: Find references in tag-related components and queries

# Search for SortedByType usage
echo "=== Checking SortedByType usage ==="
rg "SortedByType" -A 2

# Search for literal string usage to catch any inconsistencies
echo -e "\n=== Checking for potential inconsistent sort type usage ==="
rg "'ASCENDING'|'DESCENDING'" --type ts

Length of output: 4193

src/GraphQl/Queries/userTagQueries.ts (1)

17-18: LGTM: Well-structured filtering and sorting implementation

The addition of where and sortedBy parameters enhances the query's functionality, aligning perfectly with the PR objectives for implementing filtering and sorting on tag screens.

Also applies to: 27-28

src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts (3)

12-15: LGTM! Well-structured default filters.

The empty string filters provide a good default state for unfiltered results.


124-127: LGTM! Consistent filter handling with pagination.

The filters are correctly maintained across paginated requests, ensuring consistent results.


284-287: LGTM! Error case properly updated.

The error mock correctly includes the new filtering structure, maintaining consistency with successful cases.

src/screens/ManageTag/ManageTagMocks.ts (4)

Line range hint 1-8: LGTM! Import changes align with new filtering functionality.

The removal of USER_TAG_ANCESTORS and retention of necessary mutation imports properly reflect the updated functionality.


Line range hint 122-171: LGTM! Pagination mock maintains consistency.

The mock correctly implements cursor-based pagination while maintaining the new filtering and sorting structure.


222-270: LGTM! Sort order mock effectively tests both orderings.

The mock properly demonstrates ascending and descending sort functionality with consistent data.


Line range hint 326-336: LGTM! Error mock updated with new parameters.

The error mock correctly maintains consistency with the success mocks by including the new filtering and sorting parameters.

src/GraphQl/Queries/OrganizationQueries.ts (3)

92-93: LGTM: Well-structured query parameters for filtering and sorting.

The addition of UserTagWhereInput and UserTagSortedByInput parameters provides a clean interface for implementing the filtering and sorting functionality.


96-103: LGTM: Clean integration of filtering and sorting with pagination.

The parameters are well-organized and maintain compatibility with existing pagination functionality.


108-110: Consider paginating ancestorTags for deep hierarchies.

While the addition of parentTag and ancestorTags fields is good for supporting hierarchical relationships, consider the performance implications of fetching all ancestor tags without pagination.

Let's check the potential depth of tag hierarchies:

Consider adding pagination to ancestorTags if deep hierarchies are expected:

ancestorTags(first: $first, last: $last) {
  edges {
    node {
      _id
      name
    }
  }
  pageInfo {
    hasNextPage
    hasPreviousPage
  }
}

Also applies to: 117-120

src/screens/OrganizationTags/OrganizationTags.test.tsx (1)

280-284: LGTM: Good error handling test coverage.

The added validation test for empty tag name is well-implemented and verifies the correct error message.

src/screens/SubTags/SubTags.test.tsx (2)

54-79: Well-implemented cache merge strategy!

The cache configuration properly handles merging of existing and incoming tag data, with good handling of edge cases for childTags. This is crucial for maintaining cache consistency during pagination and updates.


83-84: Good test setup with proper cache management!

The addition of cache reset in beforeEach and passing the cache to MockedProvider ensures clean test state and proper cache behavior.

Also applies to: 114-114

src/components/TagActions/TagActions.test.tsx (1)

346-355: LGTM! Good addition of error handling test.

The new test case effectively validates the error feedback when attempting to submit without selecting any tags. This improves the test coverage and ensures a better user experience by verifying proper error messaging.

src/screens/OrganizationTags/OrganizationTagsMocks.ts (1)

420-421: LGTM!

The error mock data is properly updated to include the new query parameters, maintaining consistency with the successful query structure.

src/components/TagActions/TagActions.tsx (2)

53-54: LGTM: Well-implemented search functionality!

The search integration with GraphQL is properly implemented, with appropriate state management and query filtering.

Also applies to: 64-64


327-329: LGTM: Improved loading state visualization!

The switch to InfiniteScrollLoader provides better visual feedback and maintains consistency across components.

src/screens/SubTags/SubTagsMocks.ts (4)

Line range hint 222-271: LGTM! Pagination implementation follows GraphQL best practices.

The mock correctly implements cursor-based pagination with proper page info structure.


336-466: LGTM! Comprehensive test coverage for search and sort functionality.

The mock data properly covers:

  • Search filtering with prefix matching
  • Both ascending and descending sort orders
  • Consistent data structure with proper cursors

472-486: LGTM! Create tag mutation mock is correctly structured.

The mock provides the necessary response structure for tag creation.


Line range hint 272-329: Verify ancestor chain consistency in nested tags.

While the mock data structure looks correct, consider adding tests to verify that:

  1. The ancestor chain is always ordered from root to immediate parent
  2. The ancestor IDs match the actual parent tags
✅ Verification successful

Let me search for the actual ancestor chain implementations to better understand the structure.


Let me try a different approach to find the ancestor chain implementations.


Based on the search results, I can now generate the final response:

Ancestor chain implementation is consistent and correct

The mock data correctly implements the ancestor chain hierarchy:

  • First-level subtags (e.g., 'subTag1', 'subTag2') have a single ancestor: userTag1
  • Second-level subtag (subTag1.1) has the complete chain: [userTag1, subTag1]
  • The order is consistently maintained from root to immediate parent
  • IDs and names match across the hierarchy
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for inconsistencies in ancestor chains across test files
rg -U "ancestorTags.*?\[.*?\]" --multiline

Length of output: 3181


Script:

#!/bin/bash
# Search for ancestor chain implementations with context
rg -U "ancestorTags.*?\[.*?\{.*?\}.*?\]" --multiline -A 5

Length of output: 59


Script:

#!/bin/bash
# Search for ancestor chain implementations with more specific pattern
rg -U 'ancestorTags:\s*\[\s*\{\s*_id:' --multiline -A 10 src/screens/SubTags/SubTagsMocks.ts

Length of output: 6096

src/components/AddPeopleToTag/AddPeopleToTag.tsx (2)

157-160: LGTM! Good validation with user feedback.

The empty selection check with internationalized error message is well implemented.


Line range hint 330-352: LGTM! Clean implementation of infinite scroll with loading states.

The loading states and infinite scroll implementation are well-handled with proper component separation.

src/screens/OrganizationTags/OrganizationTags.tsx (3)

79-80: LGTM! Query parameters properly implemented.

The filtering and sorting parameters are correctly integrated into the GraphQL query, aligning with the PR objectives.


211-221: LGTM! Well-implemented breadcrumb navigation.

The breadcrumb implementation for ancestor tags provides good hierarchical context and navigation.


375-413: LGTM! Robust implementation of infinite scrolling with DataGrid.

The implementation:

  • Properly handles loading states
  • Includes error boundaries
  • Follows the chunk size pattern from previous implementations
  • Has appropriate fallback UI for empty states
src/screens/SubTags/SubTags.tsx (2)

19-22: LGTM: Well-structured state management for search and sort functionality

The implementation uses proper TypeScript types and follows React best practices for state management.

Also applies to: 55-57


383-422: LGTM: Well-implemented infinite scroll with DataGrid

The implementation of infinite scroll with DataGrid is well-structured and includes:

  • Proper loading states
  • Error handling
  • Row customization
  • Empty state handling
src/components/TagActions/TagActionsMocks.ts (3)

16-16: LGTM: Mock data structure updated correctly for filtering.

The changes consistently add the new filtering capability and tag relationship fields (parentTag and ancestorTags) across all mock entries. The empty string filter (starts_with: '') is appropriate for showing all tags by default.

Also applies to: 29-29, 36-36, 44-44, 51-51, 59-59, 66-66, 74-74, 81-81, 89-89, 96-96, 104-104, 111-111, 119-119, 126-126, 134-134, 141-141, 149-149, 156-156, 164-164, 171-171, 196-196, 209-209, 216-216, 224-224, 231-231


346-351: LGTM: Subtag hierarchy correctly represented.

The ancestorTags field is consistently added to all subtags, correctly representing their relationship to the parent tag.

Also applies to: 365-370, 384-389, 403-408, 422-427, 441-446, 460-465, 479-484, 498-503, 517-522, 535-535, 565-570, 583-583


629-629: LGTM: Error mocks updated consistently.

The error mocks have been properly updated to include the new filtering capability and tag relationship fields, maintaining consistency with the successful mocks.

Also applies to: 643-643, 656-656, 663-663, 671-671, 678-678

public/locales/zh/translation.json (1)

323-324: LGTM! The translation changes look good.

The changes enhance the tag management features by:

  1. Adding a trailing comma after addChildTag for better maintainability
  2. Adding an accurate Chinese translation for the tag name input prompt

The translation is natural and consistent with the existing style.

public/locales/en/translation.json (1)

323-324: LGTM! Translation key added for tag management.

The new translation key enterTagName is well-placed in the organizationTags section and follows the existing naming conventions. The translation text is clear and consistent with other similar prompts in the file.

public/locales/hi/translation.json (1)

323-324: LGTM! The translation addition is well-structured.

The new translation key "enterTagName" with Hindi translation "टैग का नाम दर्ज करें" is properly implemented and maintains consistency with the existing translations.

Let's verify that this translation key exists across other locale files:

✅ Verification successful

Translation key "enterTagName" is consistently present across all locale files

The verification confirms that the "enterTagName" key exists with appropriate translations in all locale files:

  • English (en): "Enter Tag Name"
  • French (fr): "Entrez le nom du étiquette"
  • Spanish (sp): "Ingrese el nombre de la etiqueta"
  • Chinese (zh): "输入标签名称"
  • Hindi (hi): "टैग का नाम दर्ज करें"
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if enterTagName exists in all locale files
# Expected: The key should exist in en, fr, sp, zh locale files

for locale in en fr sp zh; do
  echo "Checking $locale translation..."
  rg -A 1 '"enterTagName"' "public/locales/$locale/translation.json"
done

Length of output: 801

public/locales/sp/translation.json (1)

323-324: LGTM! The Spanish translation for the tag name input prompt is correctly implemented.

The translation is grammatically correct and consistent with Spanish language conventions and similar prompts in the file.

src/screens/ManageTag/ManageTag.tsx (1)

386-395: ⚠️ Potential issue

Verify the field used for sorting assigned members

The sorting functionality uses the id field to order assigned members by 'Latest' and 'Oldest'. However, the id may not accurately reflect the creation time or assignment time of members.

Please verify if sorting by id provides the intended ordering. If not, consider using a timestamp field like createdAt or assignedAt for accurate sorting.

Also applies to: 108-112

src/GraphQl/Queries/userTagQueries.ts Show resolved Hide resolved
src/components/AddPeopleToTag/AddPeopleToTag.test.tsx Outdated Show resolved Hide resolved
src/screens/SubTags/SubTags.tsx Show resolved Hide resolved
public/locales/fr/translation.json Outdated Show resolved Hide resolved
src/screens/ManageTag/ManageTag.tsx Show resolved Hide resolved
src/screens/ManageTag/ManageTag.tsx Show resolved Hide resolved
src/screens/ManageTag/ManageTag.tsx Show resolved Hide resolved
Copy link

codecov bot commented Nov 2, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.08%. Comparing base (7501e34) to head (5085b7f).
Report is 1 commits behind head on develop.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #2398      +/-   ##
===========================================
+ Coverage    98.06%   98.08%   +0.02%     
===========================================
  Files          255      255              
  Lines         7169     7208      +39     
  Branches      2087     2086       -1     
===========================================
+ Hits          7030     7070      +40     
+ Misses         129      128       -1     
  Partials        10       10              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 2, 2024
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (1)
src/components/AddPeopleToTag/AddPeopleToTag.test.tsx (1)

66-91: LGTM! Consider adding type safety.

The cache configuration with merge policy for getUserTag is well implemented. It correctly handles the merging of existing and incoming data while maintaining immutability.

Consider adding TypeScript interfaces for the merged data structure:

interface UsersToAssignTo {
  edges: unknown[];
  // add other properties
}

interface UserTagData {
  usersToAssignTo?: UsersToAssignTo;
  // add other properties
}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between cbe81df and 3d801ca.

📒 Files selected for processing (5)
  • .github/workflows/pull-request.yml (1 hunks)
  • public/locales/fr/translation.json (1 hunks)
  • src/components/AddPeopleToTag/AddPeopleToTag.test.tsx (6 hunks)
  • src/components/AddPeopleToTag/AddPeopleToTag.tsx (6 hunks)
  • src/components/TagActions/TagActions.test.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • public/locales/fr/translation.json
  • src/components/AddPeopleToTag/AddPeopleToTag.tsx
  • src/components/TagActions/TagActions.test.tsx
🔇 Additional comments (3)
.github/workflows/pull-request.yml (1)

41-41: LGTM! Verify the excluded file exists.

The addition of src/components/TagActions/TagActionsMocks.ts to the list of excluded files follows the established pattern.

Let's verify that the excluded file exists:

✅ Verification successful

File exists and exclusion is valid

The file src/components/TagActions/TagActionsMocks.ts exists in the codebase, confirming that the exclusion in the line counting workflow is valid.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the excluded file exists in the codebase
fd "TagActionsMocks.ts" --type f

Length of output: 77

src/components/AddPeopleToTag/AddPeopleToTag.test.tsx (2)

121-121: LGTM! Good test isolation practice.

Adding cache.reset() in beforeEach ensures proper test isolation by clearing any cached data between tests.


272-285: LGTM! Good test separation.

Excellent work on extracting the error handling into a separate test case. This improves test clarity and maintainability by following the single responsibility principle.

coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 2, 2024
Copy link

@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: 4

🧹 Outside diff range and nitpick comments (4)
src/screens/SubTags/SubTags.tsx (2)

Line range hint 55-78: Consider optimizing query variables

The GraphQL query variables could be optimized to prevent unnecessary re-renders by using useMemo for the variables object.

+ const queryVariables = useMemo(
+   () => ({
+     id: parentTagId,
+     first: TAGS_QUERY_DATA_CHUNK_SIZE,
+     where: { name: { starts_with: tagSearchName } },
+     sortedBy: { id: tagSortOrder },
+   }),
+   [parentTagId, tagSearchName, tagSortOrder]
+ );

  const {
    data: subTagsData,
    error: subTagsError,
    loading: subTagsLoading,
    refetch: subTagsRefetch,
    fetchMore: fetchMoreSubTags,
  }: InterfaceOrganizationSubTagsQuery = useQuery(USER_TAG_SUB_TAGS, {
-   variables: {
-     id: parentTagId,
-     first: TAGS_QUERY_DATA_CHUNK_SIZE,
-     where: { name: { starts_with: tagSearchName } },
-     sortedBy: { id: tagSortOrder },
-   },
+   variables: queryVariables,
  });

Don't forget to add the following import:

import { useMemo } from 'react';

Line range hint 144-154: Use translation key for error message

The error message is hardcoded. For consistency with i18n practices, use a translation key.

  if (subTagsError) {
    return (
      <div className={`${styles.errorContainer} bg-white rounded-4 my-3`}>
        <div className={styles.errorMessage}>
          <WarningAmberRounded className={styles.errorIcon} fontSize="large" />
          <h6 className="fw-bold text-danger text-center">
-           Error occured while loading sub tags
+           {t('errorLoadingSubTags')}
          </h6>
        </div>
      </div>
    );
  }
src/screens/ManageTag/ManageTag.tsx (2)

443-443: Simplify the className assignment for readability

The className for the breadcrumb items can be simplified for better readability by avoiding nested template literals.

Consider refactoring the className as follows:

- className={`ms-2 my-1 ${tag._id === currentTagId ? `fs-4 fw-semibold text-secondary` : `${styles.tagsBreadCrumbs} fs-6`}`}
+ className={`ms-2 my-1 ${
+   tag._id === currentTagId
+     ? 'fs-4 fw-semibold text-secondary'
+     : `${styles.tagsBreadCrumbs} fs-6`
+ }`}

359-367: Ensure the search icon is accessible

The search icon added lacks accessibility features such as aria-label or role. This may affect users who rely on assistive technologies.

Consider adding an aria-hidden attribute if the icon is purely decorative, or provide an accessible name:

-<i className="fa fa-search position-absolute text-body-tertiary end-0 top-50 translate-middle" />
+<i
+  className="fa fa-search position-absolute text-body-tertiary end-0 top-50 translate-middle"
+  aria-hidden="true"
+/>

If the icon conveys important information, use aria-label:

+  aria-label="Search"
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3d801ca and 5085b7f.

📒 Files selected for processing (9)
  • public/locales/en/translation.json (2 hunks)
  • public/locales/fr/translation.json (2 hunks)
  • public/locales/hi/translation.json (2 hunks)
  • public/locales/sp/translation.json (2 hunks)
  • public/locales/zh/translation.json (2 hunks)
  • src/components/AddPeopleToTag/AddPeopleToTag.tsx (7 hunks)
  • src/screens/ManageTag/ManageTag.tsx (13 hunks)
  • src/screens/OrganizationTags/OrganizationTags.tsx (11 hunks)
  • src/screens/SubTags/SubTags.tsx (10 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • public/locales/en/translation.json
  • public/locales/fr/translation.json
  • public/locales/hi/translation.json
  • public/locales/sp/translation.json
  • public/locales/zh/translation.json
  • src/components/AddPeopleToTag/AddPeopleToTag.tsx
🧰 Additional context used
📓 Learnings (3)
src/screens/ManageTag/ManageTag.tsx (3)
Learnt from: meetulr
PR: PalisadoesFoundation/talawa-admin#2398
File: src/screens/ManageTag/ManageTag.tsx:263-0
Timestamp: 2024-11-02T07:38:14.044Z
Learning: In `src/screens/ManageTag/ManageTag.tsx`, `currentTagName` is guaranteed to be non-empty when constructing the `orgUserTagAncestors` array for breadcrumbs.
Learnt from: meetulr
PR: PalisadoesFoundation/talawa-admin#2398
File: src/screens/ManageTag/ManageTag.tsx:108-0
Timestamp: 2024-11-02T07:39:51.950Z
Learning: In `src/screens/ManageTag/ManageTag.tsx`, when `assignedMemberSearchFirstName` or `assignedMemberSearchLastName` are empty strings, the query in the `useQuery` for `USER_TAGS_ASSIGNED_MEMBERS` intentionally includes filters with empty strings to match all entries.
Learnt from: meetulr
PR: PalisadoesFoundation/talawa-admin#2387
File: src/screens/ManageTag/ManageTag.tsx:113-147
Timestamp: 2024-10-30T13:29:28.310Z
Learning: In the `src/screens/ManageTag/ManageTag.tsx` file, the `InfiniteScroll` component uses the `loadMoreAssignedMembers` function efficiently, and additional error handling is unnecessary.
src/screens/OrganizationTags/OrganizationTags.tsx (1)
Learnt from: meetulr
PR: PalisadoesFoundation/talawa-admin#2387
File: src/screens/OrganizationTags/OrganizationTags.tsx:350-376
Timestamp: 2024-10-30T13:18:56.627Z
Learning: In the `src/screens/OrganizationTags/OrganizationTags.tsx` file, the `OrganizationTags` component uses chunk size with the `InfiniteScroll` component and an outer parent div for handling data loading and scrolling.
src/screens/SubTags/SubTags.tsx (1)
Learnt from: meetulr
PR: PalisadoesFoundation/talawa-admin#2398
File: src/screens/SubTags/SubTags.tsx:77-0
Timestamp: 2024-11-02T07:36:11.553Z
Learning: In the `SubTags` component (`src/screens/SubTags/SubTags.tsx`), when filtering tag names in GraphQL queries, use `starts_with` as per the API's supported types. The `contains` filter is not currently supported by the API, and additional filtering criteria may be added later.
🔇 Additional comments (8)
src/screens/OrganizationTags/OrganizationTags.tsx (4)

52-53: LGTM: Well-structured state management for filtering and sorting

The new state variables are properly typed and initialized with sensible default values.


79-80: LGTM: GraphQL query properly enhanced with filtering and sorting

The query parameters are correctly structured to support the new filtering and sorting functionality.


305-313: LGTM: Search functionality properly implemented

The search implementation is clean and well-integrated with the UI.


327-341: LGTM: Sort functionality well-implemented with clear UX

The sorting implementation provides clear visual feedback and proper internationalization support.

src/screens/SubTags/SubTags.tsx (1)

347-424: Well-implemented infinite scroll with proper loading states

The implementation includes:

  • Proper loading states
  • Infinite scroll with error handling
  • Clear data grid implementation with proper test IDs
src/screens/ManageTag/ManageTag.tsx (3)

135-135: Confirm the placement of istanbul ignore next comment

The /* istanbul ignore next */ comment is placed after the condition. For accurate test coverage reporting, ensure it's correctly positioned.

Please verify that the comment is ignoring the intended line. The comment should precede the line you wish to exclude from coverage.

-if (!fetchMoreResult) /* istanbul ignore next */ return prevResult;
+/* istanbul ignore next */
if (!fetchMoreResult) return prevResult;

Would you like assistance in adjusting the placement to ensure proper coverage reporting?


153-160: Handle cases where the search input is empty

When assignedMemberSearchInput is empty, the firstName and lastName variables may be set to empty strings. Ensure that this behavior aligns with the intended functionality, considering that empty strings are used to match all entries.


64-71: Initialization of state variables for search and sorting

The addition of state variables for managing search inputs and sorting order is appropriate and enhances the component's functionality.

src/screens/ManageTag/ManageTag.tsx Show resolved Hide resolved
src/screens/ManageTag/ManageTag.tsx Show resolved Hide resolved
@rishav-jha-mech rishav-jha-mech merged commit 7707708 into PalisadoesFoundation:develop Nov 2, 2024
10 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants