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: allow user to leave a group #88

Merged
merged 3 commits into from
Nov 27, 2024
Merged

feat: allow user to leave a group #88

merged 3 commits into from
Nov 27, 2024

Conversation

chalabi2
Copy link
Collaborator

@chalabi2 chalabi2 commented Nov 26, 2024

fixes #50

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced YourGroups component to support data refreshing via a new refetch prop.
    • Introduced a handleLeave function in the GroupInfo component to facilitate group departure with transaction management.
  • Improvements

    • Updated button functionality in the GroupInfo modal to disable the "Leave" button during transactions and display a loading state.
    • Improved group data handling by linking the onUpdate prop to trigger data refetching.

These changes streamline group management and enhance user experience within the application.

Copy link
Contributor

coderabbitai bot commented Nov 26, 2024

Walkthrough

The changes in this pull request primarily focus on enhancing the functionality of the YourGroups and GroupInfo components. A new refetch prop is introduced to allow data refreshing in YourGroups, while member-related state management is removed for simplification. The GroupInfo component is updated to include transaction handling for leaving a group, with improved error handling and button states. Overall, these modifications streamline component interactions and enhance group management capabilities.

Changes

File Change Summary
components/groups/components/myGroups.tsx - Added refetch prop to YourGroups component.
- Removed members, groupId, and groupAdmin state variables.
- Updated onUpdate prop in GroupInfo to use refetch.
components/groups/modals/groupInfo.tsx - Removed useBalance and shiftDigits imports.
- Added useFeeEstimation, useTx, and chainName.
- Introduced handleLeave method for leaving a group.
- Updated button states for transaction handling.
pages/groups/index.tsx - Updated useProposalsByPolicyAccountAll to include refetchProposals.
- Passed refetch prop to YourGroups.
- Changed onUpdate prop in GroupInfo to use refetchGroupByMember.

Assessment against linked issues

Objective Addressed Explanation
One should be able to leave a group (#50)

Possibly related PRs

  • fix: admin theme #42: The changes in the main PR involve updates to the GroupInfo component's onUpdate prop to utilize a refetch function, which aligns with the modifications in the Groups component in pages/groups/index.tsx that also updates the onUpdate prop to use refetchGroupByMember. Both PRs focus on enhancing data refresh capabilities related to group management.
  • chalabi/modal fixes #87: While this PR primarily addresses modal functionality, it includes improvements to the user interface when adding new group members, which may relate to the overall user experience in managing groups as seen in the main PR's updates to the YourGroups component.

Suggested labels

render

Suggested reviewers

  • chalabi2

🐰 "In the groups we hop and play,
A button now to leave the fray.
With a click, the choice is clear,
Refreshing data, have no fear!
Simplified, we bounce along,
In our happy group, we belong!" 🐇


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
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: 2

🧹 Outside diff range and nitpick comments (5)
pages/groups/index.tsx (2)

85-85: Consider reducing duplication of YourGroups component

The YourGroups component is rendered twice with identical props in different conditions. Consider extracting it to a single component render with conditional wrapping.

- {isLoading ? (
-   <YourGroups
-     groups={groupByMemberData ?? { groups: [] }}
-     proposals={proposalsByPolicyAccount}
-     isLoading={isLoading}
-     refetch={refetchGroupByMember}
-   />
- ) : isError ? (
+ {isError ? (
    <div className="text-center text-error">Error loading groups or proposals</div>
  ) : groupByMemberData?.groups.length === 0 ? (
    <NoGroupsFound />
  ) : (
    <>
      <YourGroups
        groups={groupByMemberData ?? { groups: [] }}
        proposals={proposalsByPolicyAccount}
        isLoading={isLoading}
        refetch={refetchGroupByMember}
      />
      {selectedPolicyAddress && (
        <GroupInfo

Also applies to: 97-97


Line range hint 85-109: Consider implementing React Query or similar state management

The current implementation passes refetch callbacks through multiple levels of components. Consider using React Query or a similar state management solution to handle data fetching and cache invalidation more efficiently. This would:

  • Reduce prop drilling
  • Provide automatic background refetching
  • Handle loading and error states more consistently
  • Improve caching and performance
components/groups/components/myGroups.tsx (2)

26-26: Add JSDoc documentation for the refetch prop

While the refetch prop addition is good for handling data updates, its purpose and timing of invocation should be documented for better maintainability.

Add JSDoc documentation above the props interface:

+/**
+ * @param refetch Callback function to refresh groups data after operations like leaving a group
+ */
export function YourGroups({
  groups,
  proposals,
  isLoading,
  refetch,
}: {

Also applies to: 31-31


Line range hint 227-244: Consider consistent update handling across modals

While GroupInfo now correctly uses the refetch callback, MemberManagementModal still uses an empty callback. For consistency in data refresh handling, consider using the refetch callback for both modals.

          <MemberManagementModal
            modalId={`member-management-modal-${group.id}`}
            members={group.members.map(member => ({
              ...member.member,
              address: member?.member?.address || '',
              weight: member?.member?.weight || '0',
              metadata: member?.member?.metadata || '',
              added_at: member?.member?.added_at || new Date(),
              isCoreMember: true,
              isActive: true,
              isAdmin: member?.member?.address === group.admin,
              isPolicyAdmin: member?.member?.address === group.policies[0]?.admin,
            }))}
            groupId={group.id.toString()}
            groupAdmin={group.admin}
            policyAddress={group.policies[0]?.address ?? ''}
            address={address ?? ''}
-           onUpdate={() => {}}
+           onUpdate={refetch}
          />
components/groups/modals/groupInfo.tsx (1)

119-119: Update error message to reflect the correct operation

The error message in the catch block refers to submitting a proposal, but the operation is actually leaving a group. Update the error message to accurately reflect the action being performed.

Apply this diff:

- console.error('Error submitting proposal:', error);
+ console.error('Error leaving group:', error);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 263a5e1 and 66e1d4a.

📒 Files selected for processing (3)
  • components/groups/components/myGroups.tsx (2 hunks)
  • components/groups/modals/groupInfo.tsx (4 hunks)
  • pages/groups/index.tsx (4 hunks)
🔇 Additional comments (2)
pages/groups/index.tsx (2)

109-109: LGTM! Proper data refresh implementation

Setting onUpdate to refetchGroupByMember ensures that the groups list is properly refreshed after a user leaves a group, maintaining data consistency.


22-22: Verify if refetchProposals is needed

The refetchProposals function is being destructured but not used anywhere in the component. Consider removing it if it's not needed for the current implementation.

-  const { proposalsByPolicyAccount, isProposalsError, isProposalsLoading, refetchProposals } =
+  const { proposalsByPolicyAccount, isProposalsError, isProposalsLoading } =

Comment on lines 119 to 120
console.error('Error submitting proposal:', error);
} finally {
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Provide user feedback when an error occurs during leave operation

Currently, if an error occurs while leaving the group, the user is not notified. Consider displaying a user-friendly error message to inform the user of the issue.

Add code to display an error notification to the user. For example:

catch (error) {
  console.error('Error leaving group:', error);
+  // Display error to the user
+  showErrorNotification('An error occurred while leaving the group. Please try again.');
} finally {
  setIsSigning(false);
}

Ensure that showErrorNotification is an appropriate method or component in your application for displaying errors.

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines 143 to 153
<button
aria-label={'update-btn'}
className="btn btn-dropdown text-white rounded-[12px] h-[52px] w-[140px]"
onClick={handleLeave}
disabled={isSigning}
>
{isSigning ? <span className="animate-pulse">Leaving</span> : 'Leave'}
</button>

<button
aria-label={'update-btn'}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Duplicate aria-label values for buttons cause accessibility issues

Both the "Leave" and "Update" buttons have the same aria-label value 'update-btn', which can cause confusion for users relying on assistive technologies.

Assign unique and descriptive aria-labels to each button. Apply this diff:

<button
-   aria-label={'update-btn'}
+   aria-label={'leave-group-btn'}
    className="btn btn-dropdown text-white rounded-[12px] h-[52px] w-[140px]"
    onClick={handleLeave}
    disabled={isSigning}
>
  {isSigning ? <span className="animate-pulse">Leaving</span> : 'Leave'}
</button>

<button
-   aria-label={'update-btn'}
+   aria-label={'update-group-btn'}
    className="btn btn-gradient text-white rounded-[12px] h-[52px] w-[140px]"
    onClick={() => {
      const modal = document.getElementById('update-group-modal') as HTMLDialogElement;
      if (modal) modal.showModal();
    }}
>
  Update
</button>

Committable suggestion skipped: line range outside the PR's diff.

Copy link

codecov bot commented Nov 27, 2024

Codecov Report

Attention: Patch coverage is 53.19149% with 22 lines in your changes missing coverage. Please review.

Project coverage is 59.73%. Comparing base (263a5e1) to head (63094f7).
Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
components/groups/modals/groupInfo.tsx 51.11% 22 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #88      +/-   ##
==========================================
+ Coverage   58.85%   59.73%   +0.88%     
==========================================
  Files         145      145              
  Lines       14040    14175     +135     
==========================================
+ Hits         8263     8468     +205     
+ Misses       5777     5707      -70     

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (1)
components/groups/modals/groupInfo.tsx (1)

142-162: Add confirmation dialog for leave action

Consider adding a confirmation dialog before executing the leave action to prevent accidental group departures.

 <button
   aria-label={'leave-btn'}
   className="btn btn-dropdown text-white rounded-[12px] h-[52px] w-[140px]"
-  onClick={handleLeave}
+  onClick={() => {
+    if (window.confirm('Are you sure you want to leave this group?')) {
+      handleLeave();
+    }
+  }}
   disabled={isSigning}
 >
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 66e1d4a and e66971f.

📒 Files selected for processing (1)
  • components/groups/modals/groupInfo.tsx (4 hunks)
🧰 Additional context used
🪛 GitHub Check: codecov/patch
components/groups/modals/groupInfo.tsx

[warning] 101-120: components/groups/modals/groupInfo.tsx#L101-L120
Added lines #L101 - L120 were not covered by tests

🔇 Additional comments (3)
components/groups/modals/groupInfo.tsx (3)

6-8: LGTM: Clean import additions

The new imports are well-organized and appropriate for implementing the transaction handling functionality.


101-123: ⚠️ Potential issue

Enhance error handling and add test coverage

The handleLeave implementation needs improvements in two areas:

  1. Error handling needs user feedback (previous comment still applies)
  2. Test coverage is missing for this critical functionality

For error handling, apply this diff:

 } catch (error) {
   console.error('Error submitting proposal:', error);
+  // Show error to user
+  const errorMessage = error instanceof Error ? error.message : 'Failed to leave group';
+  // Use your notification system, e.g.:
+  // toast.error(errorMessage);
 } finally {

Would you like me to help create unit tests for the leave group functionality?

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 101-120: components/groups/modals/groupInfo.tsx#L101-L120
Added lines #L101 - L120 were not covered by tests


Line range hint 101-162: Verify removal of Leave Group from proposal creation

The implementation successfully adds direct group leaving functionality. Let's verify the removal of "Leave Group" from proposal creation UI.

✅ Verification successful

Leave Group functionality has been correctly moved from proposals to direct action

The implementation aligns with the PR objectives. The codebase shows:

  1. Direct Leave Group functionality is implemented in groupInfo.tsx
  2. While leaveGroup message type still exists in the message definitions, it's only used as a message composer for the direct action, not for proposal creation
  3. The Leave Group option has been removed from the active proposal message types in the UI, as it's not listed in the messageTypes array in ProposalMessages.tsx
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining references to "Leave Group" in proposal creation
rg -i "leave.*group" --type ts --type tsx

Length of output: 71


Script:

#!/bin/bash
# Search for any remaining references to "Leave Group" in proposal creation, adjusting file types
rg -i "leave.*group" -g '*.ts' -g '*.tsx'

Length of output: 1469


Script:

#!/bin/bash
# Let's check the proposal message form components to see if Leave Group is still available in the UI
ast-grep --pattern 'case "leaveGroup"' -l ts,tsx

# Also check the actual implementation of proposal messages
cat components/groups/forms/proposals/ProposalMessages.tsx

Length of output: 44114


Script:

#!/bin/bash
# Let's check the proposal message form components to see if Leave Group is still available in the UI
cat components/groups/forms/proposals/messages.ts

Length of output: 3728

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 101-120: components/groups/modals/groupInfo.tsx#L101-L120
Added lines #L101 - L120 were not covered by tests

Comment on lines +18 to +20
const { tx, isSigning, setIsSigning } = useTx(chainName);
const { leaveGroup } = cosmos.group.v1.MessageComposer.withTypeUrl;
const { estimateFee } = useFeeEstimation(chainName);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for fee estimation

While the transaction hooks are properly set up, consider adding error handling for fee estimation failures.

- const { estimateFee } = useFeeEstimation(chainName);
+ const { estimateFee, error: feeError } = useFeeEstimation(chainName);
+ 
+ useEffect(() => {
+   if (feeError) {
+     console.error('Fee estimation error:', feeError);
+     // Consider showing user feedback
+   }
+ }, [feeError]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { tx, isSigning, setIsSigning } = useTx(chainName);
const { leaveGroup } = cosmos.group.v1.MessageComposer.withTypeUrl;
const { estimateFee } = useFeeEstimation(chainName);
const { tx, isSigning, setIsSigning } = useTx(chainName);
const { leaveGroup } = cosmos.group.v1.MessageComposer.withTypeUrl;
const { estimateFee, error: feeError } = useFeeEstimation(chainName);
useEffect(() => {
if (feeError) {
console.error('Fee estimation error:', feeError);
// Consider showing user feedback
}
}, [feeError]);

@fmorency
Copy link
Contributor

Added the following

  • Close modal when leaving tx is a success
  • Fix leave button aria-label (fixes test)
  • Fix leave button colors

@fmorency fmorency merged commit bd782d5 into main Nov 27, 2024
7 of 8 checks passed
@fmorency fmorency deleted the chalabi/leave_group branch November 27, 2024 15:04
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 (2)
components/groups/modals/groupInfo.tsx (2)

104-109: Add input validation for group ID

The group ID should be validated before attempting the transaction.

 try {
+  if (!group?.id) {
+    throw new Error('Invalid group ID');
+  }
   const msg = leaveGroup({
     address: address,
     groupId: group?.id,
   });

144-164: Add confirmation dialog before leaving group

Consider adding a confirmation step before executing the leave operation, as it's a destructive action.

 <button
   aria-label={'leave-btn'}
   className="btn btn-error text-white disabled:bg-red-900 rounded-[12px] h-[52px] w-[140px]"
-  onClick={handleLeave}
+  onClick={() => {
+    const confirmed = window.confirm('Are you sure you want to leave this group?');
+    if (confirmed) {
+      handleLeave();
+    }
+  }}
   disabled={isSigning}
 >
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between e66971f and 63094f7.

📒 Files selected for processing (1)
  • components/groups/modals/groupInfo.tsx (4 hunks)
🧰 Additional context used
🪛 GitHub Check: codecov/patch
components/groups/modals/groupInfo.tsx

[warning] 101-122: components/groups/modals/groupInfo.tsx#L101-L122
Added lines #L101 - L122 were not covered by tests

🔇 Additional comments (5)
components/groups/modals/groupInfo.tsx (5)

6-8: LGTM: Imports are appropriate for transaction handling

The new imports provide the necessary functionality for transaction management and chain configuration.


146-146: Improve button accessibility with descriptive aria-labels

The current aria-labels are not descriptive enough.

- aria-label={'leave-btn'}
+ aria-label={'leave-group-btn'}
- aria-label={'update-btn'}
+ aria-label={'update-group-btn'}

Also applies to: 155-155


18-20: 🛠️ Refactor suggestion

Add error handling for fee estimation

While the transaction hooks are properly set up, consider adding error handling for fee estimation failures.

- const { estimateFee } = useFeeEstimation(chainName);
+ const { estimateFee, error: feeError } = useFeeEstimation(chainName);
+ 
+ useEffect(() => {
+   if (feeError) {
+     console.error('Fee estimation error:', feeError);
+     // Consider showing user feedback
+   }
+ }, [feeError]);

101-125: Add test coverage for leave group functionality

The new leave group functionality lacks test coverage according to static analysis.

Would you like me to help create test cases for the leave group functionality?

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 101-122: components/groups/modals/groupInfo.tsx#L101-L122
Added lines #L101 - L122 were not covered by tests


101-125: 🛠️ Refactor suggestion

Add comprehensive error handling and user feedback

The current implementation only logs errors to console. Users should be notified of failures.

 } catch (error) {
   console.error('Error leaving group:', error);
+  const modal = document.getElementById('error-toast') as HTMLDialogElement;
+  if (modal) {
+    modal.textContent = 'Failed to leave group. Please try again.';
+    modal.showModal();
+  }
 }

Likely invalid or redundant comment.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 101-122: components/groups/modals/groupInfo.tsx#L101-L122
Added lines #L101 - L122 were not covered by tests

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.

One should be able to leave a group
2 participants