Skip to content

refactor(dashnote): redesign workspace with toolbar, activity log, and sign-in hero#83

Open
thephez wants to merge 15 commits into
dashpay:mainfrom
thephez:dashnote/design-refactor
Open

refactor(dashnote): redesign workspace with toolbar, activity log, and sign-in hero#83
thephez wants to merge 15 commits into
dashpay:mainfrom
thephez:dashnote/design-refactor

Conversation

@thephez
Copy link
Copy Markdown
Collaborator

@thephez thephez commented May 14, 2026

Summary

  • Reworks the dashnote example app UI: adds a slim notes toolbar, editor metadata strip, and activity log panel; refreshes note list rows and selection styling.
  • Adds a signed-out experience — sign-in hero with editor preview, click-to-sign-in on the read-only editor, and a Login modal with a real header and Bridge card; collapses the prior "Remembered" state into the signed-out variant.
  • Rebuilds the How it works tab as a full tutorial-style page led by an in-page header.
  • Tightens identity card status labels, centers the splash on mobile, and moves the activity-panel detail emit out of src/dash/* helpers so dash helpers stay UI-agnostic.

Notable changes

  • New components: ActivityPanel, NotesToolbar, NoteJsonDrawer
  • Expanded HowItWorks, NoteEditor, NotesWorkspace, LoginModal, IdentityCard
  • New unit tests for ActivityPanel, App, HowItWorks, NoteEditor, NoteList; updated e2e specs (auth, notes, settings, smoke) and fixtures to match the new UI

Test plan

  • npm run build and npm run test inside example-apps/dashnote
  • Playwright e2e suite passes
  • Manual: signed-out hero → click editor opens login; Bridge card visible; How it works tab renders new layout; activity log records note ops; mobile splash centered

Summary by CodeRabbit

  • New Features

    • Activity panel with Ctrl/Cmd+L toggle and toolbar access
    • JSON document drawer for notes
    • Desktop notes toolbar and updated compose button label
    • Editor conflict warning and read‑only overlay that prompts sign‑in
  • Improvements

    • Richer activity logging (details, timestamps, clear)
    • Updated identity UI and login modal copy
    • Reworked How‑it‑Works walkthrough and note editor metadata/actions
    • Search shortcut (/) focuses note search
  • Tests

    • Expanded unit and e2e coverage for these flows

Review Change Stack

thephez and others added 12 commits May 14, 2026 11:00
… log

Implements P1–P3 from the design-review implementation guide: slim NotesToolbar replaces the heavy header card on Notes, editor toolbar surfaces rev/Updated/View JSON with JSON drawer and ⌘S Save, and a new ActivityPanel (⌘L) buffers structured log entries from the dash/* helpers so users can see SDK calls as they happen.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the padlock empty state on the Notes tab with a two-column
teaching hero. Left column has the original "stores notes against your
testnet identity" copy joined to the tutorial framing, a Sign in CTA,
and a View source link to the dashnote folder on GitHub. Right column
mirrors the real NoteEditor layout — Revision pill + "Updated", title +
body, and the \$createdAt / \$updatedAt mono strip — so the preview
matches what a logged-in user actually sees. The "no contract" branch
still uses the original EmptyState.

Also moves e.preventDefault() ahead of the bail-out gates in the
NoteEditor ⌘S handler so the browser Save Page dialog never opens
when the in-app save is unavailable (read-only, saving in flight, no
changes, or oversize).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops the double timestamp on each row to a single relative time, gives
the preview the full row width by anchoring the timestamp to the title
line, and italicizes the fallback when a note has no title so untitled
rows read as derived rather than authored. Adds a global "/" hotkey
that focuses the list search input (skipped when typing in any text
field) and a "/" hint chip inside the search input. Selected rows now
show a thin accent bar flush to the left edge of a tinted lg-rounded
card instead of a full accent outline; the bar is absolutely positioned
so the row text does not shift on select.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Widens Modal's title prop to accept a ReactNode so the login screen
can replace the small uppercase eyebrow with a 28-px key glyph,
"Sign in to Dashnote" title, and a "Connects to testnet" subtitle.
The privacy reassurance moves directly under the password input as a
shield-glyphed "Stored in memory only — never sent over the network"
line, replacing the trailing paragraph. The Bridge prompt becomes a
dedicated dashed-bordered card at the bottom of the form, gated on
the no-remembered-identity path so the "hides when remembered" test
still holds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
P5 replaced the old "Personal notes on Dash Platform" EmptyState
heading with the SignInHero's "Personal notes, stored on a public
blockchain." The tab-navigation smoke spec was still asserting the
old copy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the small "Sign in to edit" toolbar button with a transparent
overlay layered above the disabled inputs so any click on the editor
body opens the login modal. The disabled inputs stay disabled
underneath, so a missed click can't mutate state. Read-only viewing
still looks identical to before — same dimmed text, same cursor on the
fields themselves; only the surface gains a click target.

Adds the same sign-in affordance to the note list create paths so a
remembered-but-signed-out user can act: the desktop "New note" pill
becomes "Sign in to create" and the mobile compose "+" is now visible
in browsing mode; both call onOpenLogin instead of starting a draft.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the two-paragraph stub with a four-section tutorial map:

- Data flow: product-model intro plus a four-card pipeline (UI →
  Helper → Evo SDK → Platform). Cards are progressively accent-tinted
  to reinforce direction, and each links to a canonical target
  (GitHub source for UI/Helper, npm for Evo SDK, Platform Explorer
  testnet for Platform).
- Platform operations: five-row table where each row links to a
  one-file helper in src/dash/, with the SDK call name alongside.
- Inline code peek of the simplest mutation (createNote.ts), with
  a View full file link.
- Recommended source files: numbered-pill reading order, each row
  a clickable link to its GitHub source.
- Continue to docs CTA: solid surface, accent-tinted icon background,
  hover fill — reads as a primary action rather than a disabled tag.

Also drops the page-header eyebrow on App.tsx so the section labels
inside HowItWorks are the canonical typographic anchors.

Adds HowItWorks.test.tsx covering pipeline labels, ops-table links,
the code peek, the reading-order list, and the new link behavior on
the pipeline cards and reading-order rows.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops the App-shell page-header card on the how-it-works tab so the
HowItWorks component owns its own header instead of stacking under one.
The new in-page header lifts the previous data-flow narrative paragraph
into the lead, and the revision/timestamps follow-up moves into the
Platform-operations intro where it's contextually relevant.

The data-flow card is now a pure diagram: pipeline cards lose the
left-to-right accent gradient in favor of a flat bg, and each card
leads with an accent-colored glyph (grid for UI, code-brackets for
Helper, link for Evo SDK, shield for Platform) so the four steps read
as distinct affordances rather than tinted siblings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the connection-dot indicator and relabel the IdentityCard states by
identity status: Guest / Remembered / Signed in, with Full access and
Read-only access subtitles. Adds a document glyph to the sidebar logo
and resizes the identity avatar.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Strip the splash hero's border and rounded corners on mobile so it goes
edge-to-edge, and center its text and buttons vertically and
horizontally. Update e2e specs and the Playwright fixture to match the
new IdentityCard labels (Guest / Connected / Read-only access / Full
access) — the prior `.conn-dot.connected` boot gate is gone, so each
wait now anchors on the corresponding subtitle text instead. Also fix
the How it works heading match against the new walkthrough headline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Treat a remembered identity as "signed out with hint" rather than its
own first-class state — the IdentityCard now shows "Signed out" /
"Read-only access" with the cached DPNS row, and clicking the card
opens the login modal directly (no menu). The authenticated branch
keeps its menu (Settings / Switch identity / Log out). Updates unit
tests to assert the eyebrow + subtitle pair per state, and reworks the
Playwright fixtures so loginViaModal clicks the IdentityCard itself in
browsing mode.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… helpers

Revert the structured log payloads added in 8468756 from createNote /
updateNote / deleteNote so each helper is "just the SDK call" again.
NotesWorkspace now wraps the session logger via withDetail() to attach
the activity-panel detail string and emits the success row itself.
updateNote returns the new revision so the caller can render `rev N`
without recomputing +1n.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

Warning

Rate limit exceeded

@thephez has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 46 minutes and 19 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 94299980-45a5-4b17-a14a-64f2d27000b5

📥 Commits

Reviewing files that changed from the base of the PR and between ea57f71 and b8b2cc6.

📒 Files selected for processing (1)
  • example-apps/dashnote/test/e2e/notes.spec.ts
📝 Walkthrough

Walkthrough

Adds structured activity logging and UI panel (hotkey + toolbar), JSON preview and conflict warnings in the editor, search shortcut and row redesign in the list, Identity/Login/HowItWorks UI updates, removal of conn-dot styles, and corresponding unit and e2e test updates.

Changes

Activity Logging & App Integration

Layer / File(s) Summary
Logger contract and utilities
example-apps/dashnote/src/lib/logger.ts
Logger accepts LogLevel or LogOptions (with optional detail); normalizeLogOptions and ACTIVITY_LOG_LIMIT added; LogEntry extended with detail.
Session context activity logging
example-apps/dashnote/src/session/SessionContext.tsx
SessionProvider exposes activityLog and clearActivityLog; log function normalizes options, writes console/toasts, and prepends structured LogEntry objects capped by ACTIVITY_LOG_LIMIT.
ActivityPanel component and tests
example-apps/dashnote/src/components/ActivityPanel.tsx, example-apps/dashnote/test/ActivityPanel.test.tsx
ActivityPanel renders right-side modal with entries, status dots, Clear/close controls, Escape/backdrop close behavior; tests cover empty state, entry rendering, clear, and close interactions.
App shell activity panel wiring
example-apps/dashnote/src/App.tsx, example-apps/dashnote/src/components/NotesToolbar.tsx, example-apps/dashnote/test/App.test.tsx
App adds activityOpen state and Cmd/Ctrl+L listener; NotesToolbar renders title/testnet badge and optional Activity button; ActivityPanel mounted with onClose; tests verify hotkey and toolbar open/close.

Note Editor & List Display Enhancements

Layer / File(s) Summary
NoteEditor contract and JSON drawer
example-apps/dashnote/src/components/NoteEditor.tsx, example-apps/dashnote/src/components/NoteJsonDrawer.tsx
NoteEditorProps adds optional conflictWarning; jsonOpen state introduced; NoteJsonDrawer shows document JSON and supports Escape/backdrop close.
NoteEditor UI restructuring
example-apps/dashnote/src/components/NoteEditor.tsx
Header shows revision/updated-time chips; desktop-only View JSON and delete/save layout changes; conflict warning banner and read-only overlay that opens login; desktop footer bar shows metadata/message size.
NoteList keyboard & layout redesign
example-apps/dashnote/src/components/NoteList.tsx
NoteList adds searchRef and global '/' key to focus search, newButtonLabel prop, row redesign with active accent, italic empty-title fallback, and relative timestamps.
NotesWorkspace operation logging integration
example-apps/dashnote/src/components/NotesWorkspace.tsx
Adds withDetail logger wrapper and passes wrapped logger into create/update/delete flows; emits success logs with shortened ids/revisions; handleNew opens login for read-only users; SignInHero replaces previous empty-state.
NoteEditor and NoteList test coverage
example-apps/dashnote/test/NoteEditor.test.tsx, example-apps/dashnote/test/NoteList.test.tsx, example-apps/dashnote/test/NotesWorkspace.test.tsx
Tests added/updated for NoteEditor read-only overlay and click-to-sign-in, NoteList row layout and '/' focus behavior, and NotesWorkspace hero messaging and updateNote bigint return expectations.

Identity, Auth, HowItWorks UI Redesigns & E2E Test Updates

Layer / File(s) Summary
Modal contract and UI updates
example-apps/dashnote/src/components/Modal.tsx
ModalProps.title widened from string to ReactNode; header rendering branches on title type while preserving aria-labelledby.
LoginModal UI restructure
example-apps/dashnote/src/components/LoginModal.tsx
Title replaced by composed header (icon + "Sign in to Dashnote" + subtitle); new "Stored in memory only" notice added; dashed callout with Dash Bridge link shown when remembered panel absent.
IdentityCard state handling simplification
example-apps/dashnote/src/components/IdentityCard.tsx
Remove unused hasIdentity; unify readonly/browsing early-return with optional identity decoration; update label pairs ("Guest"/"Signed out", "Read-only access"/"Connected"/"Full access"); ensure "Switch identity" and "Log out" availability.
HowItWorks walkthrough reimplementation
example-apps/dashnote/src/components/HowItWorks.tsx, example-apps/dashnote/test/HowItWorks.test.tsx
HowItWorks refactored into multi-section walkthrough: header, Data flow pipeline cards with glyph icons, Platform operations table with code peek, Recommended source files list, and CTA link; tests added for links and content.
AppShell and styling updates
example-apps/dashnote/src/components/AppShell.tsx, example-apps/dashnote/src/styles/globals.css, example-apps/dashnote/src/dash/updateNote.ts
LogoAvatar now renders centered inline SVG; conn-dot animation and variants removed from globals.css; updateNote now returns Promise and returns revision.
IdentityCard and auth test updates
example-apps/dashnote/test/IdentityCard.test.tsx
IdentityCard unit tests adjusted: browsing-mode interaction simplified to direct click calling onLoginClick; new assertions verify label pairs for readonly/browsing/authenticated states; logout menu test preserved.
E2E fixtures selectors and login flow updates
example-apps/dashnote/test/e2e/fixtures.ts
Fixtures now wait for "Connected" text in main navigation and detect browsing via "Read-only access"; loginViaModal clicks Read-only access entry directly; post-login expected "Full access".
Auth e2e test expectations
example-apps/dashnote/test/e2e/auth.spec.ts
Auth e2e assertions updated to check sidebar text sequences (e.g., "Guest"/"Connected", "Read-only access") and updated walkthrough heading text.
Notes, settings, and smoke e2e test updates
example-apps/dashnote/test/e2e/notes.spec.ts, example-apps/dashnote/test/e2e/settings.spec.ts, example-apps/dashnote/test/e2e/smoke.spec.ts
E2E tests updated to use "Connected"/"Read-only access" text selectors for readiness checks and to align heading expectations with redesigned content.
Minor test formatting
example-apps/dashnote/test/DeleteNoteModal.test.tsx
Reformat DeleteNoteModal asserts to multi-line expect blocks; no behavior change.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰 Activity logs hum in rows,

JSON peeks where editor glows,
Identity cards speak clear and bright,
Walkthrough steps guide through the night,
Tests now follow changed sidebar light.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: a redesign introducing a toolbar, activity log panel, and sign-in hero component—all key architectural changes evident across the modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Copy Markdown

@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

🧹 Nitpick comments (4)
example-apps/dashnote/test/DeleteNoteModal.test.tsx (1)

92-102: ⚡ Quick win

Prefer .toBeDisabled() matcher for clearer assertions.

Testing Library provides a .toBeDisabled() matcher that is more semantic and idiomatic than checking .hasAttribute("disabled"). It also produces clearer error messages when assertions fail.

✨ Suggested refactor
   expect(
-    screen
-      .getByRole("button", { name: /deleting…/i })
-      .hasAttribute("disabled"),
-  ).toBe(true);
+    screen.getByRole("button", { name: /deleting…/i }),
+  ).toBeDisabled();
   expect(
-    screen
-      .getByRole("button", { name: /^cancel$/i })
-      .hasAttribute("disabled"),
-  ).toBe(true);
+    screen.getByRole("button", { name: /^cancel$/i }),
+  ).toBeDisabled();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@example-apps/dashnote/test/DeleteNoteModal.test.tsx` around lines 92 - 102,
Replace the manual attribute checks in the DeleteNoteModal test with the
semantic matcher: instead of asserting screen.getByRole("button", { name:
/deleting…/i }).hasAttribute("disabled") and the same for
screen.getByRole("button", { name: /^cancel$/i }), use the Testing Library
matcher .toBeDisabled() on those getByRole results (i.e.,
expect(screen.getByRole("button", { name: /deleting…/i })).toBeDisabled() and
expect(screen.getByRole("button", { name: /^cancel$/i })).toBeDisabled()) so the
assertions are clearer and produce better failure messages.
example-apps/dashnote/src/components/ActivityPanel.tsx (1)

26-29: ⚡ Quick win

Mark the panel as a modal dialog for assistive tech.

On Line 27, add aria-modal="true" to the role="dialog" container so screen readers treat background content as non-interactive while the panel is open.

Proposed patch
     <div
       role="dialog"
+      aria-modal="true"
       aria-label="Activity log"
       className="fixed inset-0 z-40 flex justify-end bg-black/40"
       onClick={onClose}
     >
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@example-apps/dashnote/src/components/ActivityPanel.tsx` around lines 26 - 29,
Add the missing aria-modal attribute to the dialog container in the
ActivityPanel component so assistive tech treats background content as
non-interactive; update the element that currently has role="dialog" (the
top-level div in ActivityPanel) to include aria-modal="true" alongside
role="dialog" and aria-label="Activity log".
example-apps/dashnote/test/App.test.tsx (1)

169-184: ⚡ Quick win

Add a Ctrl+L assertion for parity with runtime behavior.

The test covers metaKey only; adding ctrlKey verifies the non-mac path already implemented in App.

Proposed patch
   it("opens the activity panel via ⌘L hotkey and toolbar button", () => {
@@
     // Toggling again closes it.
     fireEvent.keyDown(window, { key: "l", metaKey: true });
     expect(screen.getByText("activity:false")).toBeTruthy();
+
+    fireEvent.keyDown(window, { key: "l", ctrlKey: true });
+    expect(screen.getByText("activity:true")).toBeTruthy();
 
     fireEvent.click(screen.getByRole("button", { name: /open activity/i }));
     expect(screen.getByText("activity:true")).toBeTruthy();
   });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@example-apps/dashnote/test/App.test.tsx` around lines 169 - 184, The test
currently only simulates the macOS hotkey using fireEvent.keyDown(window, { key:
"l", metaKey: true }) in the "opens the activity panel via ⌘L hotkey and toolbar
button" test; add an equivalent assertion that sends the non-mac hotkey
(fireEvent.keyDown with ctrlKey: true) to verify App toggles activity the same
way. Locate the test in example-apps/dashnote/test/App.test.tsx and insert a
fireEvent.keyDown(window, { key: "l", ctrlKey: true }) call followed by the same
expect(...) check used after the metaKey events to assert activity toggles.
example-apps/dashnote/src/dash/updateNote.ts (1)

1-8: ⚡ Quick win

Update JSDoc to document the return value.

The function signature now returns Promise<bigint> (the saved note's revision), but the JSDoc block does not document this return value.

📝 Suggested JSDoc enhancement
 /**
  * Update an existing note. Fetches the current document to bump its revision,
  * then submits a replace state transition.
  *
  * SDK methods:
  *   sdk.documents.get(contractId, documentTypeName, documentId)
  *   sdk.documents.replace({ document, identityKey, signer })
+ *
+ * `@returns` Promise resolving to the new revision number after successful save
  */
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@example-apps/dashnote/src/dash/updateNote.ts` around lines 1 - 8, The JSDoc
for updateNote is missing documentation of its return value; update the comment
for the updateNote function to include an `@returns` (or `@return`) entry describing
that the function returns Promise<bigint> representing the saved note's revision
(the bumped document revision after replace), and briefly note any failure
behavior (e.g., it throws on error). Keep the description concise and match the
return type exactly: Promise<bigint>.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@example-apps/dashnote/src/components/NotesToolbar.tsx`:
- Around line 49-50: The displayed shortcut hint in NotesToolbar (the span
rendering "⌘L") is misleading because the app supports both Command and Control;
update the label in the span inside NotesToolbar (the rounded border span
element) to indicate both modifiers (e.g., "⌘/Ctrl L" or "Ctrl/Cmd L") and also
update any aria-label/title text for the same element so keyboard users on
Windows/Linux see the correct shortcut; ensure the visible text and any
accessible label match the actual handler that listens for Cmd and Ctrl.

In `@example-apps/dashnote/test/e2e/notes.spec.ts`:
- Around line 244-246: The selector for "Read-only access" is not scoped to the
sidebar; update the assertion to scope the lookup to the sidebar locator used
elsewhere by calling the sidebar locator (aside[aria-label="Main navigation"])
and then using getByText("Read-only access", { exact: true }) on that locator so
the check (toBeVisible with the existing { timeout: 60_000 }) targets the main
navigation only.
- Around line 219-221: The assertion uses page2.getByText("Read-only access")
without scoping to the main navigation sidebar; change it to scope the lookup to
the sidebar locator (e.g., replace page2.getByText("Read-only access", { exact:
true }) with something like
page2.locator('<sidebar-selector>').getByText("Read-only access", { exact: true
}) or use the same sidebar helper used elsewhere so the check is limited to the
sidebar (update the expression that calls page2.getByText on "Read-only access"
to be invoked on the sidebar locator instead).

---

Nitpick comments:
In `@example-apps/dashnote/src/components/ActivityPanel.tsx`:
- Around line 26-29: Add the missing aria-modal attribute to the dialog
container in the ActivityPanel component so assistive tech treats background
content as non-interactive; update the element that currently has role="dialog"
(the top-level div in ActivityPanel) to include aria-modal="true" alongside
role="dialog" and aria-label="Activity log".

In `@example-apps/dashnote/src/dash/updateNote.ts`:
- Around line 1-8: The JSDoc for updateNote is missing documentation of its
return value; update the comment for the updateNote function to include an
`@returns` (or `@return`) entry describing that the function returns Promise<bigint>
representing the saved note's revision (the bumped document revision after
replace), and briefly note any failure behavior (e.g., it throws on error). Keep
the description concise and match the return type exactly: Promise<bigint>.

In `@example-apps/dashnote/test/App.test.tsx`:
- Around line 169-184: The test currently only simulates the macOS hotkey using
fireEvent.keyDown(window, { key: "l", metaKey: true }) in the "opens the
activity panel via ⌘L hotkey and toolbar button" test; add an equivalent
assertion that sends the non-mac hotkey (fireEvent.keyDown with ctrlKey: true)
to verify App toggles activity the same way. Locate the test in
example-apps/dashnote/test/App.test.tsx and insert a fireEvent.keyDown(window, {
key: "l", ctrlKey: true }) call followed by the same expect(...) check used
after the metaKey events to assert activity toggles.

In `@example-apps/dashnote/test/DeleteNoteModal.test.tsx`:
- Around line 92-102: Replace the manual attribute checks in the DeleteNoteModal
test with the semantic matcher: instead of asserting screen.getByRole("button",
{ name: /deleting…/i }).hasAttribute("disabled") and the same for
screen.getByRole("button", { name: /^cancel$/i }), use the Testing Library
matcher .toBeDisabled() on those getByRole results (i.e.,
expect(screen.getByRole("button", { name: /deleting…/i })).toBeDisabled() and
expect(screen.getByRole("button", { name: /^cancel$/i })).toBeDisabled()) so the
assertions are clearer and produce better failure messages.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5e3a2e75-874b-4e90-8d6b-e353cc5f885f

📥 Commits

Reviewing files that changed from the base of the PR and between 0dfbe37 and 1fbf9f7.

📒 Files selected for processing (29)
  • example-apps/dashnote/src/App.tsx
  • example-apps/dashnote/src/components/ActivityPanel.tsx
  • example-apps/dashnote/src/components/AppShell.tsx
  • example-apps/dashnote/src/components/HowItWorks.tsx
  • example-apps/dashnote/src/components/IdentityCard.tsx
  • example-apps/dashnote/src/components/LoginModal.tsx
  • example-apps/dashnote/src/components/Modal.tsx
  • example-apps/dashnote/src/components/NoteEditor.tsx
  • example-apps/dashnote/src/components/NoteJsonDrawer.tsx
  • example-apps/dashnote/src/components/NoteList.tsx
  • example-apps/dashnote/src/components/NotesToolbar.tsx
  • example-apps/dashnote/src/components/NotesWorkspace.tsx
  • example-apps/dashnote/src/dash/updateNote.ts
  • example-apps/dashnote/src/lib/logger.ts
  • example-apps/dashnote/src/session/SessionContext.tsx
  • example-apps/dashnote/src/styles/globals.css
  • example-apps/dashnote/test/ActivityPanel.test.tsx
  • example-apps/dashnote/test/App.test.tsx
  • example-apps/dashnote/test/DeleteNoteModal.test.tsx
  • example-apps/dashnote/test/HowItWorks.test.tsx
  • example-apps/dashnote/test/IdentityCard.test.tsx
  • example-apps/dashnote/test/NoteEditor.test.tsx
  • example-apps/dashnote/test/NoteList.test.tsx
  • example-apps/dashnote/test/NotesWorkspace.test.tsx
  • example-apps/dashnote/test/e2e/auth.spec.ts
  • example-apps/dashnote/test/e2e/fixtures.ts
  • example-apps/dashnote/test/e2e/notes.spec.ts
  • example-apps/dashnote/test/e2e/settings.spec.ts
  • example-apps/dashnote/test/e2e/smoke.spec.ts
💤 Files with no reviewable changes (1)
  • example-apps/dashnote/src/styles/globals.css

Comment thread example-apps/dashnote/src/components/NotesToolbar.tsx Outdated
Comment thread example-apps/dashnote/test/e2e/notes.spec.ts
Comment thread example-apps/dashnote/test/e2e/notes.spec.ts
thephez added 2 commits May 15, 2026 15:04
— cross-platform shortcut hint, modal a11y, scoped e2e selectors
Copy link
Copy Markdown

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@example-apps/dashnote/test/e2e/notes.spec.ts`:
- Around line 275-283: The test uses page.keyboard.press("Meta+l") which only
fires on macOS; change the keyboard invocation to use Playwright's
cross-platform modifier "ControlOrMeta+l" so the shortcut handler in App.tsx
((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "l") is triggered on all
platforms; update the test case "activity panel opens via ⌘L, lists entries,
clears, and closes via Escape" to press "ControlOrMeta+l" before asserting the
dialog (keep the same dialog lookup via page.getByRole).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5537ecce-5631-4426-bd9d-7868f34c5312

📥 Commits

Reviewing files that changed from the base of the PR and between eefa57a and ea57f71.

📒 Files selected for processing (6)
  • example-apps/dashnote/test/NoteJsonDrawer.test.tsx
  • example-apps/dashnote/test/NotesToolbar.test.tsx
  • example-apps/dashnote/test/SessionContext.test.tsx
  • example-apps/dashnote/test/e2e/notes.spec.ts
  • example-apps/dashnote/test/e2e/smoke.spec.ts
  • example-apps/dashnote/test/logger.test.ts

Comment thread example-apps/dashnote/test/e2e/notes.spec.ts
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.

1 participant