Use shared headings and consistent field widths across the dashboard. Load older messages on scroll and prevent unread badges from flashing after sending messages.
Preserve the sidebar preference after search navigation and layout changes.
Show unsorted icons on hover or focus. Move toast close buttons right and apply theme colors.
Let the main panels fill the remaining space to avoid layout warnings.
Save the conversation sidebar width in pixels to keep both dividers independent.
Use explicit transition timing for emoji pickers to remove Tailwind warnings.
Center avatar initials on a subtle theme gradient.
Reduce the inbox form to five grouped tabs and add a responsive live preview.
Add separate light and dark branding with system theme support.
Add launcher size and logo scale controls. Ref #627
Fix realtime message ordering in the agent dashboard. Fixes#626
Widget:
- home background stays pinned while the content scrolls, fade sits on it
- one radius and shadow scale across cards, buttons and inputs
- live search in the help tab with a "no results" state
- attachment-only messages show "Image" in the conversation preview
- launcher and panel use the same shadows as the header
Admin:
- preview column is a fixed width so zoom does not resize it, hidden on small screens
- preview matches the real widget again
- search spinner replaces the magnifier instead of covering the page
Fixes:
- deleting a proactive message did nothing, the dialog cleared the pending
id before the handler read it
- an inbox created through the API could not be saved from the form, it
jumped to the pre-chat tab with no error
Adds livechatWidgetTabs.cy.js covering the proactive message and help
center tabs.
Idle agents still get auto-assigned tickets. Only the manual away
statuses skip them. The amber away dot made other agents think the
idle person would not get tickets. The agent picker, widget header
and the agents report now treat idle as online.
Expand widget conversations with audience-specific forms, AI handoffs, message previews, and help article translations. Keep existing inbox settings compatible and reject invalid live chat configuration.
Keep local templates unchanged when Meta rejects edits or deletions. Block unsupported template sends and add regression tests for template actions and form controls.
The fullscreen composer closed itself before the send checks ran, so a
blocked send (empty To, missing tags, contact email not in recipients)
collapsed the editor on a phone even though nothing was sent. The close
now happens after all the guards.
The hover rewrite dropped focus-within from the private note delete menu,
so it could not be reached by keyboard on desktop. Put it back.
The mobile contact sheet hides its own close button, so the collapse icon
was the only way out at 28px. It is 44px below md now and stays 28px above.
Also dropped `overflow-wrap: break-all` from .message-bubble. break-all is
not a valid overflow-wrap value, so that line never did anything.
The rest is comment cleanup and switching `../..` imports to `@main` in the
files already being touched.
Bumps taps to 44px across the sidebar, reply box, conversation header and
data tables, adds a `can-hover` Tailwind variant so hover-gated controls
work on touch, and makes the reports page stack on narrow screens.
The country code was guessed from navigator.language, which is the UI
language and often has no region, so most visitors got US. It now reads
the browser timezone first and falls back to language, then US.
`DialogContent` and `AlertDialogContent` are `w-full max-w-lg` with no side
inset, no max height and no vertical scrolling, and `sm:rounded-lg` only
applies from 640px. In a window narrower than that they render edge to
edge with square corners, and cannot be scrolled when taller than the
viewport.
Add a 1rem side inset, `max-h-[calc(100dvh-2rem)]` with `overflow-y-auto`,
and make the radius unconditional. At 640px and above `max-w-lg` still
governs the width, so nothing changes there.
Fixing the two primitives covers all 17 dialog call sites.
Lets an agent triage and reply to conversations from a phone. Admin and
reports are deliberately untouched, per the discussion in #470.
`apps/main/index.html` pinned `width=1280, initial-scale=0.29`, which makes
a phone lay the page out at 1280 CSS pixels and scale the document to 29
percent. Switching it to `width=device-width` requires the layout to cope
with a real viewport:
- Add `useIsMobile`, using `max-width: 767px` so it is the exact complement
of Tailwind's `md:`. Align the sidebar primitive's own query to match; at
exactly 768px it previously reported mobile while `md:` already applied.
- Fold the 3rem icon rail into the drawer. The mobile `Sheet` in
`ui/sidebar/Sidebar.vue` was already implemented but unreachable, since
the layout viewport could never match its media query. The rail is
`collapsible="none"`, which returns before the Sheet branch, so its
destinations move into the one drawer rather than nesting a second.
- Render the inbox one pane at a time below `md`. Both `ResizablePanelGroup`
minimums are percentages of the window, giving a ~205px thread beside a
~117px contact sidebar at 390px, which no class change can fix. The
routes are already nested, so list-to-detail is push navigation with a
back affordance; only the desktop branch reads the persisted panel sizes.
- Show the contact sidebar as a `Sheet`. It has no intrinsic width, being
sized entirely by its panel, and `collapse()`/`expand()` are splitter
specific, so this is a parallel path off the same emitter event.
- Collapse the composer to a tap target that opens the existing fullscreen
editor, and make that dialog full-bleed below `sm`; its `max-w-[60%]`
gave a 234px modal at 390px. Inline it takes ~280px, which with a soft
keyboard raised leaves the thread nothing.
- Widen message bubbles and trim the hardcoded 47px gutters on phones, and
use `overflow-wrap: break-word` so ordinary words stop splitting
mid-character. Reveal the private-note menu on touch via
`[@media(hover:hover)]`.
- Remove `SmallScreenOverlay`, whose tuned `scale(3)` existed only to
cancel out the old `initial-scale`.
Desktop is unchanged, verified by screenshot comparison at 1440px.
Agents can now publish a public knowledge base per help center.
Backend:
- new internal/helpcenter package for help centers, collections and articles
- admin JSON API behind a new help_center:manage permission
- public /hc/{slug} pages, JSON API, search and sitemap, all rate limited
- migration v2.7.0 for the new tables
AI:
- published articles with the AI flag on get embedded, so the agent answers
from them. Unpublishing or clearing the flag removes the embeddings.
Media:
- media rows now carry a private flag. Help article images are public so the
public pages can serve them without auth, and only agents with
help_center:manage can upload them.
Frontend:
- admin help center list, tree view and article editor
- the old TextEditor is split into ArticleEditor and ConversationEditor over a
shared useTextEditor composable, so article-only tools like callouts,
collapsibles and YouTube embeds stay out of the reply box
Colors: the brand color moves from indigo to green in both themes, and the
sidebar, tooltip, card and link styles follow it. Three new tokens replace
hardcoded values: foreground-lighter for idle sidebar items, warning-600 for
warning text that needs 4.5:1 contrast on light backgrounds, and link for
anchors inside rendered email content. DESIGN_SYSTEM.md now lists the real
values from main.scss instead of the old indigo ones.
Forms: every button inside a form that is not the submit button now has an
explicit type. Without it the browser treats it as a submit button, so
clicking Cancel on a contact note posted an empty note, "New holiday" saved
the whole business-hours form, and pressing Enter in an SLA field deleted the
first alert row. The login page also highlights an empty password field on a
failed submit, which a broken condition prevented before, and the two
password fields on the set-password page get their own show and hide toggles.
Search: conversation and contact search now drop responses from an older
query, so clearing the box no longer repopulates the list with stale results.
Permissions: /api/v1/ai/summarize now needs messages:write, since it writes a
private note, and the menu item is hidden for agents without it.