Merge "Improve chat error UI and add retry button"
diff --git a/polygerrit-ui/app/elements/chat-panel/chat-panel_screenshot_test.ts b/polygerrit-ui/app/elements/chat-panel/chat-panel_screenshot_test.ts
index 90d7e6a..9c16d2f 100644
--- a/polygerrit-ui/app/elements/chat-panel/chat-panel_screenshot_test.ts
+++ b/polygerrit-ui/app/elements/chat-panel/chat-panel_screenshot_test.ts
@@ -178,6 +178,32 @@
await visualDiffDarkTheme(element, 'chat-panel-chat-mode-with-comment');
});
+ test('chat mode with error', async () => {
+ chatModel.updateState({
+ ...chatModel.getState(),
+ turns: [
+ {
+ userMessage: {
+ content: 'Do something',
+ userType: UserType.USER,
+ contextItems: [],
+ },
+ geminiMessage: {
+ responseParts: [],
+ regenerationIndex: 0,
+ references: [],
+ citations: [],
+ userType: UserType.GEMINI,
+ errorMessage: 'Something went wrong',
+ },
+ },
+ ] as Turn[],
+ });
+ await element.updateComplete;
+ await visualDiff(element, 'chat-panel-chat-mode-with-error');
+ await visualDiffDarkTheme(element, 'chat-panel-chat-mode-with-error');
+ });
+
test('chat mode with references', async () => {
chatModel.updateState({
...chatModel.getState(),
diff --git a/polygerrit-ui/app/elements/chat-panel/gemini-message.ts b/polygerrit-ui/app/elements/chat-panel/gemini-message.ts
index 0b2e4fb..eb399b8 100644
--- a/polygerrit-ui/app/elements/chat-panel/gemini-message.ts
+++ b/polygerrit-ui/app/elements/chat-panel/gemini-message.ts
@@ -97,7 +97,34 @@
margin-left: 10px;
}
.server-error {
- font-weight: bold;
+ display: flex;
+ align-items: center;
+ gap: var(--spacing-s);
+ font-weight: 500;
+ color: var(--error-foreground);
+ margin-bottom: var(--spacing-s);
+ }
+ .error-icon {
+ color: var(--error-foreground);
+ }
+ .error-message {
+ margin-bottom: var(--spacing-m);
+ color: var(--deemphasized-text-color);
+ }
+ .error-details {
+ margin-top: var(--spacing-s);
+ margin-bottom: var(--spacing-s);
+ font-family: var(--monospace-font-family);
+ font-size: var(--font-size-small);
+ white-space: pre-wrap;
+ background-color: var(--background-color-tertiary);
+ padding: var(--spacing-s);
+ border-radius: var(--border-radius);
+ }
+ .error-actions {
+ display: flex;
+ gap: var(--spacing-m);
+ margin-top: var(--spacing-s);
}
.user-info {
margin-bottom: var(--spacing-m);
@@ -179,6 +206,10 @@
this.getCommentsModel().reloadAllComments();
}
+ private onRetry() {
+ this.getChatModel().regenerateMessage(this.turnId());
+ }
+
private toggleShowErrorDetails() {
this.showErrorDetails = !this.showErrorDetails;
}
@@ -210,24 +241,23 @@
${when(
message.errorMessage,
() => html`
- <p class="server-error text-content">Server issue.</p>
- <p class="error-message">
- We were unable to fulfill your request for this due to a server
- issue. Please reload the webpage to try again.
- </p>
- <md-text-button
- @click=${() => this.toggleShowErrorDetails()}
- class="error-details-button"
- >
- <gr-icon
- icon=${this.showErrorDetails ? 'expand_less' : 'expand_more'}
- ></gr-icon>
- Details
- </md-text-button>
- ${when(
- this.showErrorDetails,
- () => html`<p class="error-details">${message.errorMessage}</p>`
- )}
+ <div class="server-error text-content">
+ <gr-icon icon="error" class="error-icon"></gr-icon>
+ Server error
+ </div>
+ <div class="error-message">
+ We were unable to fulfill your request.
+ ${when(
+ this.showErrorDetails,
+ () => html`<p class="error-details">${message.errorMessage}</p>`
+ )}
+ <div class="error-actions">
+ <gr-button @click=${() => this.onRetry()} link>Retry</gr-button>
+ <gr-button @click=${() => this.toggleShowErrorDetails()} link>
+ ${this.showErrorDetails ? 'Hide details' : 'Show details'}
+ </gr-button>
+ </div>
+ </div>
`
)}
${when(!message.errorMessage && responseParts.length === 0, () =>
diff --git a/polygerrit-ui/app/elements/chat-panel/gemini-message_test.ts b/polygerrit-ui/app/elements/chat-panel/gemini-message_test.ts
index 1edeb95..998e8db 100644
--- a/polygerrit-ui/app/elements/chat-panel/gemini-message_test.ts
+++ b/polygerrit-ui/app/elements/chat-panel/gemini-message_test.ts
@@ -133,7 +133,21 @@
const error = element.shadowRoot?.querySelector('.server-error');
assert.isOk(error);
- assert.equal(error?.textContent, 'Server issue.');
+ assert.include(error?.textContent, 'Server error');
+
+ const retryButton = element.shadowRoot?.querySelector(
+ 'gr-button'
+ ) as HTMLElement;
+ assert.isOk(retryButton);
+ assert.equal(retryButton.textContent, 'Retry');
+
+ const spy = sinon.spy(chatModel, 'regenerateMessage');
+ retryButton.click();
+ assert.isTrue(spy.calledOnce);
+ assert.deepEqual(spy.firstCall.args[0], {
+ turnIndex: 0,
+ regenerationIndex: 0,
+ });
});
test('renders suggested comment', async () => {
diff --git a/polygerrit-ui/screenshots/Chromium/baseline/chat-panel-chat-mode-with-error-dark.png b/polygerrit-ui/screenshots/Chromium/baseline/chat-panel-chat-mode-with-error-dark.png
new file mode 100644
index 0000000..c2d1f08
--- /dev/null
+++ b/polygerrit-ui/screenshots/Chromium/baseline/chat-panel-chat-mode-with-error-dark.png
Binary files differ
diff --git a/polygerrit-ui/screenshots/Chromium/baseline/chat-panel-chat-mode-with-error.png b/polygerrit-ui/screenshots/Chromium/baseline/chat-panel-chat-mode-with-error.png
new file mode 100644
index 0000000..9677c0f
--- /dev/null
+++ b/polygerrit-ui/screenshots/Chromium/baseline/chat-panel-chat-mode-with-error.png
Binary files differ