# Closes#14189.
Fixes the three UX issues reported in the original bug report, plus one
small
adjacent polish on the right-sidebar toggle that was requested during
review.
Each concern in the issue is addressed end-to-end, with the same
treatment
applied to both places the AI chat panel lives: the **sidebar chat
panel**
(right panel on a doc page) and the **standalone `/chat` page**.
---
## 1. `+` button → persistent multi-session tabs (issue point 1)
**Before:** clicking `+` called `createFreshSession()` (standalone) or
`newSession()` (sidebar), both of which tore down the current chat
content
and replaced it in place. There was no way to keep two chats open at
once.
**After:** a browser/IDE-style tab strip lives above the chat content.
Each
open session gets its own tab with a close `×`; the active tab is
highlighted; `+` now adds a tab rather than replacing the chat.
### Details
- New Lit component `ai-chat-tabs`
([packages/frontend/core/src/blocksuite/ai/components/ai-chat-toolbar/ai-chat-tabs.ts](packages/frontend/core/src/blocksuite/ai/components/ai-chat-toolbar/ai-chat-tabs.ts)).
- Tab title is derived from `session.title` → first user message → `"New
chat"`.
- Horizontal scroll when tabs overflow, with a `wheel` handler that
converts
mouse wheel / trackpad vertical swipe into horizontal scroll (native
horizontal trackpad swipes also work natively via `overflow-x: auto`).
- Auto `scrollIntoView({ inline: 'nearest' })` on active tab change, so
a
newly created or newly selected tab slides into view instead of staying
hidden behind the toolbar.
- Close `×` removes the tab from the strip but leaves the session on the
server (matches the existing **Chat history** dropdown semantics — the
session is still reachable there). Closing the active tab switches to an
adjacent one; closing the last tab starts a fresh session.
- Persistence: open session IDs are saved per-workspace in
`localStorage`
under `ai-chat-open-tabs:{workspaceId}`. On mount, the React pages
hydrate
those IDs via `AIProvider.session.getSession` /
`CopilotClient.getSession` — no new backend or schema work.
- Wiring: identical effects on both variants
([chat.tsx
(sidebar)](packages/frontend/core/src/desktop/pages/workspace/detail-page/tabs/chat.tsx)
and
[chat/index.tsx
(standalone)](packages/frontend/core/src/desktop/pages/workspace/chat/index.tsx))
— hydrate → sync active session into tabs → persist.
- The tab strip sits on the same row as the existing toolbar icons
(pin / history / `+`), separated by `flex: 1` + `min-width: 0` so the
tabs scroll cleanly up to the toolbar boundary.
- The `ShadowlessElement` base class injects its static CSS globally,
and the
`:host` selector does not match in a React-rooted DOM — the component
uses
tag-selector CSS (`ai-chat-tabs { display: flex; … }`) instead.
## 2. Drag-and-drop attachments (issue point 2)
**Before:** the chat input accepted no DnD. Attaching anything required
the
`+` → file-picker flow.
**After:** the chat input accepts OS files via native HTML5 DnD and
AFFiNE
documents via the repo's existing pragmatic-drag-and-drop
infrastructure.
### Details
- Native handlers (`dragenter/over/leave/drop`) on
[ai-chat-input.ts](packages/frontend/core/src/blocksuite/ai/components/ai-chat-input/ai-chat-input.ts)
accept OS files: images go into the image preview grid, other files
become
attachment chips, with the same 50 MB per-file cap as the `+` picker.
- Internal AFFiNE document drags from the nav panel land as doc chips,
handled via `dropTargetForElements` from
`@atlaskit/pragmatic-drag-and-drop` (same library the rest of the app
already uses for internal DnD).
- A "Drop to attach" overlay appears during drag, reusing the existing
focused-border token (`--affine-v2-layer-insideBorder-primaryBorder`)
for
visual consistency with the focused state.
- The image/file routing logic that previously lived inline in
`add-popover.ts` was factored into a shared helper
[attachment-utils.ts](packages/frontend/core/src/blocksuite/ai/components/ai-chat-chips/attachment-utils.ts)
(`addFilesToChat`), so the `+` picker and the drop handler stay in
lockstep.
- Analytics: extended the `addEmbeddingDoc.control` union in
[events.ts](packages/frontend/track/src/events.ts) with `'dragDrop'` so
drag-originated attachments are distinguishable from button-initiated
ones in telemetry.
- `@atlaskit/pragmatic-drag-and-drop` is promoted from a transitive
dependency (via `@affine/component`) to a direct dependency of
`@affine/core` and `yarn.lock` is refreshed accordingly.
## 3. Chat-history tooltip + icon (issue point 3)
**Before:** hovering the chat-history button showed a tooltip whose
background did not invert for dark theme (`--affine-tooltip` is not
theme-aware), and the icon was `ArrowDownSmallIcon` — a chevron that
does
not convey "history."
**After:** the tooltip primitive itself is theme-aware (every tooltip in
the app benefits, not just the chat one), and the icon is the
semantically-clear `HistoryIcon`.
### Details
- [tooltip.ts](blocksuite/affine/components/src/tooltip/tooltip.ts) now
uses
`var(--affine-v2-tooltips-background, var(--affine-tooltip))` and
`var(--affine-v2-tooltips-foreground, var(--affine-white))`. The V2
tokens auto-invert with theme; the old vars remain as fallbacks so
components that override via the existing `tooltipStyle` escape hatch
continue to work.
- Triangle arrow colors updated to use the same V2 token.
-
[ai-chat-toolbar.ts](packages/frontend/core/src/blocksuite/ai/components/ai-chat-toolbar/ai-chat-toolbar.ts):
`ArrowDownSmallIcon` → `HistoryIcon`; added
`data-testid="ai-panel-chat-history"` for future e2e coverage.
## 4. Right-sidebar toggle: tooltips + open-state icon *(adjacent
polish)*
Not part of the original issue, but surfaced while testing the tab strip
—
neither of the two right-sidebar toggle buttons had hover affordance,
and
both used the same icon regardless of the sidebar's state.
- Added `tooltip="Open sidebar"` on the route-container button shown
when
the sidebar is hidden.
- Added `tooltip="Close sidebar"` on the sidebar-header button shown
when
the sidebar is expanded.
- The close button now renders a small inline `RightSidebarOpenIcon`
variant: same outline as `RightSidebarIcon`, but with the right panel
filled in the AFFiNE accent color to convey the open state. Icon shape
change is self-contained — no new icon asset added to
`@blocksuite/icons`.
---
## Commits
- `2adc0c7` — fix(ai-chat): theme-aware tooltip + semantic chat-history
icon *(2 files)*
- `bf26974` — feat(ai-chat): drag-and-drop file and doc attachments in
chat input *(7 files)*
- `fca29c8` — feat(ai-chat): persistent multi-session tab strip *(8
files)*
- `7d5dffe` — feat(workbench): tooltips and open-state icon for the
right-sidebar toggle *(2 files)*
Kept ordered smallest → largest blast radius so the history is easy to
bisect.
---
## Test plan
Verified locally against a fresh server stack (postgres / redis /
mailpit via
compose, migrations run) signed in as `dev@affine.pro`, in both `/chat`
and
the sidebar chat on a doc page, in light and dark themes:
- [x] Tooltip: hover the chat-history icon in dark mode → tooltip is
dark-on-light; toggle to light mode → tooltip is light-on-dark. Existing
tooltips on other surfaces (slash menu, edgeless, linked-doc) still
render correctly.
- [x] Icon: chat-history button renders the history glyph (clock), not a
chevron.
- [x] Drag-and-drop (OS file): drop a PDF / PNG / TXT onto the input →
overlay shows → chips/images appear; file > 50 MB → rejected silently
(same as `+` picker).
- [x] Drag-and-drop (internal doc): drag an AFFiNE doc from the nav
panel → becomes a doc chip.
- [x] Pin-picker, `+` picker, paste-image — all unchanged.
- [x] Tab strip: first chat auto-becomes a tab on first message; `+`
adds tab; click tab switches chat; `×` removes tab and switches to
adjacent; close last tab → new fresh tab spawns.
- [x] Reload browser → tab strip rehydrates from localStorage with the
same sessions.
- [x] Tab overflow: 12+ tabs → horizontal scroll via trackpad vertical
swipe, trackpad horizontal swipe, and mouse wheel; active tab
auto-scrolls into view on `+` click.
- [x] Right-sidebar: hover both toggle buttons → tooltips appear; open
the sidebar → close button shows the filled right-panel icon.
- [x] `yarn lint:ox` and lint-staged both clean on every commit.
Not verified locally (no local model key configured): the assistant
actually
streams a response. Drop/chip flow is independent of that path.
## Out of scope / follow-ups
- No new unit or Playwright tests — the fixes are visually verifiable
and
reuse existing reducer / state paths. Happy to add tests if reviewers
prefer.
- `@affine/native` is not required for the web dev stack; I only built
`@affine/server-native`. Irrelevant to the PR diff.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Multi-tab chat UI with a tabs component, open/close/switch actions,
and per-workspace persistence/restoration.
* Drag-and-drop attachments into chat input (files and docs).
* **UI/UX**
* Tooltip theming moved to v2 variables (includes arrow color).
* Sidebar toggle/close buttons now show tooltips.
* “Drop to attach” overlay and updated history icon.
* **Behavior**
* Unified attachment handling with 50MB validation and toast notices.
* **Analytics**
* Attachment events record drag-and-drop as a control method.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
#### PR Dependency Tree
* **PR #14583** 👈
This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added Gemini 3.1 Pro Preview support (text, image, audio) and new
GPT‑5 variants as defaults; centralized persistent telemetry state for
more reliable client identity.
* **UX**
* Improved model submenu placement in chat preferences.
* More robust mindmap parsing, preview, regeneration and replace
behavior.
* **Chores**
* Bumped AI SDK and related dependencies.
* **Tests**
* Expanded/updated tests and increased timeouts for flaky flows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
#### PR Dependency Tree
* **PR #14452** 👈
This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved null-safety, dependency tracking, upload validation, and
error logging for more reliable uploads, clipboard, calendar linking,
telemetry, PDF/theme printing, and preview/zoom behavior.
* Tightened handling of all-day calendar events (missing date now
reported).
* **Deprecations**
* Removed deprecated RadioButton and RadioButtonGroup; use RadioGroup.
* **Chores**
* Unified and upgraded linting/config, reorganized imports, and
standardized binary handling for more consistent builds and tooling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Close [AI-335](https://linear.app/affine-design/issue/AI-335)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added support for an "independent mode" and document-specific context
in AI chat components, allowing enhanced context handling and tracking.
* Introduced new tracking options to distinguish between current
document and general document actions in chat interactions.
* **Improvements**
* More flexible property handling for independent mode and document
context across chat-related components for consistent behavior and
tracking.
* Enhanced tracking system to support additional event categories and
methods for more granular analytics.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added user interaction tracking for document editing and diff review
actions, including accepting, rejecting, applying, and copying changes.
* Introduced tracking for "Accept all" and "Reject all" actions in block
diff views.
* **Chores**
* Enhanced event tracking system with new event types and payloads to
support detailed analytics for editing and review actions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
fix PD-2688
#### PR Dependency Tree
* **PR #13105** 👈
This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Summary by CodeRabbit
* **New Features**
* Added configurable support for enabling or disabling inline comments.
* Introduced visual indication (strikethrough) for deleted comments in
the comment sidebar.
* Sidebar now shows when a comment is no longer present in the editor.
* Added a localized placeholder prompt ("What are your thoughts?") in
the comment editor.
* Integrated detailed event tracking for comment actions: create, edit,
delete, and resolve.
* **Improvements**
* Inline comments are now disabled in shared mode.
* Enhanced synchronization between editor comments and provider state to
remove stale comments.
* Inline comment features now respect the document’s read-only state.
* Improved mention handling and tracking in comment creation and
editing.
* Comment manager and entities now dynamically track comments present in
the editor.
* Comment configuration updated to enable or disable inline comments
based on settings.
* **Bug Fixes**
* Prevented comment block creation when in read-only mode.
* **Localization**
* Added English localization for the comment prompt.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
#### PR Dependency Tree
* **PR #13105** 👈
This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
- **New Features**
- Enhanced tracking for code block interactions, including language selection and preview toggling.
- Improved error reporting for HTML block preview failures, providing better visibility into issues.
- **Bug Fixes**
- Added explicit feedback and tracking when cross-origin isolation is not supported during code block preview setup.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
- **New Features**
- Added tracking for document creation when importing with the clipper tool.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
- **New Features**
- Added enhanced tracking for user interactions across document lists, navigation, display menus, quick actions, and collection operations.
- User actions such as opening documents, editing collections, toggling favorites, changing view modes, and navigating collections are now logged for analytics.
- **Chores**
- Expanded internal event tracking capabilities to support more detailed analytics on user interactions throughout the interface.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
- **New Features**
- Implemented account deletion functionality with confirmation dialogs and success notifications.
- Added a warning modal for team workspace owners before account deletion.
- Introduced a new, richly formatted internationalized message for account deletion confirmation.
- Added a new dialog component to inform users of successful account deletion.
- **Improvements**
- Updated localization strings to provide detailed guidance and warnings for account deletion.
- Enhanced error handling by converting errors into user-friendly notifications.
- Simplified and improved the sign-out process with better error handling and streamlined navigation.
- **Style**
- Added new style constants for success and warning modals related to account deletion.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
- **New Features**
- Added event tracking for workspace embedding settings, including toggling embedding, uploading attachments, and selecting ignored documents. This enhances visibility into user interactions within the embedding settings panel.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Close [BS-2315](https://linear.app/affine-design/issue/BS-2315/page-block-header)
### What Changes
- Add header toolbar to page block (the first note in canvas)
- Add e2e tests
- Add some edgeless e2e test utils. **The package `@blocksuite/affine` was added to `"@affine-test/kit"`**