feat: add portfolio activity timeline - #737
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository: euler-xyz/coderabbit/.coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
🚅 Deployed to the euler-lite-pr-737 environment in euler-lite
|
61a1bd1 to
48b823c
Compare
48b823c to
caa6faf
Compare
LeonardEulerXYZ
left a comment
There was a problem hiding this comment.
Leonard review — changes requested
Reviewed the stacked child delta against feature/lite-219-add-activity-events-section-to-vault-page-filterable-by at 050f2585d4a50a1c834a93b292a5580b15a5c094. The account Activity route, runtime-support isolation, event enrichment, and category request wiring are coherent. Two child-specific UI regressions remain, detailed inline: the replacement category selector is not keyboard/screen-reader operable, and direct mobile navigation leaves the active Activity tab clipped.
Validation
- Focused Activity/runtime/display tests: 33/33 passed
- ESLint over changed Activity/portfolio files: passed
git diff --check: passed- Headed Railway smoke: populated desktop timeline; Borrowing selection updated both the rendered feed and
category=borrowingrequest; 390×844 mobile route and filter exercised - Full typecheck/test CI remains blocked by the Activity SDK surface absent from the stack's currently locked
@eulerxyz/euler-v2-sdk@1.1.4; the child does not change that dependency, so I treated it as an inherited #736 integration gate rather than a #737-specific finding - Security/malicious-code sweep: no concerns in the child delta
- Scalability/maintainability pass: both fixes belong in the shared
UiSelect/UiTabsabstractions, with focused accessibility and mobile direct-route tests, so vault Activity and future tab/filter consumers inherit the correction - Bot feedback: CodeRabbit skipped this non-default-base PR; there were no bot findings to adopt or refute
Visual evidence
Desktop, 1440×1000 — Borrowing selected and filtered events rendered:
Mobile, 390×844 — filtered feed works, but the selected Activity tab is clipped at the right edge:
Smoke coverage: browser visual smoke + mobile smoke; no wallet/signing flow was exercised.
| {{ option.label }} | ||
| </button> | ||
| </div> | ||
| <UiSelect |
There was a problem hiding this comment.
Blocking — restore keyboard and screen-reader operability. This replaces the native category buttons (button + aria-pressed) with UiSelect, but the shared trigger renders as a clickable div with no role, focusability, keyboard handler, or expanded state. In the headed preview DOM it was role=null and tabIndex=-1, so a keyboard user cannot open this filter. The modal's checkbox inputs are also not associated with the adjacent option text. Because this component feeds both account and vault Activity, please fix the shared UiSelect trigger/options semantics (or retain native buttons) and add a focused keyboard/accessibility test.
|
|
||
| if (showActivityTab.value) { | ||
| items.push({ | ||
| label: 'Activity', |
There was a problem hiding this comment.
Mobile regression — ensure the route-selected tab is scrolled fully into view. At 390px, direct navigation to /portfolio/activity leaves this active label visibly clipped at the right edge. UiTabs scrolls only from onSelect; initial routes, browser history, and programmatic currentIdx changes only update the active block. Please fix this in shared UiTabs on mount/current-index/list changes and cover a narrow direct-route case, rather than adding a portfolio-only offset.
Leonard review — current head
|
LeonardEulerXYZ
left a comment
There was a problem hiding this comment.
Reviewed current head 8158e496827da7882748374e5397400b435d2292.
The new event-presentation work is coherent in focused tests and desktop/mobile preview smoke, but the two current-head inline blockers remain:
- the shared activity filter trigger is a mouse-only
<div>with no keyboard semantics; - the fixed six-column portfolio tab row clips
Activityand hidesMigrateat 390 px.
The current-head inline threads contain the concrete findings. I also posted a walkthrough with validation and verified raster screenshot evidence. No additional blocking issue was found in the 8158e496 presentation delta itself.
Validation: 4 focused activity test files / 33 tests passed; scoped ESLint passed; headed Chromium desktop + 390 px mobile smoke exercised the Borrowing filter and populated feed. Local Nuxt typecheck was inconclusive because the cached local SDK predates this stacked branch's activity exports; GitHub's current-head typecheck/test checks are green.
Smoke coverage: desktop browser visual + filter interaction + mobile visual. Wallet/signing not applicable.
8158e49 to
257dac9
Compare
257dac9 to
ff196eb
Compare
ff196eb to
53cc658
Compare
53cc658 to
5c5486c
Compare
- clarify transfers and suppress exact paired share movements - add token imagery, compact responsive details, and copyable addresses - hide unavailable pricing noise while preserving truthful fallbacks
Describe incomplete categories without implying that no events exist.
Limit position history to attributable operations, show asset-unit amounts, and conservatively collapse exact paired events.
Align portfolio activity copy with the position terminology used throughout Lite.
5c5486c to
930442d
Compare
LeonardEulerXYZ
left a comment
There was a problem hiding this comment.
Reviewed current head 930442db1f41620d7db09dfefb51541892d65913 as the stacked child delta against feature/lite-219-add-activity-events-section-to-vault-page-filterable-by / PR #736, plus the incremental delta from the previously reviewed 8158e496 head.
The latest position-history presentation is coherent in the deployed desktop/mobile fixture, and the Borrowing filter issues the expected category-scoped account-events request. Two current-head blockers remain in the existing inline threads:
- the Activity category selector is not keyboard or screen-reader operable because the shared
UiSelecttrigger is an unfocusable click-only<div>and its option text does not name the checkbox; - direct
/portfolio/activitynavigation at 390 px leaves the active Activity tab clipped because sharedUiTabsdoes not reveal route/model-driven selections.
Validation:
git diff --checkpassed on the child delta;- GitHub lint and Railway dev build pass;
- GitHub test: 1,293/1,294 pass; the sole failure is the declared unpublished-SDK query-policy gate;
- GitHub typecheck fails only on Activity exports/service/query names absent from the pinned public SDK;
- headed Chromium preview smoke at 1440×1000 and 390×844: populated activity rows, Borrowing filter interaction/request verified, no page exceptions or material console errors;
- scalability/maintainability pass: shared feed/display/runtime-support abstractions are reused appropriately; the remaining fixes should land in shared
UiSelectandUiTabsrather than portfolio-only workarounds; - CodeRabbit skipped the stacked-base review and supplied no actionable finding.
The updated Leonard walkthrough contains current-head screenshot evidence and the exact validation caveats.
6b86ec8
into
feature/lite-219-add-activity-events-section-to-vault-page-filterable-by




Summary
Linear: https://linear.app/euler-labs/issue/LITE-220/add-activity-events-tab-to-portfolio-per-wallet-event
Portfolio UX
/portfolio/activity.useEffectiveAddress(), so spy mode and a connected wallet follow the same path.Availability and fallback behavior
This initial implementation is V3-only. It does not query the subgraph directly.
The tab combines three signals:
unsupported.An authoritative unsupported result hides the tab and redirects a direct Activity route back to Portfolio. Runtime support state is scoped by effective owner and chain so a negative result cannot leak across wallets or networks.
Transient capability checks and request failures remain visible as retryable error states. They do not become empty timelines and do not permanently hide the tab. A successful empty response is the only path to the no-indexed-activity message.
The SDK adapter boundary remains the extension point for a future subgraph implementation if product decides that Activity must work on chains without V3.
Enrichment rules
Cross-repo dependencies and merge order
This PR is stacked on the LITE-219 branch so its diff contains only Portfolio-specific work. Rebase onto
developmentafter #736 merges.Both Lite Activity PRs remain draft until the published SDK is consumed and V3 #274 is deployed on the supported chains.
Known overlap
#718 currently overlaps
pages/portfolio.vueand is reported as conflicting. The changes are semantically compatible, but whichever PR lands second needs a manual rebase that preserves both the migration load-error handling and the Activity tab availability watcher.Current draft CI gate
GitHub lint passes. Typecheck fails only on Activity exports,
activityService, and Activity query names absent from the currently published SDK. The remote test job passes 1,281 of 1,282 tests; the sole failure is the SDK query-policy check for those two unpublished Activity query names. Local validation against the built SDK #66 passes typecheck and all 1,282 tests. This gate clears when #66 is published and the Lite dependency is bumped.Test plan
git diff --checkpassed.