Repository navigation
Batch 2026-09-30: account menu, settings dialogs, share select, document images, onboarding recovery, table quick filter, view tabs, and fixes (13 PRs) - #1915
Merged
Conversation
Editing inside the settings section swapped the list for a long form and put the Save/Cancel buttons below it, which felt cramped. The lists stay on the AI settings page; creating or editing an agent, skill or MCP server now opens a shared ConfigEditorDialog with the form and Cancel/Save actions. Escape, the close button and an outside click cancel; Save is disabled until the required fields are filled in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P648McUYrscNsheXY5Ya81
The App panel at the bottom of the sidebar listed eight entries. It is now a single row: the current user opens a dropdown with Profile, Notifications (with the unread count), Integrations, Sync, Feedback, About and, when available, Install App. Settings sits beside the row as a gear icon button. Signed out, the row reads "Login / New User" and its first item leads to the sign-in page. The row reuses DropdownMenu, so arrow keys, Enter and Escape work and focus returns to the trigger. An unread-notifications dot shows on the row while the menu is closed. To serve both the floating Feedback button and the menu item, the feedback dialog moved into useFeedbackDialog (FeedbackMenuItem is now FeedbackButton), and SyncMenuItem became a useSyncStatus hook. E2E specs that clicked the old panel entries go through the new openAccountMenu / clickAccountMenuItem helpers, and signIn waits for the account row instead of a link to /app/agent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P648McUYrscNsheXY5Ya81
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P648McUYrscNsheXY5Ya81
The email invite field focused its input on every click inside it, including clicks on the "Can write / Can read" select. Moving focus to the input blurred the native select right after it opened its option list, so the list closed again. The field now only focuses the input when the click lands outside its controls. The input also asks password managers not to fill it (data-bwignore, data-1p-ignore, data-lpignore, data-form-type) and uses autocomplete="off", since it holds other people's addresses rather than the user's own. It stays type="email". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P648McUYrscNsheXY5Ya81
An image uploaded into a document keeps only its `downloadURL` (`<server>/download/files/<hash>`) in the node's `src`. In a browser-only drive (the default for the hosted distribution and for drives created there), neither the File's commit nor its bytes ever reach a server, so that URL answers 404 and the editor's node view showed "Failed to load image". File previews did not have this problem because they resolve the bytes locally through `useFileObjectUrl`; the editor image never did. - `@tomic/lib`: `blobSubjectFromDownloadUrl` maps a content-addressed download URL back to its `atomic:blob:<hash>`. - `@tomic/react`: `useBlobObjectUrl`, the blob-reference half of `useFileObjectUrl`, for callers without a File resource. - `ImagePicker`: render the local copy when there is one, fall back to the URL otherwise, wait for the lookup instead of racing it, and key the error state by src so a new src gets a fresh attempt. The document still stores the portable URL. - Wrap two label texts in spans: the i18n transform turned them into keyless arrays, which logged a React key warning whenever the picker opened. Adds `document-image.spec.ts`, which fails with "Failed to load image." before this change and passes after, including across a reload. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P648McUYrscNsheXY5Ya81
The status icon's SVG title ("Connected", "Offline") became part of the
menu item's accessible name. Hide the icon from assistive tech; the status
is still in the item's tooltip.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P648McUYrscNsheXY5Ya81
# Conflicts: # browser/CHANGELOG.md # browser/data-browser/src/components/SideBar/FeedbackMenuItem.tsx # browser/data-browser/src/locales/de.po # browser/data-browser/src/locales/en.po # browser/data-browser/src/locales/es.po # browser/data-browser/src/locales/fr.po
# Conflicts: # browser/CHANGELOG.md
# Conflicts: # browser/CHANGELOG.md # browser/data-browser/src/locales/de.po # browser/data-browser/src/locales/en.po # browser/data-browser/src/locales/es.po # browser/data-browser/src/locales/fr.po
…al bootstrap # Conflicts: # browser/data-browser/src/locales/de.po # browser/data-browser/src/locales/en.po # browser/data-browser/src/locales/es.po # browser/data-browser/src/locales/fr.po
…date React after teardown
# Conflicts: # browser/data-browser/src/routes/ShowRoute.tsx
…s where the sidebar /app/agent link was
joepio
added a commit
that referenced
this pull request
Sep 30, 2026
…date React after teardown Before: the data-browser unit stage failed with "ReferenceError: window is not defined" counted as an unhandled error, although all tests passed. It stopped develop's run for c2e2682 before e2e started. After: the unit stage passes. The test stores connected to server.example, which runs no atomic-server. The socket failed a moment later, the store reported "Server disconnected", and the components' state update landed after jsdom was torn down. The stores are now created with `connect: false`, as in bootstrap.test.ts. Same change as the one in #1915, so that PR merges without a conflict.
This was referenced Sep 30, 2026
Closed
joepio
added a commit
that referenced
this pull request
Sep 30, 2026
# Conflicts: # browser/data-browser/src/locales/de.po # browser/data-browser/src/locales/en.po # browser/data-browser/src/locales/es.po # browser/data-browser/src/locales/fr.po
This was referenced Sep 30, 2026
joepio
added a commit
that referenced
this pull request
Oct 1, 2026
The parent fan-out, Store.subscribeLive and the Collection change for unsynced drives move to their own PR (claude/shared-resource-live), which needs its own review. This PR keeps the plan and the client polish: grouped rows, reading on return, the OS-notification offer and the loading state. The top-bar bell goes: #1915 already shows the unread count next to Notifications in the account menu, so the bell showed the same number twice. The plan says so too.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Joep
Before: four finished PRs from the UI fixes thread sat open. Since #1661, pushes to a PR no longer run the full pipeline, so none of them had an e2e verdict.
After: they sit together on one branch off develop (dd6a959), and one Mancave run decides them. Merge this with a merge commit, not squash: then each included PR head is in develop and GitHub marks it as merged.
Included, at these heads:
Left out: Ask the drive for its apps again when a view menu opens (#1846) #1904 (conflicts in
useDriveApps.live.test.tsx), Calendar: event times, on the viewer's local day (#1802) #1898/Calendar: a Repeat field instead of recurrence JSON (#1801) #1896 (large calendar stacks), Replay a sync delta on the local history before asking the server (#1905) #1920 (sync, needs review), Forms (#875), continuing Polle's #1281 #1923 (Forms), Move the browser workspace to pnpm 11 (split out of #1281) #1931 (pnpm 11), and Hosted builds open on sign-in, not the welcome screen #1911–Stop the sync page repeating account requests every five seconds #1914, Report writes that keep failing to Sentry #1918, Fix Cloud Server setup leaving the node without the drive #1919 (in another batch).Decisions made while resolving:
.pocatalogs conflicted; they are combined and settled again (2295 entries,de.pokeeps its 12 translations). develop's e2e: size the four shards by measured cost #1893 (e2e shard sizing) is merged in too.FeedbackMenuItem.tsxand moves feedback into the newAccountMenu(useFeedbackDialog) andFeedbackButton. Since Replace the sidebar App panel with an account menu #1890 branched, Make Try Atomic one calm start, and a demo tour that keeps up with you #1876 made the More menu's "Give feedback" open the sidebar's feedback dialog throughOPEN_FEEDBACK_EVENT, withFeedbackMenuItemas the listener.AccountMenunow listens for that event instead, so "Give feedback" still opens the dialog.CrashPagealready usesFeedbackButtonin Replace the sidebar App panel with an account menu #1890.browser/CHANGELOG.mdentries from all four PRs are kept (union)..pofiles were combined, then settled withpnpm clean-translations. That gives 2295 entries, up from develop's 2288 (the new strings of these PRs), and no translation is lost:de.postill has its 12 translated entries. Most of the line churn is#:reference comments.Fixes found by the batch runs:
SearchBoxWindow.test.tsx(from Find already-fetched external classes in New Table's class picker #1842, already on develop) failed run 3 with two unhandledReferenceError: window is not defined. Its stores connected a WebSocket toserver.example. The failed socket reported "Server disconnected", and the resulting React state update landed after jsdom was torn down. The test's stores now useconnect: false, asbootstrap.test.tsdoes.ai-chat-discovery"independent signed-in devices…", thencanvas-undo"undo works right after a cold reload…"), both on 60 s timeouts while Mancave was running 4 shards at once. On a Mac, against this branch, the first passed 8/8 and the second 24/24 with 6 parallel workers. Develop's own run on Make Try Atomic one calm start, and a demo tour that keeps up with you #1876 failed the same way onai-mobile.ShowRoutenow skips consuming thedrivesearch param whileisDriveSignInErrorsays the subject needs a sign-in, and Fix onboarding recovery, metadata request bursts and local bootstrap #1917 makes the same effect wait forselectReadableDrive. Both are kept: the effect returns early onsignInRedirect, otherwise waits for a readable drive, then consumes. Its newopen-locked-drive.spec.tsclicked the old sidebara[href$="/app/agent"], which Replace the sidebar App panel with an account menu #1890 replaces, so it now goes throughclickAccountMenuItem(page, 'Profile')like Replace the sidebar App panel with an account menu #1890's other sign-out specs. Locally: route/readableDrive/isDriveSignInError vitest 20/20, andopen-locked-drive+signout-signin-data6/6.@tomic/lib'supload-roundtrip.integration.test.ts: the blob was not downloadable within the test's 15 s polling window. Locally it arrives in about 1.2 s both with this branch'swebsockets.tsand develop's, so Fix onboarding recovery, metadata request bursts and local bootstrap #1917's sync gating does not slow it. On Mancave the whole test takes 10–24 s on develop too. The window is now 45 s, inside the test's 60 s budget.Directory.exportinside the Dagger module writes into the function's sandbox, not onto the runner, so nothing reached the artifact upload. It gets reworked on its own PR.ai-chat-discovery"independent signed-in devices…" (as run 1 did). It cold-starts a second browser context, whose local database opened too late on Mancave: "ClientDb is running without its local cache". That context's app did not render withinsignIn's 20 s, and its chat answer did not arrive within 10 s. The test is nowtest.slow(), allows that ClientDb warning as an optional diagnostic, and waits up to 30 s for both answers.signIn's cold-boot wait is now 45 s; it only takes longer when boot is slow. Locally against a CI-style production build: 6/6.de.pokeeps its 12 translations), data-browsertscpasses,pnpm run -r lintis clean, and vitest passes 1519 of 1519.Checked locally on this branch: data-browser
tsc --noEmitpasses,pnpm --filter @tomic/data-browser lintis clean, and vitest passes (1471 of 1471 after adding #1917, plus@tomic/libwebsockets 34 of 34;scripts/integration-mcp.test.mjsis a node:test file vitest can't collect, the same as on develop).