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.
This commit is contained in:
Abhinav Raut
2026-09-20 18:48:51 +05:30
parent a074bc4d55
commit 08e6801fc4
52 changed files with 923 additions and 426 deletions
+5 -2
View File
@@ -5,8 +5,11 @@ It holds two fake accounts and looks them up by the contact's external user id,
which libredesk sends in the `X-Libredesk-Contact-External-Id` header. Add your
own test users by editing the `users` map in `main.go`.
Custom tools are only called by AI assistants. Copilot gets the built-in tools
and never touches these.
AI assistants call every enabled custom tool. Copilot and Generate Reply call the
ones with "Available in Copilot" or "Available in Generate Reply" turned on, and a
tool with "Require agent approval" on waits for the agent to approve the call there.
"Require verified contact" applies to assistant runs only, since an agent is the one
asking on the Copilot and Generate Reply surfaces.
## Run
+1 -1
View File
@@ -16,7 +16,7 @@ Open `http://localhost:8005`, then fill in:
- **baseURL**: your Libredesk instance (default `http://localhost:8001` - Default points to the widget dev server, not the API server)
- **inboxID**: the livechat inbox's UUID (from the inbox's installation snippet)
- **Signing secret**: the "Secret Key" from that inbox's Security tab
- **Signing secret**: the "Secret Key" from the inbox form
`exp` is set to now + 1 hour on every generate. Use "Clear session" to drop the
widget's cookies and start over as a brand-new visitor.
+10 -3
View File
@@ -2,9 +2,14 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Libredesk widget - JWT test</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; max-width: 720px; margin: 40px auto; padding: 0 16px; color: #222; }
@media (max-width: 640px) {
body { margin: 16px auto; }
.row { flex-direction: column; gap: 0; }
}
h1 { font-size: 18px; }
label { display: block; margin-top: 14px; font-size: 13px; font-weight: 600; color: #444; }
input, textarea { width: 100%; box-sizing: border-box; font-family: ui-monospace, monospace; font-size: 13px; padding: 8px; margin-top: 4px; border: 1px solid #ccc; border-radius: 6px; }
@@ -16,12 +21,13 @@
.row { display: flex; gap: 12px; }
.row > div { flex: 1; }
.hint { font-size: 12px; color: #777; font-weight: 400; }
.field-hint { display: block; margin-top: 4px; }
</style>
</head>
<body>
<h1>Libredesk widget - JWT auth test</h1>
<p class="hint">Edit the payload below, click "Sign JWT &amp; load widget". <code>exp</code> is auto-set to now + 1 hour on every generate so the token never shows up expired. The signing secret must match the "Secret Key" configured on this inbox's Security tab in Libredesk admin.</p>
<p class="hint">Edit the payload below, then load the widget. The signing secret must match the "Secret Key" configured in the inbox form.</p>
<div class="row">
<div>
@@ -29,8 +35,9 @@
<input id="baseURL" value="http://localhost:8001">
</div>
<div>
<label>inboxID</label>
<input id="inboxID" placeholder="livechat inbox UUID from inbox form" value="">
<label for="inboxID">Inbox UUID</label>
<input id="inboxID" aria-describedby="inboxIDHint" value="">
<span id="inboxIDHint" class="hint field-hint">Copy the UUID from your inbox form.</span>
</div>
</div>