mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 02:06:43 +00:00
fix(ui): quiet the reconnect-wait queue row and hide its raw transport error (#111703)
This commit is contained in:
@@ -567,6 +567,28 @@ describe("renderChatComposer controls", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("renders reconnect waits as quiet status without the raw transport error", () => {
|
||||
const { container } = renderComposer({
|
||||
queue: [
|
||||
{
|
||||
id: "reconnect-1",
|
||||
text: "send me once the gateway is back",
|
||||
createdAt: 1,
|
||||
sendError: "chat.send unavailable during gateway restart",
|
||||
sendState: "waiting-reconnect",
|
||||
},
|
||||
],
|
||||
});
|
||||
const item = container.querySelector(".chat-queue__item");
|
||||
expect(item?.classList.contains("chat-queue__item--reconnect")).toBe(true);
|
||||
expect(item?.querySelector(".chat-queue__dot")).not.toBeNull();
|
||||
expect(item?.querySelector(".chat-queue__icon")).toBeNull();
|
||||
expect(item?.querySelector(".chat-queue__error")).toBeNull();
|
||||
const badge = item?.querySelector(".chat-queue__badge");
|
||||
expect(badge?.textContent?.trim()).toBe("Waiting for reconnect");
|
||||
expect(badge?.getAttribute("title")).toBe("chat.send unavailable during gateway restart");
|
||||
});
|
||||
|
||||
it("renders failed sends as retryable and running commands as inert", () => {
|
||||
const onQueueRetry = vi.fn();
|
||||
let view = renderComposer({
|
||||
|
||||
@@ -1087,6 +1087,7 @@ function renderChatQueueItem(item: ChatQueueItem, props: ChatQueueProps) {
|
||||
const stateLabel = sendStateLabel(item);
|
||||
const steered = isSteeredQueueItem(item);
|
||||
const failed = item.sendState === "failed" || item.sendState === "unconfirmed";
|
||||
const reconnecting = item.sendState === "waiting-reconnect";
|
||||
const busy = item.sendState === "executing-command" || isInflightSteer(item);
|
||||
const canSteer =
|
||||
Boolean(props.canAbort && props.onQueueSteer) &&
|
||||
@@ -1096,21 +1097,29 @@ function renderChatQueueItem(item: ChatQueueItem, props: ChatQueueProps) {
|
||||
const text = item.text || (item.attachments?.length ? `Image (${item.attachments.length})` : "");
|
||||
const itemClass = `chat-queue__item${steered ? " chat-queue__item--steered" : ""}${
|
||||
failed ? " chat-queue__item--failed" : ""
|
||||
}`;
|
||||
}${reconnecting ? " chat-queue__item--reconnect" : ""}`;
|
||||
// Row order keeps the actions on the first flex line; the error wraps below
|
||||
// them via flex-basis so failed rows grow by one line instead of a card.
|
||||
return html`
|
||||
<div class=${itemClass}>
|
||||
<span class="chat-queue__icon" aria-hidden="true">
|
||||
${failed ? icons.alertTriangle : icons.clock}
|
||||
</span>
|
||||
${reconnecting
|
||||
? html`<span class="chat-queue__dot" aria-hidden="true"></span>`
|
||||
: html`<span class="chat-queue__icon" aria-hidden="true">
|
||||
${failed ? icons.alertTriangle : icons.clock}
|
||||
</span>`}
|
||||
${renderChatAuthorAvatar(item.sender)}
|
||||
${steered
|
||||
? html`<span class="chat-queue__badge chat-queue__badge--steered"
|
||||
>${t("chat.queue.steered")}</span
|
||||
>`
|
||||
: nothing}
|
||||
${stateLabel ? html`<span class="chat-queue__badge">${stateLabel}</span>` : nothing}
|
||||
${stateLabel
|
||||
? html`<span
|
||||
class="chat-queue__badge"
|
||||
title=${ifDefined(reconnecting ? item.sendError : undefined)}
|
||||
>${stateLabel}</span
|
||||
>`
|
||||
: nothing}
|
||||
<span class="chat-queue__text" title=${text}>${text}</span>
|
||||
<span class="chat-queue__actions">
|
||||
${failed && props.onQueueRetry
|
||||
@@ -1154,7 +1163,14 @@ function renderChatQueueItem(item: ChatQueueItem, props: ChatQueueProps) {
|
||||
</openclaw-tooltip>
|
||||
`}
|
||||
</span>
|
||||
${item.sendError ? html`<span class="chat-queue__error">${item.sendError}</span>` : nothing}
|
||||
${
|
||||
// Reconnect rows auto-retry, so the raw transport error is noise there;
|
||||
// it stays inspectable via the badge tooltip. Failed/unconfirmed rows
|
||||
// keep the visible error because the user must act on them.
|
||||
item.sendError && !reconnecting
|
||||
? html`<span class="chat-queue__error">${item.sendError}</span>`
|
||||
: nothing
|
||||
}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -2670,6 +2670,24 @@ td.data-table-key-col {
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
/* Reconnect rows mirror the connection pill's amber status dot so the queue
|
||||
reads as quiet auto-retry status, not a failure needing action. */
|
||||
.chat-queue__dot {
|
||||
flex-shrink: 0;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
margin: 0 3.5px;
|
||||
border-radius: var(--radius-full);
|
||||
background: var(--warn);
|
||||
box-shadow: 0 0 8px color-mix(in srgb, var(--warn) 55%, transparent);
|
||||
animation: pulse-subtle 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.chat-queue__item--reconnect .chat-queue__badge {
|
||||
background: color-mix(in srgb, var(--warn) 14%, transparent);
|
||||
color: color-mix(in srgb, var(--warn) 78%, var(--text-strong));
|
||||
}
|
||||
|
||||
.chat-queue__badge {
|
||||
flex-shrink: 0;
|
||||
padding: 1px 7px;
|
||||
|
||||
Reference in New Issue
Block a user