Skip to content

UX improvement for chat window: Stop button, scroll bar fix and text box height increase#11266

Merged
SuZhou-Joe merged 3 commits into
opensearch-project:mainfrom
arjunkumargiri:chat-ux-improvement
Feb 12, 2026
Merged

UX improvement for chat window: Stop button, scroll bar fix and text box height increase#11266
SuZhou-Joe merged 3 commits into
opensearch-project:mainfrom
arjunkumargiri:chat-ux-improvement

Conversation

@arjunkumargiri

@arjunkumargiri arjunkumargiri commented Jan 29, 2026

Copy link
Copy Markdown
Contributor

Description

Chat box UX improvements:

  • Added stop button to stop response streaming
  • Scroll will not scroll down to bottom by default
  • Modified text box to text area with max height of 4 lines allowing users to view more text during input.

Screenshot

Screenshot 2026-01-28 at 5 31 49 PM Screenshot 2026-01-28 at 5 32 13 PM

Testing the changes

Local testing

Changelog

  • skip: UX improvement for chat window: Stop button, scroll bar fix and text box height increase

Check List

  • All tests pass
    • yarn test:jest
    • yarn test:jest_integration
  • New functionality includes testing.
  • New functionality has been documented.
  • Update CHANGELOG.md
  • Commits are signed per the DCO using --signoff

@github-actions

Copy link
Copy Markdown
Contributor

❌ Invalid Prefix For Manual Changeset Creation

Invalid description prefix. Found "feat". Only "skip" entry option is permitted for manual commit of changeset files.

If you were trying to skip the changelog entry, please use the "skip" entry option in the ##Changelog section of your PR description.

@coderabbitai

coderabbitai Bot commented Jan 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR converts the chat input from a single-line text field to a multiline textarea with auto-resizing capabilities, adds stop streaming functionality with subscription management, implements smart auto-scroll behavior in chat messages, and provides comprehensive test coverage for these components.

Changes

Cohort / File(s) Summary
Chat Input Component
src/plugins/chat/public/components/chat_input.tsx, src/plugins/chat/public/components/chat_input.scss, src/plugins/chat/public/components/chat_input.test.tsx
Replaced single-line input with multiline textarea (EuiTextArea) with auto-resize based on content, max height constraint, and custom scrollbar styling. Added onStop prop to handle stop streaming. Updated button behavior to toggle between send and stop icons based on streaming state. Includes new comprehensive test suite for rendering, input handling, button behavior, and accessibility.
Chat Messages Component
src/plugins/chat/public/components/chat_messages.tsx, src/plugins/chat/public/components/chat_messages.scss, src/plugins/chat/public/components/chat_messages.test.tsx
Introduced advanced auto-scroll behavior with user-scroll detection using container ref and proximity-to-bottom threshold. Scroll behavior now respects user scrolling up and prevents unwanted auto-scrolling. Updated styling to include positioning context. Comprehensive test suite covers rendering, scrolling logic, message types, tool calls, and suggestions.
Chat Window Component & Hooks
src/plugins/chat/public/components/chat_window.tsx, src/plugins/chat/public/components/chat_window.test.tsx, src/plugins/chat/public/hooks/use_command_menu_keyboard.ts
Added subscription tracking (currentSubscriptionRef) and handleStop function to abort streaming and manage subscription cleanup. Wired onStop to ChatInput. Updated inputRef type from HTMLInputElement to HTMLTextAreaElement in hook signature. New test suite covers stop streaming, subscription cleanup, and edge cases like multiple rapid stops.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant ChatInput as ChatInput UI
    participant ChatWindow as ChatWindow
    participant ChatService as ChatService
    participant Observable as Stream Observable

    User->>ChatInput: Clicks Stop button (during streaming)
    ChatInput->>ChatWindow: Calls onStop()
    ChatWindow->>ChatService: Calls chatService.abort()
    ChatService->>Observable: Triggers abort
    Observable-->>ChatWindow: Unsubscribe
    ChatWindow->>ChatWindow: Clears currentSubscriptionRef
    ChatWindow->>ChatWindow: Sets isStreaming = false
    ChatWindow->>ChatInput: Updates state (button switches to Send)
    ChatInput-->>User: Displays Send button
Loading
sequenceDiagram
    participant User as User
    participant ChatMessages as ChatMessages Container
    participant ScrollHandler as Scroll Event Handler
    participant AutoScroll as Auto-Scroll Logic

    User->>ChatMessages: Receives new message
    ChatMessages->>ScrollHandler: Triggers scroll listener
    ScrollHandler->>AutoScroll: Checks if user scrolled up
    alt User near bottom or hasn't scrolled
        AutoScroll->>ChatMessages: Scroll to bottom smoothly
        ChatMessages-->>User: Message visible at bottom
    else User scrolled up
        AutoScroll->>ChatMessages: Skip auto-scroll
        ChatMessages-->>User: Message appended but not scrolled into view
    end
    User->>ChatMessages: User scrolls down
    ScrollHandler->>AutoScroll: Re-enables auto-scroll
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

distinguished-contributor

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes all three main changes in the PR: stop button, scroll behavior fix, and textarea height increase.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The PR description covers all major required sections: description of changes, issues resolved (none applicable), screenshots, testing steps, and changelog entry.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added Skip-Changelog PRs that are too trivial to warrant a changelog or release notes entry and removed failed changeset labels Jan 29, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/plugins/chat/public/components/chat_input.test.tsx`:
- Around line 304-324: The tests fail because ChatInput binds handlers directly
via onClick={isStreaming ? onStop : onSend} and clicking when onStop/onSend is
undefined throws; update the ChatInput component (referencing the ChatInput
component and props onStop and onSend) to defensively call the callbacks (e.g.,
use a wrapper that checks for existence or provide no-op defaults) so the
button's click handler invokes onStop() or onSend() only if they are functions,
and add/update tests if you choose to enforce non-optional callbacks instead.

In `@src/plugins/chat/public/components/chat_window.tsx`:
- Around line 62-63: The stream stop path doesn't clear the "loading-"
placeholder because unsubscribing prevents error/complete callbacks; add a ref
to track the loading message id (e.g., loadingMessageIdRef alongside
currentSubscriptionRef) when you insert the "loading-" message, and ensure the
stop/unsubscribe handler (the function that cancels the current stream:
reference currentSubscriptionRef and the stop/unsubscribe function) explicitly
removes/clears that message id from the timeline state (call the existing
message removal/update logic) and nul­l out the ref; also clear it in any
cleanup effects so the "Thinking…" placeholder is always removed when a stream
is stopped.
🧹 Nitpick comments (5)
src/plugins/chat/public/components/chat_input.test.tsx (3)

145-152: Test doesn't verify the stated behavior.

The test is named "should show sortUp icon when not streaming" but it only checks that the button exists and is enabled. It doesn't actually verify the icon type.

Consider either renaming the test to match what it verifies, or adding actual icon verification:

💡 Option 1: Rename to match actual behavior
-    it('should show sortUp icon when not streaming', () => {
+    it('should show enabled send button when not streaming with input', () => {
💡 Option 2: Verify icon via data attribute or snapshot

If EUI exposes icon type through a data attribute or class, you could verify it directly. Otherwise, a snapshot test or visual regression test may be more appropriate for icon verification.


182-189: Test doesn't verify the stated behavior.

Similar to the send button test, this test claims to verify "stop icon" but only checks button existence and enabled state.

💡 Rename to match actual behavior
-    it('should show stop icon when streaming', () => {
+    it('should show enabled stop button when streaming', () => {

280-287: Autofocus test doesn't verify focus state.

The test claims to verify autofocus but only checks that the input element exists. It doesn't actually verify that the element is focused.

💡 Proposed fix to verify focus
     it('should have autofocus on input', () => {
       const { getByPlaceholderText } = render(<ChatInput {...defaultProps} />);
 
       const input = getByPlaceholderText('How can I help you today?') as HTMLTextAreaElement;
-      // Input should exist and be focused
-      expect(input).toBeTruthy();
+      expect(document.activeElement).toBe(input);
     });

Note: If jsdom doesn't properly handle autoFocus, you may need to verify the attribute instead:

expect(input).toHaveAttribute('autofocus');
src/plugins/chat/public/components/chat_messages.test.tsx (2)

79-128: Missing test coverage for smart scroll's "user scrolled up" behavior.

Based on the AI summary, the ChatMessages component has logic to detect when the user has scrolled up and should prevent auto-scroll. However, these tests only verify that scrollIntoView is called when new messages arrive.

Consider adding tests that:

  1. Simulate user scrolling up (fire scroll event with scrollTop not near bottom)
  2. Add new messages
  3. Verify scrollIntoView is NOT called (auto-scroll should be suppressed)

This would require mocking the scroll container's dimensions (scrollHeight, scrollTop, clientHeight) and dispatching scroll events. Example approach:

it('should not auto-scroll when user has scrolled up', () => {
  const { container, rerender } = render(<ChatMessages {...defaultProps} timeline={[]} />);
  
  const messagesContainer = container.querySelector('.chatMessages');
  // Mock scroll position as "not near bottom"
  Object.defineProperty(messagesContainer, 'scrollTop', { value: 0, writable: true });
  Object.defineProperty(messagesContainer, 'scrollHeight', { value: 500 });
  Object.defineProperty(messagesContainer, 'clientHeight', { value: 200 });
  
  fireEvent.scroll(messagesContainer!);
  jest.clearAllMocks();
  
  const newTimeline: Message[] = [{ id: '1', role: 'user', content: 'New message' }];
  rerender(<ChatMessages {...defaultProps} timeline={newTimeline} />);
  
  expect(Element.prototype.scrollIntoView).not.toHaveBeenCalled();
});

285-298: Test doesn't verify the stated behavior.

This test claims to verify that onResendMessage is passed correctly, but it only asserts that the callback wasn't called during render (which is expected). It doesn't actually verify the prop is passed to MessageRow.

Either remove this test or make it meaningful by verifying the prop is passed:

💡 Option 1: Use a mock that captures props
 jest.mock('./message_row', () => ({
-  MessageRow: ({ message }: any) => <div data-test-subj="message-row">{message.content}</div>,
+  MessageRow: jest.fn(({ message }: any) => <div data-test-subj="message-row">{message.content}</div>),
 }));

+import { MessageRow } from './message_row';

 // In test:
 it('should pass onResendMessage to MessageRow', () => {
   const onResendMessage = jest.fn();
   const timeline: Message[] = [{ id: '1', role: 'user', content: 'Message' }];

   render(<ChatMessages {...defaultProps} timeline={timeline} onResendMessage={onResendMessage} />);

   expect(MessageRow).toHaveBeenCalledWith(
     expect.objectContaining({ onResend: onResendMessage }),
     expect.anything()
   );
 });
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 18c88c8 and 449db16.

📒 Files selected for processing (9)
  • src/plugins/chat/public/components/chat_input.scss
  • src/plugins/chat/public/components/chat_input.test.tsx
  • src/plugins/chat/public/components/chat_input.tsx
  • src/plugins/chat/public/components/chat_messages.scss
  • src/plugins/chat/public/components/chat_messages.test.tsx
  • src/plugins/chat/public/components/chat_messages.tsx
  • src/plugins/chat/public/components/chat_window.test.tsx
  • src/plugins/chat/public/components/chat_window.tsx
  • src/plugins/chat/public/hooks/use_command_menu_keyboard.ts
🧰 Additional context used
🧬 Code graph analysis (2)
src/plugins/chat/public/components/chat_input.test.tsx (1)
src/plugins/chat/public/components/chat_input.tsx (1)
  • ChatInput (24-107)
src/plugins/chat/public/components/chat_window.test.tsx (1)
src/plugins/chat/public/components/chat_window.tsx (2)
  • ChatWindowInstance (30-33)
  • ChatWindow (44-46)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (69)
  • GitHub Check: Run functional tests on Windows (ciGroup6)
  • GitHub Check: Run functional tests on Windows (ciGroup11)
  • GitHub Check: Run functional tests on Windows (ciGroup5)
  • GitHub Check: Run functional tests on Windows (ciGroup12)
  • GitHub Check: Run functional tests on Windows (ciGroup10)
  • GitHub Check: Run functional tests on Windows (ciGroup8)
  • GitHub Check: Run functional tests on Windows (ciGroup7)
  • GitHub Check: Run functional tests on Windows (ciGroup13)
  • GitHub Check: Run functional tests on Windows (ciGroup3)
  • GitHub Check: Run functional tests on Linux (ciGroup12)
  • GitHub Check: Run functional tests on Windows (ciGroup9)
  • GitHub Check: Run functional tests on Windows (ciGroup1)
  • GitHub Check: Run functional tests on Windows (ciGroup4)
  • GitHub Check: Run functional tests on Linux (ciGroup8)
  • GitHub Check: Run functional tests on Linux (ciGroup13)
  • GitHub Check: Run functional tests on Windows (ciGroup2)
  • GitHub Check: Run functional tests on Linux (ciGroup7)
  • GitHub Check: Run functional tests on Linux (ciGroup10)
  • GitHub Check: Run functional tests on Linux (ciGroup11)
  • GitHub Check: Run functional tests on Linux (ciGroup9)
  • GitHub Check: Run functional tests on Linux (ciGroup3)
  • GitHub Check: Run functional tests on Linux (ciGroup5)
  • GitHub Check: Run functional tests on Linux (ciGroup6)
  • GitHub Check: Run functional tests on Linux (ciGroup2)
  • GitHub Check: Run functional tests on Linux (ciGroup1)
  • GitHub Check: Run functional tests on Linux (ciGroup4)
  • GitHub Check: Build and Verify on Windows (ciGroup3)
  • GitHub Check: Build and Verify on Linux (ciGroup4)
  • GitHub Check: Build and Verify on Windows (ciGroup4)
  • GitHub Check: Build and Verify on Linux (ciGroup1)
  • GitHub Check: Build and Verify on Linux (ciGroup3)
  • GitHub Check: Build and Verify on Windows (ciGroup1)
  • GitHub Check: Build and Verify on Linux (ciGroup2)
  • GitHub Check: Run plugin functional tests on Linux
  • GitHub Check: Build min release artifacts on macOS x64
  • GitHub Check: Build and Verify on Windows (ciGroup2)
  • GitHub Check: bundle-analyzer
  • GitHub Check: Build min release artifacts on Linux ARM64
  • GitHub Check: Build min release artifacts on macOS ARM64
  • GitHub Check: Build min release artifacts on Linux x64
  • GitHub Check: Build min release artifacts on Windows x64
  • GitHub Check: Run plugin functional tests on Windows
  • GitHub Check: Lint and validate
  • GitHub Check: Run cypress tests (osd:ciGroup8)
  • GitHub Check: Run cypress tests (osd:ciGroup14Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup16Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup15)
  • GitHub Check: Run cypress tests (osd:ciGroup17Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup12Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup11)
  • GitHub Check: Run cypress tests (osd:ciGroup14)
  • GitHub Check: Run cypress tests (osd:ciGroup10Slow)
  • GitHub Check: Run cypress tests (osd:ciGroup3)
  • GitHub Check: Run cypress tests (osd:ciGroup6)
  • GitHub Check: Run cypress tests (osd:ciGroup9)
  • GitHub Check: Run cypress tests (osd:ciGroup7)
  • GitHub Check: Run cypress tests (osd:ciGroup5)
  • GitHub Check: Run cypress tests (osd:ciGroup1)
  • GitHub Check: Run cypress tests (osd:ciGroup13)
  • GitHub Check: Run cypress tests (osd:ciGroup12)
  • GitHub Check: Run cypress tests (osd:ciGroup4)
  • GitHub Check: Run cypress tests (osd:ciGroup10Fast)
  • GitHub Check: Run cypress tests (osd:ciGroup10Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup15Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup13Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup2)
  • GitHub Check: lighthouse
  • GitHub Check: linkchecker
  • GitHub Check: WhiteSource Security Check
🔇 Additional comments (18)
src/plugins/chat/public/components/chat_messages.scss (1)

8-8: Positioning context + keyframe cleanup look good.
Adding a relative positioning context should help any absolutely positioned children, and the keyframe formatting preserves behavior. A quick visual pass to confirm the fade-in still matches expectations would be enough.

Also applies to: 47-54

src/plugins/chat/public/components/chat_input.scss (1)

1-64: Textarea + ghost text styling aligns well with the multiline UX.
Min/max height, padding, and overflow settings look consistent. Please do a quick UI check to confirm the 4‑line max height and scrollbar appearance across browsers.

src/plugins/chat/public/components/chat_window.test.tsx (2)

42-43: scrollIntoView mock is a good safety net for jsdom.
Keeps the test environment stable when the API is missing.


688-1042: Stop‑streaming test coverage is thorough.
Nice coverage of abort/unsubscribe flows and post‑stop messaging. Please ensure the suite runs cleanly in CI (or run the focused test locally).

src/plugins/chat/public/components/chat_messages.tsx (1)

6-127: Auto‑scroll locking + near‑bottom detection look solid.
Should prevent unexpected jumps while keeping the view pinned when appropriate; the shorter empty‑state copy is fine too. Please QA: scroll up, receive new messages (no auto‑jump), then scroll near bottom (auto‑scroll resumes).

Also applies to: 155-161

src/plugins/chat/public/hooks/use_command_menu_keyboard.ts (1)

9-14: inputRef type update correctly aligns with textarea implementation.
Verified that all call sites properly create and pass HTMLTextAreaElement refs. The change is type-safe and consistent.

src/plugins/chat/public/components/chat_input.test.tsx (4)

1-46: Well-structured test setup with appropriate mocks.

The mocks for child components and the hook are properly configured, and the defaultProps setup with beforeEach cleanup follows good testing practices.


48-74: LGTM!

Rendering tests properly verify the presence of key UI elements under different states.


76-109: LGTM!

Input handling tests correctly verify the onChange callback, value display, and disabled state based on streaming status.


213-245: LGTM!

Button state transition tests properly verify bidirectional changes using rerender and both positive/negative assertions.

src/plugins/chat/public/components/chat_messages.test.tsx (4)

1-44: Well-organized test setup with appropriate mocks.

The mocks for child components and scrollIntoView are properly configured. The defaultProps pattern is clean and follows testing best practices.


130-183: LGTM!

Good coverage of different message types including the loading state variations and special handling of tool messages.


185-283: LGTM!

Tool calls and suggestions tests provide good coverage of conditional rendering logic based on message types and streaming state.


300-333: LGTM!

Cleanup and accessibility tests verify basic component lifecycle and DOM structure.

src/plugins/chat/public/components/chat_input.tsx (4)

6-7: LGTM!

Clean imports for the new functionality - useEffect for auto-resize and EuiTextArea for multiline input.


50-60: Auto-resize implementation looks correct.

The technique of resetting to 'auto' before reading scrollHeight is the standard approach. The 96px max height aligns with the PR requirement of ~4 lines.

One minor note: If you want to make the max height more maintainable, consider extracting to a constant:

const MAX_TEXTAREA_HEIGHT = 96; // ~4 lines at default line-height

95-103: Button behavior is well-implemented.

The conditional logic correctly:

  • Enables the stop button during streaming regardless of input
  • Disables the send button only when empty and not streaming
  • Switches icons, colors, and aria-labels appropriately

74-85: LGTM!

The EuiTextArea configuration is appropriate:

  • resize="none" correctly prevents manual resize since JS handles it
  • rows={1} provides a compact initial state
  • disabled={isStreaming} prevents input during streaming

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +304 to +324
it('should handle empty onStop callback', () => {
const { getByLabelText } = render(
<ChatInput {...defaultProps} isStreaming={true} onStop={undefined as any} />
);

const button = getByLabelText('Stop generating');

// Should not throw when clicking with undefined callback
expect(() => fireEvent.click(button)).not.toThrow();
});

it('should handle empty onSend callback', () => {
const { getByLabelText } = render(
<ChatInput {...defaultProps} input="test" onSend={undefined as any} />
);

const button = getByLabelText('Send message');

// Should not throw when clicking with undefined callback
expect(() => fireEvent.click(button)).not.toThrow();
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Edge case tests may fail - component doesn't guard against undefined callbacks.

Looking at the ChatInput implementation (line 97), the click handler directly calls onStop or onSend:

onClick={isStreaming ? onStop : onSend}

If these props are undefined, clicking the button will throw TypeError: onStop is not a function. Either:

  1. The tests will fail (and should be removed if undefined callbacks aren't a valid use case), or
  2. The component should add defensive checks:
🛡️ Proposed fix in chat_input.tsx if undefined callbacks should be supported
         <EuiButtonIcon
           iconType={isStreaming ? 'stop' : 'sortUp'}
-          onClick={isStreaming ? onStop : onSend}
+          onClick={isStreaming ? onStop : onSend}
+          onClick={() => {
+            if (isStreaming) {
+              onStop?.();
+            } else {
+              onSend?.();
+            }
+          }}

If undefined callbacks are not a valid use case, consider removing these tests to avoid confusion.

🤖 Prompt for AI Agents
In `@src/plugins/chat/public/components/chat_input.test.tsx` around lines 304 -
324, The tests fail because ChatInput binds handlers directly via
onClick={isStreaming ? onStop : onSend} and clicking when onStop/onSend is
undefined throws; update the ChatInput component (referencing the ChatInput
component and props onStop and onSend) to defensively call the callbacks (e.g.,
use a wrapper that checks for existence or provide no-op defaults) so the
button's click handler invokes onStop() or onSend() only if they are functions,
and add/update tests if you choose to enforce non-optional callbacks instead.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you fix this

Comment thread src/plugins/chat/public/components/chat_window.tsx
@codecov

codecov Bot commented Jan 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 65.07937% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.17%. Comparing base (527cb08) to head (cdd6f9f).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...c/plugins/chat/public/components/chat_messages.tsx 42.10% 17 Missing and 5 partials ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main   #11266   +/-   ##
=======================================
  Coverage   60.16%   60.17%           
=======================================
  Files        4652     4652           
  Lines      129576   129634   +58     
  Branches    22034    22049   +15     
=======================================
+ Hits        77954    78001   +47     
- Misses      46067    46074    +7     
- Partials     5555     5559    +4     
Flag Coverage Δ
Linux_1 24.80% <ø> (ø)
Linux_2 38.29% <ø> (ø)
Linux_3 40.07% <65.07%> (+0.03%) ⬆️
Linux_4 33.50% <ø> (+<0.01%) ⬆️
Windows_1 24.83% <ø> (ø)
Windows_2 38.27% <ø> (ø)
Windows_3 40.07% <65.07%> (+0.03%) ⬆️
Windows_4 33.50% <ø> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment on lines +1 to +2
@import "@elastic/eui/src/global_styling/variables";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need to import this

Comment thread src/plugins/chat/public/components/chat_input.scss
Comment on lines -62 to +76
placeholder="Ask anything. Type / for actions"
placeholder="How can I help you today?"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why we changed this placeholder?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Existing placeholder seems incorrect. I don't think '/' for actions is suggested yet.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have added a / command system for investigation with /investigation and there will more command next, i think we need to keep it


// Update streaming state
setIsStreaming(false);
}, [chatService]);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the behavior stop the response in middle? should we clean the incomplete message for next round of llm call or keep it whatever it is? can we have a test about this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If stop is pressed in the middle of streaming, then the content is retained as is with incomplete message. This is the existing behavior in other LLM chat UI such as claude. There is existing test case to cover this scenario.

@Hailong-am Hailong-am Jan 30, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so for next round LLM call, we will send the incomplete message to LLM? For now, it works. When we support store the conversation history and persist the conversation data, there will have a inconsistency between UI and the storage side. And agent side need to support stop as well

@arjunkumargiri arjunkumargiri force-pushed the chat-ux-improvement branch 2 times, most recently from a5e72bc to 5c73724 Compare January 29, 2026 22:17
…box height increase

Signed-off-by: Arjun kumar Giri <arjung@amazon.com>
@kamingleung

Copy link
Copy Markdown
Contributor

@sicheng-lu, can you work with @arjunkumargiri to review the UX improvements before merging. Thanks.

@sicheng-lu

Copy link
Copy Markdown

Stop button looks good. Is the textfield still accessible in the stop button state?

@arjunkumargiri

Copy link
Copy Markdown
Contributor Author

Stop button looks good. Is the textfield still accessible in the stop button state?

No, it could be accessed only after streaming is stopped.

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>
SuZhou-Joe
SuZhou-Joe previously approved these changes Feb 12, 2026

@SuZhou-Joe SuZhou-Joe left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#11328

Similar PR for stop agent execution, will consolidate the PRs.

wanglam
wanglam previously approved these changes Feb 12, 2026
Signed-off-by: SuZhou-Joe <suzhou@amazon.com>
@SuZhou-Joe SuZhou-Joe dismissed stale reviews from wanglam and themself via cdd6f9f February 12, 2026 03:37
@SuZhou-Joe SuZhou-Joe merged commit bdb31af into opensearch-project:main Feb 12, 2026
105 of 109 checks passed
markdboyd pushed a commit to cloud-gov/OpenSearch-Dashboards that referenced this pull request Mar 9, 2026
…box height increase (opensearch-project#11266)

* UX improvement for chat window: Stop button, scroll bar fix and text box height increase

Signed-off-by: Arjun kumar Giri <arjung@amazon.com>

* feat: fix UT

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

---------

Signed-off-by: Arjun kumar Giri <arjung@amazon.com>
Signed-off-by: SuZhou-Joe <suzhou@amazon.com>
Co-authored-by: SuZhou-Joe <suzhou@amazon.com>
Signed-off-by: Mark Boyd <mark.boyd@gsa.gov>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

repeat-contributor Skip-Changelog PRs that are too trivial to warrant a changelog or release notes entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants