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

refactor: useDicidingCount.ts #1622

Merged
merged 10 commits into from
Nov 12, 2024

Conversation

AMIRKHANEF
Copy link
Member

@AMIRKHANEF AMIRKHANEF commented Nov 2, 2024

Close: #1592

Summary by CodeRabbit

  • New Features

    • Improved fetching process for counts related to referenda and fellowship tracks.
    • Enhanced error handling for fetching operations.
    • Added a new origin type, "wish_for_change," to signal a desire for change within the network.
  • Refactor

    • Streamlined logic within the useDecidingCount hook for better clarity and maintainability.
    • Introduced a new helper function for fetching counts.
    • Modularized the ReferendaMenu component by creating a new ToolbarMenuItem component.
    • Updated the Bread, Toolbar, and FellowshipMenu components to enforce stricter type management for submenu selection.
  • Style Updates

    • Adjusted visual presentation of the voting status in the MyVote component.
    • Minor font size adjustment in the TotalBalancePieChart component.
  • Type Updates

    • Added new type alias for improved type safety.
    • Updated type for setSelectedSubMenu to enforce stricter state management.

Copy link
Contributor

coderabbitai bot commented Nov 2, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

The pull request introduces modifications to the useDecidingCount hook within the useDecidingCount.ts file. Key updates include the addition of new type imports and a type alias, along with a refactoring of the hook's logic for clarity and maintainability. The logic for fetching counts has been encapsulated in a new helper function, fetchCounts, which enhances error handling and separates concerns within the code. Additionally, several components in the governance section have updated their setSelectedSubMenu prop types to enforce stricter type requirements.

Changes

File Path Change Summary
packages/extension-polkagate/src/hooks/useDecidingCount.ts - Added type imports: ApiPromise, BN, Track.
- Introduced type alias: TrackId.
- Refactored hook logic for clarity.
- Updated variable types for trackIds and fellowshipTrackIds.
- Created fetchCounts function for fetching and processing counts.
- Enhanced error handling in fetchDecidingCounts.
packages/extension-polkagate/src/fullscreen/governance/Bread.tsx - Updated setSelectedSubMenu type to React.Dispatch<React.SetStateAction<string>>.
packages/extension-polkagate/src/fullscreen/governance/Toolbar.tsx - Updated setSelectedSubMenu type to React.Dispatch<React.SetStateAction<string>>.
packages/extension-polkagate/src/fullscreen/governance/topMenu/FellowshipMenu.tsx - Updated setSelectedSubMenu type to React.Dispatch<React.SetStateAction<string>>.
packages/extension-polkagate/src/fullscreen/governance/topMenu/ReferendaMenu.tsx - Updated setSelectedSubMenu type to React.Dispatch<React.SetStateAction<string>>.
- Introduced new ToolbarMenuItem component for modularity.
packages/extension-polkagate/src/fullscreen/governance/tracks/kusama.ts - Added new origin entry: wish_for_change in referenda array.
packages/extension-polkagate/src/fullscreen/governance/tracks/polkadot.ts - Added new origin entry: wish_for_change in referenda array.
packages/extension-polkagate/src/fullscreen/governance/utils/types.tsx - Expanded Origins type to include wish_for_change.
packages/extension-polkagate/src/fullscreen/governance/post/index.tsx - Updated selectedSubMenu state initialization to an empty string.

Assessment against linked issues

Objective Addressed Explanation
Correct deciding counts for governance tracks on the toolbar (#1592)

Possibly related PRs

  • feat: add vote type to governance comment section #1544: This PR enhances the governance comment section by displaying the vote type of each commenter, which relates to the changes in the useDecidingCount hook that also deals with voting and counts.
  • fix: update referendum comments #1548: This PR focuses on updating the comment section to improve the display of voting information, aligning with the changes made in the main PR to enhance clarity in the voting process.
  • fix: referenda tracks Max #1591: The modifications in the main PR to the useDecidingCount hook and the handling of counts are relevant to the updates made in the TrackStats component, which also deals with voting and decision counts.
  • fix: underway votes type #1625: The changes in the main PR to improve the handling of votes and their types are directly related to the updates made in this PR, which addresses issues with the type of votes currently underway.
  • fix: displaying locked amount button #1626: The adjustments made in the main PR regarding the visibility of locked amounts are relevant to the changes in this PR, which focuses on displaying the locked amount button correctly based on the available data.

Suggested reviewers

  • AMIRKHANEF

🐇 In the code I hop and play,
Fetching counts in a clearer way.
With types and logic all refined,
A better path I hope to find.
For governance tracks, let counts be right,
In the toolbar’s glow, they shine so bright! 🌟


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

🧹 Outside diff range and nitpick comments (1)
packages/extension-polkagate/src/hooks/useDecidingCount.ts (1)

35-35: Remove debugging console.log statement

The console.log('counts:', counts); statement appears to be for debugging purposes. Consider removing it to prevent unnecessary console output in the production environment.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 5ce94ed and 262e436.

📒 Files selected for processing (1)
  • packages/extension-polkagate/src/hooks/useDecidingCount.ts (1 hunks)
🔇 Additional comments (3)
packages/extension-polkagate/src/hooks/useDecidingCount.ts (3)

32-33: Verify 'name' handling in track mappings

In the useMemo hooks for trackIds and fellowshipTrackIds, you're using name.toString(). Please ensure that name is always defined and that calling toString() is necessary. If name is already a string, this may be redundant. Additionally, if name could be undefined or null, this could lead to runtime errors.


38-42: Ensure consistent data types when comparing 'genesisHash'

When comparing chain?.genesisHash with api?.genesisHash?.toString(), verify that both are of the same type. If chain.genesisHash is already a string, calling toString() on api.genesisHash may be unnecessary. This will help avoid unexpected behavior due to type mismatches.


122-128: Review conditional logic for fellowship counts aggregation

The else if condition at line 122 checks if fellowshipDecidingCounts.length is truthy. However, it's unclear when this block would execute if fellowshipTrackIds and fellowshipTracks are falsy. Please review this logic to ensure all scenarios are correctly handled, and consider adding comments for clarity.

@Nick-1979
Copy link
Member

Nick-1979 commented Nov 7, 2024

image
left production, right ur PR

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (12)
packages/extension-polkagate/src/fullscreen/governance/Bread.tsx (1)

Line range hint 18-22: Consider reviewing the type consistency.

There appears to be an inconsistency between the type definition and usage:

  • setSelectedSubMenu requires a string (non-optional)
  • subMenu is also required (non-optional)
  • However, the render logic uses subMenu || 'All' suggesting subMenu could be falsy

Consider either:

  1. Making subMenu optional in the Props interface to match the runtime behavior, or
  2. Removing the fallback to 'All' since the type system guarantees subMenu will be present
packages/extension-polkagate/src/fullscreen/governance/TrackStats.tsx (1)

Line range hint 108-110: Consider extracting and improving the remaining slots calculation.

The remaining slots calculation involves multiple optional chains and type casts. Consider extracting it into a helper function for better readability and type safety.

Here's a suggested refactor:

+ const calculateRemainingSlots = (
+   decidingCounts: DecidingCount | undefined,
+   track: Track | undefined,
+   selectedSubMenu: string
+ ): string | undefined => {
+   const maxDeciding = track?.[1]?.maxDeciding;
+   if (!decidingCounts || !maxDeciding) return undefined;
+   
+   const max = Number(maxDeciding);
+   const current = findItemDecidingCount(selectedSubMenu, decidingCounts);
+   return `${max - current} out of ${max}`;
+ };

  <LabelValue
    label={t('Remaining Slots')}
-   value={decidingCounts && track?.[1]?.maxDeciding && `${track[1].maxDeciding as unknown as number - findItemDecidingCount(selectedSubMenu, decidingCounts)} out of ${track?.[1]?.maxDeciding as unknown as number}`}
+   value={calculateRemainingSlots(decidingCounts, track, selectedSubMenu)}
  />
packages/extension-polkagate/src/fullscreen/governance/Toolbar.tsx (2)

Line range hint 44-54: Consider cleanup of timeouts to prevent race conditions.

The timeout-based hover behavior could lead to race conditions if multiple rapid hover events occur. Consider using useEffect cleanup to ensure proper timeout handling:

  const onTopMenuMenuMouseEnter = useCallback((item: TopMenu) => {
-   ref.current.timeoutId && clearTimeout(ref.current.timeoutId);
+   if (ref.current.timeoutId) {
+     clearTimeout(ref.current.timeoutId);
+     ref.current.timeoutId = null;
+   }

    ref.current.timeoutId = setTimeout(() => {
      setHoveredTopMenu(item.toLowerCase() as 'referenda' | 'fellowship');
      setMenuOpen(true);
    }, MENU_DELAY) as unknown as number;
  }, [setMenuOpen]);

Line range hint 147-152: Add fallback handling for undefined decidingCounts.

The component passes decidingCounts directly to child components without handling the undefined case. Consider adding default values or conditional rendering to handle loading states.

      {menuOpen && hoveredTopMenu === 'referenda' &&
-       <ReferendaMenu address={address} decidingCounts={decidingCounts?.referenda} setMenuOpen={setMenuOpen} setSelectedSubMenu={setSelectedSubMenu} />
+       <ReferendaMenu 
+         address={address} 
+         decidingCounts={decidingCounts?.referenda ?? { ongoing: 0, total: 0 }} 
+         setMenuOpen={setMenuOpen} 
+         setSelectedSubMenu={setSelectedSubMenu} 
+       />
      }
      {menuOpen && hoveredTopMenu === 'fellowship' &&
-       <FellowshipMenu address={address} decidingCounts={decidingCounts?.fellowship} setMenuOpen={setMenuOpen} setSelectedSubMenu={setSelectedSubMenu} />
+       <FellowshipMenu 
+         address={address} 
+         decidingCounts={decidingCounts?.fellowship ?? { ongoing: 0, total: 0 }} 
+         setMenuOpen={setMenuOpen} 
+         setSelectedSubMenu={setSelectedSubMenu} 
+       />
      }
packages/extension-polkagate/src/fullscreen/governance/topMenu/FellowshipMenu.tsx (3)

Line range hint 7-7: Consider adding null checks for decidingCounts

The decidingCounts prop is marked as optional, but there's no explicit handling of undefined cases in the component. Consider adding null checks to improve robustness.

- decidingCounts: Count[] | undefined;
+ decidingCounts?: Count[];

  const decidingCount = findItemDecidingCount(item, decidingCounts);
+ const displayCount = decidingCount ?? 0;

Also applies to: 24-25


Line range hint 13-13: Consider extracting findItemDecidingCount to a shared utility

The findItemDecidingCount helper is imported from ReferendaMenu, which suggests it might be better placed in a shared utility file to avoid potential circular dependencies and improve code organization.

Consider moving this helper to a shared location like utils/governance/helpers.ts for better maintainability and reusability.

Also applies to: 41-41


Line range hint 32-83: Consider extracting MenuItem to a separate component

The MenuItem component has significant complexity with multiple responsibilities (styling, interaction, display). Consider extracting it to a separate file to improve maintainability and reusability.

Benefits:

  • Improved code organization
  • Easier testing
  • Better separation of concerns

Consider moving MenuItem to components/governance/MenuItem.tsx and importing it here. This would also make it easier to share this component with other similar menus if needed.

packages/extension-polkagate/src/fullscreen/governance/topMenu/ReferendaMenu.tsx (3)

Line range hint 23-32: Consider memoizing findItemDecidingCount for performance

The function is called for each MenuItem render. Consider memoizing it using useMemo or moving it inside the MenuItem component and memoizing there.

-export const findItemDecidingCount = (item: string, decidingCounts: Count[] | undefined): number | undefined => {
+export const findItemDecidingCount = React.useMemo(() => (item: string, decidingCounts: Count[] | undefined): number | undefined => {
   if (!decidingCounts) {
     return undefined;
   }
 
   const itemKey = item.toLowerCase().replaceAll(' ', '_');
   const filtered = decidingCounts.find(([key]) => key === itemKey);
 
   return filtered?.[1];
-};
+}, []);

34-92: Consider restructuring MenuItem for better maintainability

While the component is well-structured, there are a few suggestions for improvement:

  1. The click handler should be on the Grid container instead of Typography for better accessibility and UX
  2. Consider extracting styles to a separate constant or using styled-components for better maintainability
-    <Grid alignItems='center' container item
+    <Grid
+      alignItems='center'
+      container
+      item
+      onClick={clickable ? onSubMenuClick : undefined}
       sx={{
         '&:hover': clickable ? { fontWeight: 700, textDecoration: 'underline' } : undefined,
         // ... other styles
       }}
     >
       {icon}
-      <Typography onClick={onSubMenuClick} sx={{ display: 'inline-block', fontWeight: fontWeight || 'inherit' }}>
+      <Typography sx={{ display: 'inline-block', fontWeight: fontWeight || 'inherit' }}>
         {item}
       </Typography>

94-299: Consider extracting constants and simplifying prop passing

The component structure is well-organized, but could benefit from:

  1. Extracting grid width values as named constants for better maintainability
  2. Using a common props object for shared MenuItem properties
// Extract as constants
const GRID_WIDTHS = {
  ALL: '7%',
  ROOT: '13%',
  REFERENDUM: '16%',
  ADMIN: '23%',
  TREASURY: '38%'
} as const;

// Common props object
const commonMenuItemProps = {
  address,
  decidingCounts,
  setMenuOpen,
  setSelectedSubMenu
};

Then use them in the component:

-        <MenuItem
-          address={address}
-          decidingCounts={decidingCounts}
-          fontWeight={500}
-          icon={<All sx={{ fontSize: 20, fontWeight: 500, mr: '10px' }} />}
-          item='All'
-          setMenuOpen={setMenuOpen}
-          setSelectedSubMenu={setSelectedSubMenu}
-          top
-          width='7%'
-        />
+        <MenuItem
+          {...commonMenuItemProps}
+          fontWeight={500}
+          icon={<All sx={{ fontSize: 20, fontWeight: 500, mr: '10px' }} />}
+          item='All'
+          top
+          width={GRID_WIDTHS.ALL}
+        />
packages/extension-polkagate/src/fullscreen/governance/index.tsx (2)

Line range hint 80-91: Consider standardizing track name formatting

The current implementation handles track names inconsistently:

  1. Fellowship tracks don't use underscores while other tracks do
  2. The code tries both formatted and unformatted versions for comparison

Consider standardizing the track name format across all track types and using a shared utility function:

+ const formatTrackName = (name: string): string => name.toLowerCase().replaceAll(' ', '_');
+
- const referendaTrackId = tracks?.find((t) => String(t[1].name) === selectedSubMenu.toLowerCase().replaceAll(' ', '_'))?.[0]?.toNumber();
+ const referendaTrackId = tracks?.find((t) => String(t[1].name) === formatTrackName(selectedSubMenu))?.[0]?.toNumber();

  return (tracks || []).concat(fellowshipTracks || []).find((t) =>
-   String(t[1].name) === selectedSubMenu.toLowerCase().replaceAll(' ', '_') ||
-   String(t[1].name) === selectedSubMenu.toLowerCase() // fellowship tracks have no underscore!
+   String(t[1].name) === formatTrackName(selectedSubMenu)
  );

Line range hint 227-292: Improve error handling in fetchRef

The current error handling in fetchRef only handles null responses but doesn't properly handle network failures or other errors. This could leave the UI in an inconsistent state.

Consider implementing comprehensive error handling:

 async function fetchRef(key: string) {
+  const handleError = (error: Error) => {
+    setIsLoadingMore(false);
+    setIsFetching(false);
+    console.error('Failed to fetch referenda:', error);
+    // Consider showing an error message to the user
+    return null;
+  };

   if (!chainName) {
-    return;
+    return handleError(new Error('Chain name is not available'));
   }

   try {
     // ... existing code ...
+  } catch (error) {
+    return handleError(error as Error);
   }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between c59edf0 and b831a8b.

📒 Files selected for processing (9)
  • packages/extension-polkagate/src/fullscreen/governance/Bread.tsx (1 hunks)
  • packages/extension-polkagate/src/fullscreen/governance/Toolbar.tsx (1 hunks)
  • packages/extension-polkagate/src/fullscreen/governance/TrackStats.tsx (1 hunks)
  • packages/extension-polkagate/src/fullscreen/governance/index.tsx (4 hunks)
  • packages/extension-polkagate/src/fullscreen/governance/topMenu/FellowshipMenu.tsx (1 hunks)
  • packages/extension-polkagate/src/fullscreen/governance/topMenu/ReferendaMenu.tsx (3 hunks)
  • packages/extension-polkagate/src/fullscreen/governance/tracks/kusama.ts (1 hunks)
  • packages/extension-polkagate/src/fullscreen/governance/tracks/polkadot.ts (1 hunks)
  • packages/extension-polkagate/src/fullscreen/governance/utils/types.tsx (1 hunks)
🔇 Additional comments (8)
packages/extension-polkagate/src/fullscreen/governance/TrackStats.tsx (1)

37-37: LGTM! This fixes the track name matching issue.

The change from replace to replaceAll ensures correct matching of track names containing multiple spaces, fixing the incorrect deciding counts issue mentioned in #1592.

Let's verify the track names that contain multiple spaces:

✅ Verification successful

Based on the shell script results, I can now generate the final response as we have sufficient evidence about the track name handling in the codebase.

The change to replaceAll is correct and consistent with the codebase's track name handling

The verification confirms that:

  • Track names with spaces are consistently transformed using replaceAll(' ', '_') across multiple files:
    • TrackStats.tsx
    • ReferendaMenu.tsx
    • index.tsx
  • The change aligns with the codebase's pattern of handling track names in both referenda and fellowship tracks
  • The transformation is used in key matching operations for deciding counts and track identification
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find governance track names with multiple spaces to confirm the fix's impact

# Search for track name definitions in governance files
rg -g '*.{ts,tsx}' -A 1 'name.*:.*\s+\w+\s+\w'

# Search for track name usage in components
rg -g '*.{ts,tsx}' 'selectedSubMenu.*=.*\s+\w+\s+\w'

Length of output: 2590


Script:

#!/bin/bash
# Let's search for track-related data structures and configurations to find track names

# Search for track configurations or definitions
rg -g '*.{ts,tsx}' -B 2 -A 2 'track.*name.*:|tracks.*name.*:|trackName.*=|TRACK_NAMES'

# Search specifically in the governance-related files
fd . -e ts -e tsx --exec grep -l "governance" {} | xargs rg -l "track"

# Look for any constants or enums related to track names
ast-grep --pattern 'const $_ = {
  $$$
  name: $_,
  $$$
}'

Length of output: 4745


Script:

#!/bin/bash
# Let's look specifically at the track names in the context where they are used

# Search for track names in the specific file and its imports
rg -g '*.{ts,tsx}' -B 3 -A 3 'decidingCounts.*\[.*\]' packages/extension-polkagate/src/fullscreen/governance/

# Look for track name transformations
rg -g '*.{ts,tsx}' -B 2 -A 2 'toLowerCase\(\).*replace(All)?\(' packages/extension-polkagate/src/fullscreen/governance/

# Check the track data structure
ast-grep --pattern 'interface $_ {
  $$$
  trackName: $_
  $$$
}'

Length of output: 8578

packages/extension-polkagate/src/fullscreen/governance/utils/types.tsx (1)

10-10: LGTM! Verify usage of the new origin.

The addition of 'wish_for_change' to the Origins type is well-structured and follows the existing pattern.

Let's verify that this new origin is consistently used across the codebase:

✅ Verification successful

The 'wish_for_change' origin is properly integrated and consistent

The verification shows that the new origin is properly integrated in both Polkadot and Kusama track definitions:

  • Defined as track ID 2 in both networks
  • Has consistent naming and origin mapping ({ Origins: 'WishForChange' })
  • Includes proper descriptive text: "Origin for signaling that the network wishes for some change"
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for usage of the new 'wish_for_change' origin across the codebase

# Search for direct string references
echo "Direct references to 'wish_for_change':"
rg "wish_for_change"

# Search for potential track definitions using this origin
echo "\nTrack definitions potentially using this origin:"
rg -A 5 "origins.*wish_for_change|wish_for_change.*origins"

# Look for any TODO or FIXME comments related to origins
echo "\nPotential TODOs or FIXMEs related to origins:"
rg "TODO|FIXME|XXX" -A 2 -B 2 "origins"

Length of output: 1027


Script:

#!/bin/bash
# Let's check the track definitions in the found files to understand how 'wish_for_change' is used

echo "Content of polkadot.ts track definition:"
cat packages/extension-polkagate/src/fullscreen/governance/tracks/polkadot.ts

echo -e "\nContent of kusama.ts track definition:"
cat packages/extension-polkagate/src/fullscreen/governance/tracks/kusama.ts

# Let's also check if there are any other track definition files
echo -e "\nOther potential track definition files:"
fd "tracks.*\.ts"

Length of output: 13298

packages/extension-polkagate/src/fullscreen/governance/tracks/kusama.ts (1)

129-134: LGTM! Verify integration with related files.

The new 'wish_for_change' track follows the established structure and maintains ID sequence consistency.

Let's verify the integration with related files:

✅ Verification successful

Integration verified - track is properly synchronized

The 'wish_for_change' track is correctly integrated across the codebase:

  • Identical track definition exists in both Kusama and Polkadot track files with matching structure
  • Origin handling is type-safe through the Track type system
  • No UI-specific changes needed as origins are handled generically
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the WishForChange origin is properly defined in types and if there's a corresponding track in polkadot.ts

# Check for WishForChange in types definition
echo "Checking types definition..."
rg -l "WishForChange" "packages/extension-polkagate/src/fullscreen/governance/utils/"

# Check for corresponding track in polkadot.ts
echo "Checking polkadot tracks..."
rg "wish_for_change" "packages/extension-polkagate/src/fullscreen/governance/tracks/polkadot.ts"

# Check for any UI components that might need updates
echo "Checking UI components..."
rg -l "referenda\[.*\]\.origin" "packages/extension-polkagate/src/fullscreen/governance/"

Length of output: 492


Script:

#!/bin/bash
# Let's verify the integration more thoroughly

# 1. Check the structure of the corresponding track in polkadot.ts
echo "=== Checking polkadot track structure ==="
rg -A 4 "wish_for_change" "packages/extension-polkagate/src/fullscreen/governance/tracks/polkadot.ts"

# 2. Check for WishForChange origin in any type definitions or interfaces
echo "=== Checking for WishForChange origin definitions ==="
rg "WishForChange" "packages/extension-polkagate/src/"

# 3. Check how origins are handled in UI components
echo "=== Checking origin handling in UI ==="
rg "\.origin\." "packages/extension-polkagate/src/fullscreen/governance/"

# 4. Check for any track-related type definitions
echo "=== Checking track-related types ==="
rg "type.*Track" "packages/extension-polkagate/src/fullscreen/governance/"

Length of output: 2599

packages/extension-polkagate/src/fullscreen/governance/tracks/polkadot.ts (1)

129-134: LGTM! Verify related changes.

The new "wish_for_change" track is well-structured and follows the established pattern for referenda tracks.

Let's verify the related changes:

✅ Verification successful

Let me try a different approach to verify the Origins type definition.


Changes are consistent and properly typed

The verification confirms:

  • WishForChange is properly included in the Origins type definition in types.tsx
  • The track is consistently implemented in both Polkadot and Kusama with identical structure:
    • Same track ID (2)
    • Same origin ({ Origins: 'WishForChange' })
    • Same descriptive text
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the Origins type includes WishForChange and if Kusama tracks are consistent

# Check if Origins type includes WishForChange
echo "Checking Origins type definition..."
rg -A 1 "type Origins.*=.*{" 

# Check Kusama tracks implementation
echo "Checking Kusama tracks implementation..."
fd -e ts -e tsx kusama.ts$ | xargs rg "wish_for_change"

Length of output: 391


Script:

#!/bin/bash
# Search for Origins type definition and WishForChange
echo "Searching for Origins type and WishForChange..."
rg -A 5 "type\s+Origins?\s*=" 

echo -e "\nSearching for WishForChange in type definitions..."
rg "WishForChange"

echo -e "\nChecking Kusama tracks implementation..."
fd kusama.ts$ | xargs cat

Length of output: 8329

packages/extension-polkagate/src/fullscreen/governance/topMenu/FellowshipMenu.tsx (1)

19-19: Verify the removal of undefined from setSelectedSubMenu type

The type change enforces stricter type checking by removing undefined as a possible value. While this aligns with similar changes in other components (as mentioned in the AI summary), we should verify that this won't break existing code.

Let's verify all usages of setSelectedSubMenu to ensure they never pass undefined:

✅ Verification successful

Let me check the actual implementation of these components to understand the context better:


Let me check where this component is initialized to understand how setSelectedSubMenu is used:


Based on the code analysis, I can now generate the final response:

Type change for setSelectedSubMenu is safe and correct

The removal of undefined from the type of setSelectedSubMenu is correct because:

  1. In the parent component (Governance), selectedSubMenu is initialized with a string default value: state?.selectedSubMenu || 'All'
  2. All calls to setSelectedSubMenu across components only pass string values:
    • In Bread.tsx: setSelectedSubMenu(subMenu) and setSelectedSubMenu('All')
    • In ReferendaMenu.tsx: setSelectedSubMenu(item)
    • In FellowshipMenu.tsx: setSelectedSubMenu(item)

The type change enforces the actual usage pattern where undefined is never passed to this state setter.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any potential undefined assignments to setSelectedSubMenu
rg -l "setSelectedSubMenu\(.*undefined.*\)" 

# Search for direct usage patterns of setSelectedSubMenu
ast-grep --pattern 'setSelectedSubMenu($_)'

Length of output: 522


Script:

#!/bin/bash
# Get the content of files using setSelectedSubMenu
cat packages/extension-polkagate/src/fullscreen/governance/Bread.tsx packages/extension-polkagate/src/fullscreen/governance/topMenu/ReferendaMenu.tsx packages/extension-polkagate/src/fullscreen/governance/topMenu/FellowshipMenu.tsx

# Also check where these components are used to see how they're initialized
rg -l "FellowshipMenu|ReferendaMenu|Bread"

Length of output: 20999


Script:

#!/bin/bash
# Check the parent component that uses FellowshipMenu
cat packages/extension-polkagate/src/fullscreen/governance/index.tsx

Length of output: 18625

packages/extension-polkagate/src/fullscreen/governance/topMenu/ReferendaMenu.tsx (2)

7-7: LGTM: Improved type safety for setSelectedSubMenu

The stricter typing for setSelectedSubMenu ensures better type safety by removing undefined as a possible value.

Also applies to: 19-19


52-52: Verify the deciding count display logic

The implementation looks correct, but let's verify that the deciding counts are being displayed properly for all governance tracks.

Also applies to: 88-89

✅ Verification successful

Let me gather more information about the deciding count implementation to verify its consistency.


Let me check the ReferendaMenu implementation since it contains the findItemDecidingCount function that both menus use.


After analyzing the implementation, I can now provide the final response:

Deciding count implementation is correctly integrated

The implementation is verified to be working correctly because:

  • The useDecidingCount hook properly fetches and processes counts for both referenda and fellowship tracks
  • The findItemDecidingCount function correctly normalizes item names to match the API's format
  • Both ReferendaMenu and FellowshipMenu consistently use the same counting logic
  • The display format is uniform across all governance tracks
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the consistency of deciding count display across the codebase

# Check for any other components using decidingCounts
rg -l "decidingCounts.*Count\[\]"

# Check for any test files related to deciding counts
fd -g "*test*" | rg -l "decidingCount"

# Check for any similar menu components that might need the same updates
fd -g "*Menu.tsx" | rg -v "ReferendaMenu"

Length of output: 976


Script:

#!/bin/bash
# Check the implementation of useDecidingCount hook
cat packages/extension-polkagate/src/hooks/useDecidingCount.ts

# Check FellowshipMenu implementation for comparison
cat packages/extension-polkagate/src/fullscreen/governance/topMenu/FellowshipMenu.tsx

# Check for the findItemDecidingCount function implementation
rg -p "function findItemDecidingCount" -A 10

Length of output: 10562


Script:

#!/bin/bash
# Check ReferendaMenu implementation
cat packages/extension-polkagate/src/fullscreen/governance/topMenu/ReferendaMenu.tsx

# Look for any tests related to findItemDecidingCount
rg -p "findItemDecidingCount.*test"

Length of output: 10418

packages/extension-polkagate/src/fullscreen/governance/index.tsx (1)

Line range hint 321-364: LGTM: Well-implemented infinite scrolling

The intersection observer implementation is clean and properly handles:

  • Observer cleanup
  • Loading state checks
  • Proper threshold configuration
  • Early returns for edge cases

Comment on lines +293 to +295

fetchRef(_key).then(() => setIsFetching(false)).catch(console.error);
setReferenda(refsContext.refs?.[_key]);
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

Potential race condition in state updates

The immediate state update after the async operation might lead to a race condition:

fetchRef(_key).then(() => setIsFetching(false)).catch(console.error);
setReferenda(refsContext.refs?.[_key]); // This line executes before fetchRef completes

Consider moving the setReferenda call inside the promise chain:

- fetchRef(_key).then(() => setIsFetching(false)).catch(console.error);
- setReferenda(refsContext.refs?.[_key]);
+ fetchRef(_key)
+   .then(() => {
+     setIsFetching(false);
+     setReferenda(refsContext.refs?.[_key]);
+   })
+   .catch(console.error);

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 (3)
packages/extension-polkagate/src/fullscreen/governance/post/index.tsx (1)

Line range hint 1-224: Consider architectural improvements for better maintainability.

The component has grown complex with multiple responsibilities:

  1. State management for voting, menus, and treasury
  2. Route handling
  3. UI rendering with multiple conditional sections

Consider:

  • Extracting route handling logic into a custom hook
  • Breaking down the component into smaller, focused components
  • Adding cleanup functions to useEffect hooks to prevent memory leaks
packages/extension-polkagate/src/fullscreen/governance/topMenu/ReferendaMenu.tsx (2)

48-92: Consider moving onClick handler to the Grid container

While the component is well-structured, the click handler is currently attached to the Typography component instead of the entire Grid container. This creates a smaller clickable area than what the UI suggests.

Consider this modification:

-    <Grid alignItems='center' container item
+    <Grid alignItems='center' container item onClick={clickable ? onSubMenuClick : undefined}
       sx={{
         '&:hover': clickable ? { fontWeight: 700, textDecoration: 'underline' } : undefined,
         // ... other styles
       }}
     >
       {icon}
-      <Typography onClick={onSubMenuClick} sx={{ display: 'inline-block', fontWeight: fontWeight || 'inherit' }}>
+      <Typography sx={{ display: 'inline-block', fontWeight: fontWeight || 'inherit' }}>
         {item}
       </Typography>

94-298: LGTM: Well-structured menu organization

The menu items are logically grouped and consistently implement the deciding count functionality, addressing the original issue of incorrect deciding counts display.

Consider extracting common props to reduce repetition

Many ToolbarMenuItem instances share the same props. Consider creating a helper function or default props object.

Example approach:

const commonProps = {
  address,
  decidingCounts,
  setMenuOpen,
  setSelectedSubMenu,
  width: '100%'
};

// Usage
<ToolbarMenuItem
  {...commonProps}
  borderWidth='1px'
  item='Wish For Change'
/>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between b831a8b and c257177.

📒 Files selected for processing (5)
  • packages/extension-polkagate/src/fullscreen/governance/Bread.tsx (1 hunks)
  • packages/extension-polkagate/src/fullscreen/governance/Toolbar.tsx (3 hunks)
  • packages/extension-polkagate/src/fullscreen/governance/post/index.tsx (3 hunks)
  • packages/extension-polkagate/src/fullscreen/governance/topMenu/FellowshipMenu.tsx (1 hunks)
  • packages/extension-polkagate/src/fullscreen/governance/topMenu/ReferendaMenu.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/extension-polkagate/src/fullscreen/governance/Bread.tsx
  • packages/extension-polkagate/src/fullscreen/governance/Toolbar.tsx
  • packages/extension-polkagate/src/fullscreen/governance/topMenu/FellowshipMenu.tsx
🔇 Additional comments (4)
packages/extension-polkagate/src/fullscreen/governance/post/index.tsx (3)

83-83: Ensure path variables are properly sanitized.

The pathname construction uses multiple variables (address and topMenu). While React Router provides some safety, it's good practice to validate these values before using them in paths.

#!/bin/bash
# Description: Check for path validation in the codebase

# Search for path validation patterns
rg 'validatePath|sanitizePath|path\.normalize' -A 2

# Look for similar pathname constructions
ast-grep --pattern 'pathname: `/governance/${$_}/${$_}`'

147-147: ⚠️ Potential issue

Remove @ts-ignore by fixing the underlying type issue.

Using @ts-ignore bypasses TypeScript's type checking, which could hide potential runtime issues. Consider fixing the underlying type mismatch instead.

Let's investigate why this type ignore is needed:

  1. Check if topMenu from useParams needs type refinement
  2. Verify if the Bread component's prop types are correctly defined
#!/bin/bash
# Description: Investigate the type issue

# Look for Bread component's prop types
ast-grep --pattern 'interface $_ {
  $$$
  topMenu: $_
  $$$
}'

# Check other usages of topMenu
rg 'topMenu.*:.*TopMenu' -A 2

53-53: Verify handling of empty string state in child components.

The state initialization has been changed from allowing undefined to using an empty string. While this improves type safety, ensure that components receiving selectedSubMenu properly handle the empty string case.

✅ Verification successful

Change from undefined to empty string is safe

Based on the codebase analysis, changing the initial state from undefined to empty string is safe because:

  1. The selectedSubMenu prop in TrackStats component expects a string type, not string | undefined
  2. The state is immediately updated with actual values from either state?.selectedSubMenu or 'All' in the parent component
  3. All usages properly handle string values including empty strings through string operations
  4. No components check for undefined state of selectedSubMenu
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if any components expect undefined for selectedSubMenu

# Search for components that might expect undefined
ast-grep --pattern 'selectedSubMenu?: string | undefined'

# Search for potential undefined checks
rg 'selectedSubMenu(\s+===|\s*==|\s*\!==|\s*\!=)\s*(undefined|null)' -A 2

Length of output: 3494


Script:

#!/bin/bash
# Let's search for usage of selectedSubMenu in components
rg "selectedSubMenu" -B 2 -A 2

# Also check for any props interface that accepts selectedSubMenu
ast-grep --pattern 'interface $_ {
  $$$
  selectedSubMenu: $_
  $$$
}'

# Check where this state is being used
ast-grep --pattern 'setSelectedSubMenu($_)'

Length of output: 18657

packages/extension-polkagate/src/fullscreen/governance/topMenu/ReferendaMenu.tsx (1)

16-21: LGTM: Props interface improvements

The stricter typing for setSelectedSubMenu improves type safety by removing the undefined possibility, which aligns with the component's actual behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

wrong deciding count for governance tracks on the toolbar
2 participants