Skip to content

Conversation

@RanaBug
Copy link
Collaborator

@RanaBug RanaBug commented Sep 11, 2025

Description

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Summary by CodeRabbit

  • New Features
    • Search now shows a loading indicator while wallet portfolio data is fetching and adds a manual refresh action. Refresh controls reflect progress and are disabled during active loads, improving feedback.
    • Preview Sell modal now supports click-outside-to-close, making it faster to dismiss without using buttons and reducing friction across modal interactions.

@RanaBug RanaBug requested a review from IAmKio September 11, 2025 13:32
@RanaBug RanaBug self-assigned this Sep 11, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 11, 2025

Walkthrough

Adds wallet portfolio fetching state and refetch propagation from AppWrapper to Search via new props. Updates Search to display loading and trigger refetch for wallet portfolio. Enhances PreviewSell with a click-outside-to-close behavior using a ref and document listener. No public API changes except new optional Search props.

Changes

Cohort / File(s) Summary
Wallet portfolio fetch propagation
src/apps/pulse/components/App/AppWrapper.tsx, src/apps/pulse/components/Search/Search.tsx
AppWrapper reads isFetching and refetch from useGetWalletPortfolioQuery and passes them to Search as walletPortfolioFetching and refetchWalletPortfolio. Search props interface updated (optional), refresh controls bind isLoading/disabled to walletPortfolioFetching and onClick to refetchWalletPortfolio.
PreviewSell modal outside-click close
src/apps/pulse/components/Sell/PreviewSell.tsx
Adds useRef and a document mousedown listener to close the modal when clicking outside. Ref attached to wrapper; effect cleans up on unmount or closePreview change. No public interface changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant AppWrapper
  participant Search
  participant WalletQuery as useGetWalletPortfolioQuery

  AppWrapper->>WalletQuery: subscribe { data, isFetching, refetch }
  AppWrapper->>Search: props { walletPortfolioFetching, refetchWalletPortfolio }

  User->>Search: Click Refresh
  Search->>WalletQuery: refetch()
  WalletQuery-->>AppWrapper: isFetching = true
  AppWrapper-->>Search: walletPortfolioFetching = true
  Note over Search: Refresh shows loading/disabled
  WalletQuery-->>AppWrapper: data loaded, isFetching = false
  AppWrapper-->>Search: walletPortfolioFetching = false
Loading
sequenceDiagram
  autonumber
  actor User
  participant PreviewSell
  participant Document

  PreviewSell->>PreviewSell: mount, set ref on wrapper
  PreviewSell->>Document: addEventListener('mousedown', handler)
  User->>Document: mousedown outside wrapper
  Document->>PreviewSell: handler detects outside
  PreviewSell->>PreviewSell: closePreview()
  PreviewSell-->>Document: cleanup listener on unmount
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • IAmKio
  • vignesha22

Pre-merge checks (2 warnings, 1 inconclusive)

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR description currently only contains the template placeholders (dashes) and includes no summary of changes, no testing details, no screenshots, and the types-of-changes checklist is left unchecked. This is insufficient for review because the changes include public API additions (walletPortfolioFetching and refetchWalletPortfolio on Search) and a UX behavior change in PreviewSell that require explicit testing and impact notes. Complete template sections are required so reviewers can assess scope, testing, and compatibility. Fill the Description with a concise summary of what changed (files and key behavioral/API changes), complete "How Has This Been Tested?" with explicit manual and/or automated test steps and environment details, attach screenshots or recordings if relevant, and mark the appropriate "Types of changes" checkbox; also call out the new public props and any backward-compatibility notes or QA sign-off information. Providing these details will make the PR reviewable.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive The current title "minor UI fixes after QA review" is overly generic and does not identify the primary code changes in this PR — notably the addition of walletPortfolioFetching and refetchWalletPortfolio props propagated from AppWrapper into Search, and the outside-click-to-close behavior added to PreviewSell. Because it lacks specificity, a teammate scanning history cannot quickly understand the main change or intent. The title should be updated to a concise, specific one-line summary of the primary change. Update the PR title to succinctly state the main change; for example: "Propagate wallet portfolio fetching to Search (walletPortfolioFetching/refetch) and add outside-click close to PreviewSell" or the shorter "Search: add walletPortfolioFetching/refetch; PreviewSell: outside-click close". Ensure it is a single clear sentence that highlights the primary change.

Poem

A rabbit taps refresh with glee,
Loading wheels spin merrily.
A portfolio hops back anew—
Click outside, the modal bids adieu.
Ears up, code neat, signals true,
Burrowed flows now peek right through. 🐇✨

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/PRO-3638/sell-feature-pulse

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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

🧹 Nitpick comments (5)
src/apps/pulse/components/Sell/PreviewSell.tsx (2)

80-96: Harden outside-click handling for touch, portals, and in-flight actions.

Current listener is mousedown and always closes, which can miss touch on some devices and can close during an in‑flight sell. Consider:

  • Use pointerdown for unified mouse/touch.
  • Ignore while isExecuting to prevent accidental close mid-flow.
  • Use event.composedPath() (fallback to contains) to better handle shadow DOM/portals.
  • (Optional) use capture to avoid interference from stopPropagation.

Proposed diff:

-  // Click outside to close functionality
-  useEffect(() => {
-    const handleClickOutside = (event: MouseEvent) => {
-      if (
-        previewModalRef.current &&
-        !previewModalRef.current.contains(event.target as Node)
-      ) {
-        closePreview();
-      }
-    };
-
-    document.addEventListener('mousedown', handleClickOutside);
-    return () => {
-      document.removeEventListener('mousedown', handleClickOutside);
-    };
-  }, [closePreview]);
+  // Click outside to close functionality
+  useEffect(() => {
+    const handlePointerDown = (event: PointerEvent) => {
+      if (isExecuting || event.defaultPrevented) return;
+      const el = previewModalRef.current;
+      if (!el) return;
+      const path = typeof event.composedPath === 'function' ? event.composedPath() : [];
+      const clickedInside = path.length ? path.includes(el) : el.contains(event.target as Node);
+      if (!clickedInside) closePreview();
+    };
+    // capture=true to survive stopPropagation in descendants
+    document.addEventListener('pointerdown', handlePointerDown, true);
+    return () => {
+      document.removeEventListener('pointerdown', handlePointerDown, true);
+    };
+  }, [closePreview, isExecuting]);

235-238: Add basic dialog a11y attributes.

Mark the container as a dialog for assistive tech; optional: manage focus when opened.

-    <div
-      ref={previewModalRef}
-      className="flex flex-col w-full max-w-[446px] bg-[#1E1D24] border border-white/5 rounded-[10px] p-6"
-    >
+    <div
+      ref={previewModalRef}
+      role="dialog"
+      aria-modal="true"
+      aria-label="Sell preview"
+      className="flex flex-col w-full max-w-[446px] bg-[#1E1D24] border border-white/5 rounded-[10px] p-6"
+    >

I can also wire focus management (set initial focus, trap within dialog, restore on close) if you’d like.

src/apps/pulse/components/Search/Search.tsx (2)

45-48: Type refetchWalletPortfolio to match RTK Query’s return (promise)
Typing it as () => Promise<unknown> is more accurate and helps downstream callers await it if needed.

 interface SearchProps {
@@
-  refetchWalletPortfolio?: () => void;
+  refetchWalletPortfolio?: () => Promise<unknown>;
 }

300-305: Guard undefined handler and include initial load in disabled/spinner states

Refresh.tsx defines onClick as optional (onClick?: () => void); use optional chaining for the handler and include the initial-loading flag in isLoading/disabled to avoid triggering refetch during initial load.

File: src/apps/pulse/components/Search/Search.tsx (lines 300-305)

-            <Refresh
-              isLoading={walletPortfolioFetching}
-              onClick={refetchWalletPortfolio}
-              disabled={!refetchWalletPortfolio || walletPortfolioFetching}
-            />
+            <Refresh
+              isLoading={walletPortfolioLoading || walletPortfolioFetching}
+              onClick={() => refetchWalletPortfolio?.()}
+              disabled={
+                !refetchWalletPortfolio ||
+                walletPortfolioLoading ||
+                walletPortfolioFetching
+              }
+            />
src/apps/pulse/components/App/AppWrapper.tsx (1)

57-62: Only pass refetch when a wallet address exists
Prevents a no-op refetch when the query is skipped and simplifies disabling logic in the child.

-      walletPortfolioFetching={walletPortfolioFetching}
+      walletPortfolioFetching={walletPortfolioFetching}
       walletPortfolioError={!!walletPortfolioError}
-      refetchWalletPortfolio={refetchWalletPortfolio}
+      refetchWalletPortfolio={accountAddress ? refetchWalletPortfolio : undefined}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between faa8dd2 and 41b45d9.

⛔ Files ignored due to path filters (1)
  • src/apps/pulse/components/Search/tests/__snapshots__/Search.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (3)
  • src/apps/pulse/components/App/AppWrapper.tsx (2 hunks)
  • src/apps/pulse/components/Search/Search.tsx (3 hunks)
  • src/apps/pulse/components/Sell/PreviewSell.tsx (4 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-03-28T09:22:22.712Z
Learnt from: RanaBug
PR: pillarwallet/x#275
File: src/apps/the-exchange/components/DropdownTokensList/DropdownTokenList.tsx:180-195
Timestamp: 2025-03-28T09:22:22.712Z
Learning: In the Exchange app, `swapTokenList` and `receiveTokenList` are derived from `searchTokenResult` when search is active, so including `searchToken` in the useEffect dependency array that uses these lists would be redundant as the lists will update when search results change.

Applied to files:

  • src/apps/pulse/components/Search/Search.tsx
🧬 Code graph analysis (1)
src/apps/pulse/components/Search/Search.tsx (1)
src/apps/pulse/components/Misc/Refresh.tsx (1)
  • Refresh (10-34)
🔇 Additional comments (4)
src/apps/pulse/components/Sell/PreviewSell.tsx (2)

1-1: Import update looks good.

useRef is required for the outside-click handling introduced below.


50-50: Ref setup is appropriate.

Using a typed useRef<HTMLDivElement>(null) for the modal root is correct for containment checks.

src/apps/pulse/components/Search/Search.tsx (1)

70-73: Destructuring new props — looks good
Props are optional and safely passed down.

src/apps/pulse/components/App/AppWrapper.tsx (1)

21-26: Good: expose isFetching for UI refresh controls
Surfacing isFetching as walletPortfolioFetching aligns with RTK Query semantics.

Copy link
Collaborator

@IAmKio IAmKio left a comment

Choose a reason for hiding this comment

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

LGTM

@RanaBug RanaBug merged commit 43eb1bc into staging Sep 11, 2025
3 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.

3 participants