Skip to content

feat(APP-998): support chat side panel, email escape hatch, centralized copy#1242

Open
tyhonchik wants to merge 7 commits into
mainfrom
app-998-polish-chat-assistant-ux-and-centralize-chat-copy
Open

feat(APP-998): support chat side panel, email escape hatch, centralized copy#1242
tyhonchik wants to merge 7 commits into
mainfrom
app-998-polish-chat-assistant-ux-and-centralize-chat-copy

Conversation

@tyhonchik

Copy link
Copy Markdown
Contributor

This turns the support chat from a blur overlay into a side panel the app resizes around, and centralizes all chat/assistant copy. Previously the chat was a Radix Dialog pinned over the page — backdrop blur, focus trap, page frozen behind it — opened from a footer link, with its strings scattered across a dozen widget components and the service. Now the chat is a full-height column next to the app (the header, content and footer shrink to fit), toggled from a button at the trailing edge of every navigation bar, and every string has exactly one home. The panel shell moves out of the widget into the app layout — the upcoming assistant-ui rework only swaps the panel's innards.

Changes

  • Overlay → in-flow side panel. On lg+ the panel is a sticky, full-viewport-height column (clamp(500px, 30vw, 640px)) with a ~300ms width animation; below lg it opens fullscreen with the page scroll locked behind it. Non-modal by design: no backdrop, no focus trap, no ESC-close — the page stays scrollable and interactive while the chat is open, and overscroll-contain keeps the chat scroll from chaining into the page. While closed the panel stays mounted (the conversation survives reopening) but inert.
  • Trigger moves footer → header. A new SupportChatTrigger (feedback icon ↔ chevron) sits at the trailing edge of all three navbars via a new trailing slot on Navigation.Container, so it lands right next to the panel. The footer "Support" entry reverts to the plain external portal link regardless of the flag; open/close state lives in a new SupportChatContextProvider in the root layout.
  • Support portal deprecated inside the chat. The header link and both error escape hatches now point to support@aragon.org (mailto) instead of the portal; the supportPortalUrl prop is removed from the widget API end-to-end.
  • Copy centralized, one module per package. Every user-facing widget string — including the service-error texts and file alerts — moves to packages/assistant-chat/src/copy.ts; components only reference it. Service-side, the static Linear ticket texts move from linear/issueBody.ts into chat/prompts/issueTexts.ts, so all service copy (prompts, fixed replies, ticket texts) is edited under chat/prompts/. Pure string moves, zero wording changes.
  • ChatDrawer deleted along with the widget's @radix-ui/react-dialog dependency; AssistantChat now just fills whatever container the host renders it in.

Note

The chat UI itself (message list, composer, status strip) is intentionally untouched — the assistant-ui evaluation happens in a follow-up branch based on this one. Wording changes beyond the portal→email swap are also out of scope here.

🤖 Generated with Claude Code

The chat is no longer a Radix Dialog overlay with a blur backdrop: on
lg+ screens it is an in-flow, full-height side panel the rest of the
layout resizes around (animated width, non-modal, page keeps its own
scroll and stays interactive), below lg it opens fullscreen with the
page scroll locked behind it. The panel shell now lives in the app
layout; the widget just fills its container.

The only trigger is a new header button (feedback icon <-> chevron)
pinned to the trailing edge of all three navigation bars, right next
to the panel; the footer Support entry reverts to the plain external
portal link.
…t email

The external support portal is deprecated as the chat's escape hatch:
the header link and the error suggestions now point to
support@aragon.org (mailto) instead. The supportPortalUrl prop is
removed from the widget API and the host; the footer keeps its own
external portal link.
Pure string moves, no wording changes. Every user-facing string of the
widget now lives in a single copy module
(packages/assistant-chat/src/copy.ts), including the service error
texts and file alerts; components only reference it. On the service
side, the static Linear ticket texts move from linear/issueBody.ts
into chat/prompts/issueTexts.ts so all service copy (prompts, fixed
replies, ticket texts) is edited under chat/prompts/.
@tyhonchik
tyhonchik requested a review from a team as a code owner July 16, 2026 18:42
@linear-code

linear-code Bot commented Jul 16, 2026

Copy link
Copy Markdown

APP-998

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown

🚀 Preview Deployment: View Here
🤖 Assistant Preview: View Here (app preview points at it)

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown

E2E results (preview)

Smoke

Base URL https://app-next-nw82dw78o-aragon-app.vercel.app
Suite smoke
Playwright result ✅ passed
Summary 81 passed, 1 skipped
HTML report View report
GitHub job ✅ completed

View run #4575

…inst them

Release flows now name a scope from .github/release-scopes.yml instead of
hardcoding package lists; pnpm validate:changesets (wired into pnpm test)
rejects changesets that mix packages from different release scopes, which
changeset version --ignore refuses at release time. The APP-998 changeset
is split per scope accordingly.
…screen readers

Below the lg breakpoint the open panel covers the whole viewport but left
the covered app column reachable; it is now made inert while the drawer is
open (re-evaluated across breakpoint changes). The closed panel is also
aria-hidden so its kept-mounted content stops being a complementary landmark.
@tyhonchik
tyhonchik force-pushed the app-998-polish-chat-assistant-ux-and-centralize-chat-copy branch from 74fb406 to fae492f Compare July 17, 2026 14:23
assistant:
- "@aragon/assistant"
- "@aragon/assistant-contracts"
- "@aragon/assistant-chat"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@aragon/assistant-chat ships inside the app bundle (@aragon/app depends on it and the app release filter includes packages/assistant-chat/**), but this maps it only to the assistant release scope. That means an app release can deploy assistant-chat changes without consuming the assistant-chat changeset/version/changelog; the package version would move later through an assistant flow that doesn't deploy the widget.

Can we either put app-bundled packages in the app scope, or make the coupled release behavior explicit so the tag that deploys the app also consumes the widget changeset it ships?

@thekidnamedkd

Copy link
Copy Markdown
Contributor

One copy miss I couldn't leave inline because the file isn't in the diff: apps/assistant/src/chat/prompts/fixedMessages.ts still tells users to press Create ticket in the turn/size limit replies, but the current widget flow exposes Prepare ticket and then Send ticket.

Can we update those fixed replies too, so users who hit the hard limit aren't sent looking for a button that no longer exists?

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.

2 participants