Commit Graph

126 Commits

Author SHA1 Message Date
Abhinav Raut 7fee393cce fix issues found during release testing
- Save recipient edits and sender choices with reply drafts.
- Keep CC and BCC open when an address is cleared.
- Allow SMTP without credentials when authentication is off.
- Use the workspace timezone for reports and campaign dates.
- Show CSAT responses without reloading the conversation.
- Block access to attachments from deleted messages.
- Accept conditional email templates and catch missing or repeated replies.
- Explain why choosing another default email template failed.
- Reload stale routes and keep widget image fallbacks working.
- Keep the launcher usable by keyboard and reset host button styles.
2026-10-20 00:58:33 +05:30
Abhinav Raut 13bfa07402 merge main into the widget language branch 2026-10-19 00:00:30 +05:30
Abhinav Raut f87d99f452 polish app layouts and fix UI regressions
Use available admin space and make forms adapt to screen width.
Preserve reply edits during resizing and improve widget feedback.
2026-10-12 00:34:18 +05:30
Abhinav Raut 5b3fbcb381 Merge pull request #679 from abhinavxd/fix-related-article-spacing-inbox
fix chat scrolling and related article spacing
2026-10-10 20:35:31 +05:30
Abhinav Raut 544dcf9fde update black launcher logo 2026-10-10 20:14:42 +05:30
Abhinav Raut fae282d9d0 fix layout and interactions in both helpcenter templates 2026-10-10 17:50:37 +05:30
Abhinav Raut 4275b718bc fix chat scrolling and related article spacing 2026-10-10 04:01:02 +05:30
Yinghao Sun 475bf6916c let the host page choose the live chat widget language
The widget's UI language was either the inbox's fixed language or, on
"auto", the browser's. Host apps with their own language switch had no
way to tell the widget which language their user picked.

- widget.js: an optional `language` setting (LibredeskSettings or
  initLibredesk) is passed to the iframe as `lang`, and
  `Libredesk.setLanguage(code)` switches it later. A call made while the
  iframe is still loading is sent once it reports WIDGET_LOADED.
- main.js: on inboxes set to "auto", a `lang` the host passed wins over
  the browser language; a language the admin fixed for the inbox stays.
- App.vue: SET_LANGUAGE loads the strings and switches the i18n locale in
  place (help center content reloads in the new language), so an open
  conversation is not reset.
- Short or regional tags match a shipped translation: zh -> zh-CN,
  de-AT -> de-DE.

Closes #657
2026-10-04 23:13:59 +01:00
Abhinav Raut 73f9ab3ec5 hide the closed widget window on a timer 2026-10-04 22:55:04 +05:30
Abhinav Raut bfcdcc0dbe tune animations across the app and widget 2026-10-04 22:37:14 +05:30
Abhinav Raut 8068c28cb2 simplify new i18n keys 2026-09-23 03:28:20 +05:30
Abhinav Raut 7ecc9fd084 fix help center colors that broke or went missing in dark mode 2026-09-23 02:07:02 +05:30
Abhinav Raut a2ba6fa305 add a light, dark or system color scheme setting to the help center
This replaces the old "hide theme toggle" checkbox. Admins can also set a separate primary color for dark mode, and the dark logo falls back to the light one when it's empty.
2026-09-23 01:19:20 +05:30
Abhinav Raut 0df54faac7 fix color scheme listener on old safari and reject fractional message counts 2026-09-22 12:28:30 +05:30
Abhinav Raut 127d98c46e fix proactive message bugs and simplify launcher and preview settings 2026-09-22 03:17:42 +05:30
Abhinav Raut a6143729c7 fix widget compatibility and asset loading 2026-09-22 01:57:49 +05:30
Abhinav Raut 374cd26e4a improve live chat widget settings and branding
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
2026-09-22 01:29:25 +05:30
Abhinav Raut 4ceb40e292 keep dark mode when navigating the help center inside the widget 2026-09-21 01:24:09 +05:30
Abhinav Raut f73434eea7 let admins link and unlink help center article translations
An article written in another language can now be joined to an existing
article as its translation, or pulled back out into its own group. Also caps
transcript downloads at 1000 messages and fixes the field widths in the
automation rule and action rows.
2026-09-21 01:01:31 +05:30
Abhinav Raut 04464fb2e0 show message previews only after the widget loads 2026-09-20 23:19:57 +05:30
Abhinav Raut 835128504e fix widget, search and help center bugs
- handoff form no longer overwrites a JWT contact's name, email or phone.
  The CRM resyncs those on every exchange, so the edit reverted anyway.
  Visitors still get their submitted values saved.
- search queries dropped the cs and cp table aliases. Any saved view
  filtering on conversation_statuses.name returned a 500.
- status and priority never showed as selected in the search filters.
  The combobox compares strings, the store gives numbers.
- widget logout left the previous visitor's pre chat draft on screen.
- an auto hidden campaign preview was suppressed forever instead of for
  the session.
- switching campaigns in the admin preview did not close the open panel.
  The watcher only saw null and non null, so it now keys on campaign id.
- the Help tab blanked out when featured_ids came back as null.
- copilot panel spinner stuck when no conversation was open.
- help center theme toggle was hidden when there were no nav links and
  one locale.
- help center dark mode leaked into the article panel inside the widget.
2026-09-20 22:51:20 +05:30
Abhinav Raut bd3e73612c add dark mode to the help center
A moon button next to the language picker switches the site between light
and dark. Visitors start in light and the choice is saved in their browser.
Admins get a dark logo field, a checkbox to hide the button, and a light
or dark switch on the customize preview. Colors an admin picks for the
header and footer only apply in light mode.
2026-09-20 21:35:10 +05:30
Abhinav Raut 08e6801fc4 polish widget UI and fix proactive message delete
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.
2026-09-20 18:48:51 +05:30
Abhinav Raut a074bc4d55 add hover animation to widget launcher
The launcher grows a little on hover and springs back when the pointer
leaves. Also adds a black launcher logo for light backgrounds, softens
the launcher shadow, and expands the widget when help opens on an article.
2026-09-19 17:27:01 +05:30
Abhinav Raut f6f1bb4ad1 show helpcenter article as is inside the widget. adds new ?embed query param that shows the entire helpcenter in embed mode 2026-09-19 03:58:04 +05:30
Abhinav Raut d2dc51b734 link article translations by group id and tidy the widget chat
Move the translation_group_id migration into v2.9.0 and drop the slug backfill. Existing articles each get their own group and admins link translations from the new UI. The public article page now builds its language links from the group instead of the slug, so translations with different slugs no longer 404.
2026-09-19 02:13:13 +05:30
Abhinav Raut 216451647b label audience prechat toggle, pin handoff conversation, clear dismissed preview timers 2026-09-18 20:07:35 +05:30
Abhinav Raut 7d77754b52 improve live chat widget flows
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.
2026-09-18 16:09:15 +05:30
Abhinav Raut 9c1e14704f fix campaign reply and poll edge cases, enlarge mobile launcher 2026-09-18 01:05:21 +05:30
Abhinav Raut 89f58904d2 wip: add widget campaigns, help center in widget and transcript download 2026-09-16 02:11:44 +05:30
Abhinav Raut 102e9fc625 apply Geist to toasts, charts and form controls 2026-08-21 12:59:19 +05:30
Abhinav Raut a9867dce00 move public help center api under /api/v1 and add security headers 2026-08-21 04:55:07 +05:30
Abhinav Raut 6208b291ce fix cache misses, wrong view counts, and silent cache errors in the help center 2026-08-20 21:56:54 +05:30
Abhinav Raut c865748ca5 switch to Geist and cache help center pages
Geist replaces Instrument Sans and is served from static/ instead of Google
Fonts, so it works on installs with no internet access.

Public help center pages are cached in Redis via fastcache with ETags, and any
admin write clears the group so edits show up on the next load.
2026-08-20 18:01:42 +05:30
Abhinav Raut 0c99b015cd fix missing logo in emails on a fresh install 2026-08-17 18:10:13 +05:30
Abhinav Raut 1ac0c77b88 harden help center public routes and render a themed 500 page
Uptime checkers and link validators probe with HEAD, so register
HEAD on all public routes and treat HEAD as a crawler so probes
do not inflate view counts or write search logs.

The custom-domain host lookup hit the DB before any rate limit.
Both the not-found gate and the host-home redirect now pay the
"public" limit first, and the middleware skips double-charging.

DB errors on help center pages rendered the plain unthemed error
page. Reuse the themed notfound template for them: it now takes
code, title, and text, so 404 and 500 both render inside the theme.

Also cap the sitemap at the URL limit, skip re-embedding unchanged
content in the AI embed reconciler, and autofocus the login email.
2026-08-15 12:19:50 +05:30
Abhinav Raut 2183e8140d move help center branding columns into theme and ship Instrument Sans 2026-08-15 02:22:49 +05:30
Abhinav Raut 6e020dd694 improve help center tree and docs template hierarchy UX 2026-08-15 01:39:07 +05:30
Abhinav Raut 1feb3743f6 dedupe help center template partials and reuse the markdown link helper 2026-08-14 01:44:37 +05:30
Abhinav Raut 2476ee2685 center the article editor toolbar and stop the feedback box resizing 2026-08-14 00:55:28 +05:30
Abhinav Raut cc6193c564 harden media serving and fix a few help center review findings 2026-08-14 00:50:56 +05:30
Abhinav Raut 11611de2b8 fix the second round of help center review findings
Frontend:
- the basics schema broke after the locale refine was added, since
  .pick() does not exist on a refined schema. Split the base object
  schema out and refine only the full form schema.
- creating a collection no longer overwrites the parent picked in the
  sheet with the preset parent, so "None" and other choices stick
- the article editor toolbar is inert while the editor is disabled,
  since teleporting moved it out of the pointer-events-none wrapper
- stop stealing focus when a parent swaps the editor content
- a11y: label the link/youtube URL inputs and the link list remove
  button, and make the help center name cell a real button

Backend:
- reject a custom domain whose hostname another help center already
  uses. App-level check in validateCustomDomain, matching the
  case-insensitive hostname comparison routing does.

Static:
- docs template: convert the remaining left/right rules to logical
  properties and flip the row arrows in RTL
- fix currentcolor casing in article-content.css
2026-08-13 18:29:07 +05:30
Abhinav Raut 5027fe23a2 fix a batch of help center review findings
Backend:
- log LinkHelpArticleMedia errors on article create/update
- trim a trailing slash off the root URL in PublicURL
- run uniqueCollectionSlug inside the caller's transaction
- update-article sets author_id directly so clearing the author works
- apply the help_centers template CHECK as a named constraint so it
  also lands on installs that ran an earlier build of the migration

Frontend:
- new editor tables get the email-safe inline styles by default
- replace deprecated word-wrap/word-break with overflow-wrap
- reject a default locale that is not in the allowed locales
- show an error when the icon picker sprite fails to load
- name the locale remove buttons and keep classic-only header
  fields mounted with v-show

Docs template:
- move the collection link out of <summary>, toggle is its own button
- use logical CSS properties so the sidebar nav renders in RTL
- fix text-rendering keyword casing
2026-08-13 17:12:12 +05:30
Abhinav Raut c494904ecf use a lucide chevron for the collapsible marker 2026-08-13 16:10:18 +05:30
Abhinav Raut 57af9bc20b add syntax highlighting and a copy button to article code blocks
Article code blocks were plain text with no language. They now use tiptap's
lowlight code block, and the toolbar button turns into a language dropdown
while the cursor is inside a block. 16 languages are registered.

Lowlight only highlights the editor with decorations, which tiptap never
serializes, so the saved HTML would have stayed plain. The content is run
through highlight.js on save, which bakes the hljs spans in. The published
page then needs no JS for colors, only CSS. Reopening an article flattens
the spans back to text, so they do not pile up. Existing articles need one
re-save to pick this up.

The published article page also gets a copy button on every code block,
injected by the shared behavior template. That template now receives the
root context, which it needed for the icons and labels.

Also: the editor toolbar shrink-wraps its buttons instead of stretching the
full column, and each help center row now has an Articles item in its
dropdown, so the article tree is reachable without clicking the name.
2026-08-13 15:31:26 +05:30
Abhinav Raut 6083d2f098 serve help centers at the root of a custom domain
public_url is now custom_domain. It only accepts a bare origin, no path or query.

When a help center has a custom domain, its pages live at /{locale} on that domain. Requests on that host fall through to the router's not-found handler, which prepends /hc/{slug} and re-runs the router once, so nothing about the routes changes. All page links come from a new BasePath value, which is empty-prefixed on a custom domain and /hc/{slug} on the app host. Hits on the old /hc/{slug} paths 301 to the custom domain so there is one canonical address per page.

Redirects now send a path-only Location built through fasthttp's URI encoder. ctx.Redirect would turn it into an absolute http:// URL, since nginx forwards to the app over plain HTTP, and a raw path would let /\host in the URL read as another site.

robots.txt on a custom domain also disallows the search pages.
2026-08-13 01:27:22 +05:30
Abhinav Raut 8ca05b2460 share collection cards between help center templates 2026-08-09 22:23:39 +05:30
Abhinav Raut fbbef49bb3 fix help center feedback counts, empty state, mobile logo and a11y 2026-08-09 19:47:57 +05:30
Abhinav Raut 048eb1acd5 add page template setting for help center with docs and classic layouts
Help centers now have a template setting with two layouts. Classic is
the default: the existing hero banner, large search bar and collection
cards. Docs is new: sticky top bar, collections sidebar on every page,
command palette search (Ctrl+K) with a no-JS fallback form, and an
on-page table of contents.

Backend adds a template column (default 'classic', checked to the two
values), threads it through insert/update queries and the request
validator, and resolves page template names as '<template>-<page>' when
rendering public pages. Docs pages also get the published tree for the
sidebar.

Public templates are restructured so each layout is fully isolated and
a third template is just a new directory plus its CSS file:
web-templates/help/shared/ holds the head, announcement, lang switcher,
icons and shared JS; help/classic/ and help/docs/ each hold their own
layout and five pages. The classic stylesheet is renamed to
help-center-classic.css so the head links help-center-<template>.css
directly. Template parsing now globs the help/ subdirectories too.

The admin create and edit forms get a template picker, and classic-only
styling fields (header background, collection layout, card icons) are
hidden when docs is selected.
2026-08-09 17:40:52 +05:30
Abhinav Raut 353558ce9b add a public URL per help center and fix code review issues
Each help center gets an optional public_url. When set, canonical links, hreflang
alternates, og:url, the sitemap and robots.txt point at that host instead of the
app root URL. Stored media URLs are rewritten to root-relative paths so logos,
favicons, header images and article images resolve on whichever host serves the
page. The URL is validated on both the form and the backend, and trailing slashes
are trimmed.

Also fixes issues found in code review:

- the help center template used a locale link as the data root inside the
  alternates loop, which broke every public page on a help center with two or
  more locales
- creating an article posted the clicked collection id, so changing the
  collection in the sheet filed the article in the wrong place
- the collection field's error message was hidden when the locale had no
  collections, so Create did nothing with no error shown
- switching the header type or unticking popular articles dropped those theme
  values on save, because vee-validate unsets fields that unmount
- closing a new collection sheet with Esc left the parent id set, so the next
  collection you edited got re-parented
- a table row with th labels in the first column was treated as a header row
  when preparing article content for embeddings
- the img tag regex stopped at a > inside an attribute value and injected
  loading/decoding in the middle of an attribute
2026-08-05 01:10:31 +05:30