Skip to content

[Chat] feat: update chat-header look & feel#11330

Merged
SuZhou-Joe merged 2 commits intoopensearch-project:mainfrom
SuZhou-Joe:feature/chat-header
Feb 12, 2026
Merged

[Chat] feat: update chat-header look & feel#11330
SuZhou-Joe merged 2 commits intoopensearch-project:mainfrom
SuZhou-Joe:feature/chat-header

Conversation

@SuZhou-Joe
Copy link
Copy Markdown
Member

@SuZhou-Joe SuZhou-Joe commented Feb 12, 2026

Description

Update chat header look & feel.

Issues Resolved

Screenshot

20260212112608473.mp4

Testing the changes

Changelog

  • feat: update chat-header look & feel

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

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 12, 2026

📝 Walkthrough

Walkthrough

The pull request refactors the chat header component by removing layout mode state management and toggling functionality, replacing fixed title displays with an optional conversation name derived from chat history. SCSS styling is updated for improved spacing and visual hierarchy. The changes span header rendering logic, button behavior simplification, and comprehensive tests for conversation name extraction.

Changes

Cohort / File(s) Summary
Changelog
changelogs/fragments/11330.yml
Documents feature update to chat header styling and UX.
Chat Header Styling and Component Logic
src/plugins/chat/public/components/chat_header.scss, src/plugins/chat/public/components/chat_header.tsx
Removes border-bottom and fixed "Ask AI" title; adds gap/overflow adjustments and ellipsis handling. ChatHeaderProps modified: removes layoutMode and onToggleLayout, adds optional conversationName. Header now renders icon and dynamically displays conversation name.
Layout Mode Removal
src/plugins/chat/public/components/chat_header_button.tsx, src/plugins/chat/public/components/chat_window.tsx
Removes dynamic layout state and toggle logic from ChatHeaderButton; always renders ChatWindow with SIDECAR mode. ChatWindowProps removes onToggleLayout prop; passes conversationName to ChatHeader derived from timeline data.
Tests
src/plugins/chat/public/components/chat_header_button.test.tsx, src/plugins/chat/public/components/chat_window_conversation_name.test.tsx
Updates existing test to remove getWindowMode assertion; adds comprehensive new test suite validating conversation name extraction from various message scenarios (empty timeline, text content, binary content, whitespace handling, long messages, dynamic updates).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested labels

ai, v3.4.0

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is incomplete with missing required sections: no screenshot provided despite UI changes, no testing instructions, no linked issues, and checklist items are unchecked. Add a screenshot demonstrating the chat header updates, provide detailed testing steps to validate the changes, link any related issues using 'closes' or 'fixes', and verify checklist items before merge.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: updating the chat-header component's visual appearance and styling.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 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.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

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_header.tsx`:
- Around line 31-40: Replace nonstandard OUI icon names used in the chat header
components: update the EuiIcon instance using type="chatLeft" (in the ChatHeader
render) to a valid OUI icon name (e.g., "chat" or another supported chat-related
icon) and update the EuiButtonIcon usage that uses "documentEdit" to either
"document" or "edit" (or split into separate icons) or register a custom icon if
you require a combined glyph; ensure you change the type prop on the EuiIcon and
EuiButtonIcon elements (referenced as EuiIcon and EuiButtonIcon in this file) to
valid OUI icon names or to a custom-registered icon name so the icons render
correctly.

In `@src/plugins/chat/public/components/chat_window_conversation_name.test.tsx`:
- Around line 233-267: The test fails because reuse of the same mockChatService
doesn't retrigger the restoreTimeline effect (dependencies chatService and
eventHandler are stable), so changing mockChatService.getCurrentMessages on
rerender won't populate timeline or conversationName; to fix, simulate a real
timeline update instead of swapping the mock return: in the test after mocking
messages, invoke the same event/handler that restoreTimeline subscribes to (or
directly call the setTimeline/eventHandler callback used by restoreTimeline) so
the component updates its timeline and recomputes conversationName (refer to
restoreTimeline, useMemo -> conversationName, setTimeline, and ChatWindow to
locate the logic to call).
🧹 Nitpick comments (2)
src/plugins/chat/public/components/chat_header.scss (1)

41-44: Dead CSS: __experimentalBadge is no longer used.

The EuiBadge and "Experimental" badge were removed from chat_header.tsx, but these styles remain. Consider removing them to avoid confusion.

🧹 Remove unused styles
-  &__experimentalBadge {
-    font-size: 10px;
-    padding: 2px 6px;
-  }
src/plugins/chat/public/components/chat_window_conversation_name.test.tsx (1)

44-70: any usage in mock declarations.

The coding guidelines advise avoiding any. While as any on mocks is pragmatic, you could use partial type utilities like Partial<ChatService> or more specific mock types to reduce any usage.

As per coding guidelines, "Use TypeScript for all new code; avoid any type (use unknown or generics instead)".

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 527cb08 and 609e232.

📒 Files selected for processing (7)
  • changelogs/fragments/11330.yml
  • src/plugins/chat/public/components/chat_header.scss
  • src/plugins/chat/public/components/chat_header.tsx
  • src/plugins/chat/public/components/chat_header_button.test.tsx
  • src/plugins/chat/public/components/chat_header_button.tsx
  • src/plugins/chat/public/components/chat_window.tsx
  • src/plugins/chat/public/components/chat_window_conversation_name.test.tsx
💤 Files with no reviewable changes (1)
  • src/plugins/chat/public/components/chat_header_button.test.tsx
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js,jsx,json,scss,css,html,yml,yaml}

📄 CodeRabbit inference engine (CLAUDE.md)

Use snake_case for all filenames

Files:

  • src/plugins/chat/public/components/chat_header_button.tsx
  • changelogs/fragments/11330.yml
  • src/plugins/chat/public/components/chat_header.scss
  • src/plugins/chat/public/components/chat_window.tsx
  • src/plugins/chat/public/components/chat_window_conversation_name.test.tsx
  • src/plugins/chat/public/components/chat_header.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript for all new code; avoid any type (use unknown or generics instead)
Avoid non-null assertions (!.) and @ts-ignore comments
HTML attributes: id and data-test-subj values should be camelCase
Import .scss files at the top of the component file and use 3-letter prefix on class names for scoping (e.g., plgComponent)
Prefer functional components in React and name action props as on<Subject><Change>

Files:

  • src/plugins/chat/public/components/chat_header_button.tsx
  • src/plugins/chat/public/components/chat_window.tsx
  • src/plugins/chat/public/components/chat_window_conversation_name.test.tsx
  • src/plugins/chat/public/components/chat_header.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Use named exports, not default exports
Use ES2015 import/export syntax; only import top-level module APIs, never reach into internal paths
Use single quotes for strings with 100-character print width and ES5 trailing commas (enforced by Prettier)

Files:

  • src/plugins/chat/public/components/chat_header_button.tsx
  • src/plugins/chat/public/components/chat_window.tsx
  • src/plugins/chat/public/components/chat_window_conversation_name.test.tsx
  • src/plugins/chat/public/components/chat_header.tsx
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Unit tests must achieve 80%+ code coverage (enforced by Codecov); use react-testing-library for components, not enzyme snapshots

Files:

  • src/plugins/chat/public/components/chat_window_conversation_name.test.tsx
🧬 Code graph analysis (2)
src/plugins/chat/public/components/chat_header_button.tsx (2)
src/core/public/index.ts (1)
  • SIDECAR_DOCKED_MODE (230-230)
src/plugins/chat/public/services/chat_service.ts (1)
  • isWindowOpen (126-131)
src/plugins/chat/public/components/chat_window_conversation_name.test.tsx (3)
src/plugins/chat/public/services/confirmation_service.ts (1)
  • ConfirmationService (27-139)
src/plugins/chat/public/contexts/chat_context.tsx (1)
  • ChatProvider (26-37)
src/plugins/chat/public/components/chat_window.tsx (1)
  • ChatWindow (43-45)
⏰ 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). (67)
  • GitHub Check: Run functional tests on Windows (ciGroup8)
  • GitHub Check: Run functional tests on Windows (ciGroup5)
  • GitHub Check: Run functional tests on Windows (ciGroup10)
  • GitHub Check: Run functional tests on Windows (ciGroup12)
  • GitHub Check: Run functional tests on Windows (ciGroup2)
  • GitHub Check: Run functional tests on Windows (ciGroup13)
  • GitHub Check: Run functional tests on Windows (ciGroup9)
  • GitHub Check: Run functional tests on Windows (ciGroup11)
  • GitHub Check: Run functional tests on Linux (ciGroup6)
  • GitHub Check: Run functional tests on Windows (ciGroup3)
  • GitHub Check: Run functional tests on Windows (ciGroup6)
  • GitHub Check: Run functional tests on Linux (ciGroup2)
  • GitHub Check: Run functional tests on Windows (ciGroup4)
  • GitHub Check: Run functional tests on Linux (ciGroup12)
  • GitHub Check: Run functional tests on Windows (ciGroup7)
  • GitHub Check: Run functional tests on Linux (ciGroup10)
  • GitHub Check: Run functional tests on Linux (ciGroup11)
  • GitHub Check: Run functional tests on Linux (ciGroup8)
  • GitHub Check: Run functional tests on Linux (ciGroup4)
  • GitHub Check: Run functional tests on Linux (ciGroup9)
  • GitHub Check: Run functional tests on Linux (ciGroup5)
  • GitHub Check: Run functional tests on Linux (ciGroup13)
  • GitHub Check: Run functional tests on Linux (ciGroup3)
  • GitHub Check: Run functional tests on Linux (ciGroup7)
  • GitHub Check: Run functional tests on Linux (ciGroup1)
  • GitHub Check: Run functional tests on Windows (ciGroup1)
  • GitHub Check: Build and Verify on Windows (ciGroup3)
  • GitHub Check: Build and Verify on Linux (ciGroup2)
  • GitHub Check: Build and Verify on Windows (ciGroup4)
  • GitHub Check: Build and Verify on Linux (ciGroup4)
  • GitHub Check: Build and Verify on Linux (ciGroup3)
  • GitHub Check: Build and Verify on Windows (ciGroup1)
  • GitHub Check: Build and Verify on Linux (ciGroup1)
  • GitHub Check: Build min release artifacts on macOS ARM64
  • GitHub Check: Build min release artifacts on Linux ARM64
  • GitHub Check: Build and Verify on Windows (ciGroup2)
  • GitHub Check: Build min release artifacts on macOS x64
  • GitHub Check: Build min release artifacts on Windows x64
  • GitHub Check: Build min release artifacts on Linux x64
  • GitHub Check: Run cypress tests (osd:ciGroup1)
  • GitHub Check: Lint and validate
  • GitHub Check: bundle-analyzer
  • GitHub Check: Run cypress tests (osd:ciGroup16Explore)
  • GitHub Check: Run plugin functional tests on Linux
  • GitHub Check: Run plugin functional tests on Windows
  • GitHub Check: Run cypress tests (osd:ciGroup15Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup14)
  • GitHub Check: Run cypress tests (osd:ciGroup14Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup10Slow)
  • GitHub Check: Run cypress tests (osd:ciGroup7)
  • GitHub Check: Run cypress tests (osd:ciGroup13)
  • GitHub Check: Run cypress tests (osd:ciGroup10Fast)
  • GitHub Check: Run cypress tests (osd:ciGroup8)
  • GitHub Check: Run cypress tests (osd:ciGroup11)
  • GitHub Check: Run cypress tests (osd:ciGroup17Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup3)
  • GitHub Check: Run cypress tests (osd:ciGroup13Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup15)
  • GitHub Check: Run cypress tests (osd:ciGroup12Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup2)
  • GitHub Check: Run cypress tests (osd:ciGroup9)
  • GitHub Check: Run cypress tests (osd:ciGroup10Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup12)
  • GitHub Check: Run cypress tests (osd:ciGroup5)
  • GitHub Check: Run cypress tests (osd:ciGroup6)
  • GitHub Check: Run cypress tests (osd:ciGroup4)
  • GitHub Check: lighthouse
🔇 Additional comments (9)
src/plugins/chat/public/components/chat_header.tsx (1)

10-15: Clean prop interface simplification.

The removal of layoutMode and onToggleLayout in favor of an optional conversationName simplifies this component's API surface nicely. The default value of '' ensures the title section is not rendered when no conversation exists.

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

1-32: Well-structured overflow handling for the title.

The min-width: 0 on both __titleGroup and __titleContainer, combined with text-overflow: ellipsis on __title, correctly handles long conversation names in a flex layout.

changelogs/fragments/11330.yml (1)

1-2: Changelog entry looks good.

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

357-378: Conversation name extraction logic is solid.

The useMemo correctly iterates timeline to find the first user message with meaningful text content, handling both string and array content types. Whitespace-only and binary-only messages are properly skipped.


385-392: Integration with ChatHeader looks correct.

The conversationName is properly derived and passed down, replacing the previous onToggleLayout prop.

src/plugins/chat/public/components/chat_header_button.tsx (3)

66-86: Sidecar config simplification looks good.

Hardcoding SIDECAR_DOCKED_MODE.RIGHT and a fixed className removes unnecessary complexity from layout toggling. The dependency array is correctly trimmed.


117-126: Window state listener correctly simplified.

Only tracking isWindowOpen now that windowMode is no longer needed.


29-32: No action needed—ChatLayoutMode.FULLSCREEN is actively used.

The FULLSCREEN enum variant is referenced in chat_service.ts (line 145, where it's returned when windowMode is not 'sidecar') and validated in plugin.ts (line 34, as part of the window state validation). The enum should be retained.

Likely an incorrect or invalid review comment.

src/plugins/chat/public/components/chat_window_conversation_name.test.tsx (1)

89-231: Good test coverage for the core extraction scenarios.

The tests thoroughly cover string content, array content, binary-only messages, assistant-first timelines, and whitespace-only messages. The CSS truncation test (Lines 213-231) pragmatically verifies the class is applied without trying to assert computed styles.

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

Comment on lines 31 to +40
<EuiFlexItem grow={false}>
<EuiText size="m">
<h3>Ask AI</h3>
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiBadge color="warning" className="chatHeader__experimentalBadge">
Experimental
</EuiBadge>
<EuiIcon type="chatLeft" size="m" className="chatHeader__chatIcon" />
</EuiFlexItem>
{conversationName && (
<EuiFlexItem grow={true} className="chatHeader__titleContainer">
<EuiText size="m">
<h3 className="chatHeader__title">{conversationName}</h3>
</EuiText>
</EuiFlexItem>
)}
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 | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check the EUI version in package.json
find . -name "package.json" -path "*/package.json" | head -5 | xargs grep -l "@elastic/eui" | head -1 | xargs cat | grep -A2 "@elastic/eui"

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 359


🏁 Script executed:

# Search for chatLeft and documentEdit icon references
rg -n "chatLeft|documentEdit" --type=ts --type=tsx -g '!node_modules' | head -20

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 111


🏁 Script executed:

# Check if there are any custom icon definitions or registrations
rg -n "icon.*register|customIcon|registerIcon" --type=ts --type=tsx -g '!node_modules' | head -20

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 111


🏁 Script executed:

# Look at the chat_header.tsx file to see the full context
cat -n src/plugins/chat/public/components/chat_header.tsx

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 2075


🏁 Script executed:

# Search for icon type definitions or icon lists in the codebase
rg "chatLeft|documentEdit" -i --max-count=20

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 299


🏁 Script executed:

# Check node_modules for OUI icon types (if available)
find . -path "*/node_modules/@opensearch-project/oui*" -name "*.d.ts" 2>/dev/null | grep -i icon | head -5

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 66


🏁 Script executed:

# Search for other icon usages in the codebase to see what's common
rg "type=\"[a-zA-Z]+" -o | sort | uniq -c | sort -rn | head -20

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 2856


🏁 Script executed:

# Look for the EuiIcon component definition or imports to understand its types
rg "EuiIcon" -A5 -B5 | head -40

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 4336


🏁 Script executed:

# Search for icon type definitions in the codebase
rg "iconType|type.*icon" -i | grep -E "(documentEdit|chatLeft)" | head -10

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 299


🏁 Script executed:

# Check if there are TypeScript errors or type definition files
find . -name "*.d.ts" -path "*/eui/*" -o -path "*/oui/*" | head -10

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 197


🏁 Script executed:

# Look for what icon types are typically used with EuiIcon and EuiButtonIcon
rg "iconType=\"[^\"]+\"|type=\"[^\"]+\"" -o --max-count=30 | sort | uniq -c | sort -rn | head -20

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 2989


🏁 Script executed:

# Check if there's a types file or definition for icon types
rg "chatLeft|documentEdit" --type ts -i

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 299


🏁 Script executed:

# Check the EUI type definitions for icon types
cat -n ./typings/@elastic/eui/index.d.ts | head -100

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 1544


🏁 Script executed:

# Search for EuiIcon type definitions specifically
rg "EuiIcon|iconType" ./typings/@elastic/eui/index.d.ts -A5 -B5 | head -50

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 66


🏁 Script executed:

# Look for icon type definitions in the typings
grep -n "chatLeft\|documentEdit\|IconType" ./typings/@elastic/eui/index.d.ts

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 66


🏁 Script executed:

# Check if there are test files for the chat_header component
find . -name "*chat_header*" -type f | grep -v node_modules

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 376


🏁 Script executed:

# Look for any OUI/EUI icon constants or enumerations
rg "export.*icon|icon.*=" --type ts | grep -i "type\|const" | head -20

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 2507


🏁 Script executed:

# Search for known icon types used in the codebase to understand the pattern
rg "iconType=\"[^\"]+\"" -o | sort | uniq | head -30

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 2742


🏁 Script executed:

# Check web for OUI 1.22.1 icon availability
# First, let's look for node_modules artifacts or documentation
ls -la node_modules/@opensearch-project/oui/ 2>/dev/null | head -20 || echo "node_modules not available"

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 66


🏁 Script executed:

# Check the test file for chat_header to see if there are any icon-related tests
cat -n ./src/plugins/chat/public/components/chat_header_button.test.tsx | head -50

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 2028


🏁 Script executed:

# Look at package.json to verify the exact OUI version and check if there's a changelog
grep -A2 "@opensearch-project/oui\|@elastic/eui" package.json

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 359


🏁 Script executed:

# Search for common icon types in OUI to build a reference list
rg "iconType=\"(copy|edit|chat|document)" -o | sort | uniq

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 2297


Use valid OUI icon types for EuiIcon and EuiButtonIcon.

The icon types chatLeft (line 32) and documentEdit (line 44) do not appear to be standard icons in OUI 1.22.1. The codebase uses separate icon types like document and edit individually, never combined. Consider using valid OUI icon types such as document or documentEdit if it's a legacy alias, or register custom icons if needed.

🤖 Prompt for AI Agents
In `@src/plugins/chat/public/components/chat_header.tsx` around lines 31 - 40,
Replace nonstandard OUI icon names used in the chat header components: update
the EuiIcon instance using type="chatLeft" (in the ChatHeader render) to a valid
OUI icon name (e.g., "chat" or another supported chat-related icon) and update
the EuiButtonIcon usage that uses "documentEdit" to either "document" or "edit"
(or split into separate icons) or register a custom icon if you require a
combined glyph; ensure you change the type prop on the EuiIcon and EuiButtonIcon
elements (referenced as EuiIcon and EuiButtonIcon in this file) to valid OUI
icon names or to a custom-registered icon name so the icons render correctly.

Comment on lines +233 to +267
it('should update conversation name when new messages are added', () => {
// Start with empty timeline
mockChatService.getCurrentMessages.mockReturnValue([]);

const { container, rerender } = renderWithContext(<ChatWindow onClose={jest.fn()} />);

// Initially no title
let titleElement = container.querySelector('.chatHeader__title');
expect(titleElement).not.toBeInTheDocument();

// Simulate adding a message
const messagesWithUser = [
{ id: '1', role: 'user' as const, content: 'New conversation started' },
];
mockChatService.getCurrentMessages.mockReturnValue(messagesWithUser);

rerender(
<OpenSearchDashboardsContextProvider
services={{ core: mockCore, contextProvider: mockContextProvider }}
>
<ChatProvider
chatService={mockChatService}
suggestedActionsService={mockSuggestedActionsService}
confirmationService={mockConfirmationService}
>
<ChatWindow onClose={jest.fn()} />
</ChatProvider>
</OpenSearchDashboardsContextProvider>
);

// Now title should be present
titleElement = container.querySelector('.chatHeader__title');
expect(titleElement).toBeInTheDocument();
expect(titleElement?.textContent).toBe('New conversation started');
});
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 | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find the ChatWindow component file
fd -e tsx -e ts "chat_window" src/plugins/chat/public/components/ | grep -v test

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 134


🏁 Script executed:

#!/bin/bash
# Once we find the file, search for the restoreTimeline effect and its dependencies
rg "restoreTimeline" src/plugins/chat/public/components/ -A 5 -B 5

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 1922


🏁 Script executed:

#!/bin/bash
# Search for conversationName derivation and related useMemo
rg "conversationName|useMemo" src/plugins/chat/public/components/ -A 3 -B 3

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 13132


🏁 Script executed:

#!/bin/bash
# Look at the useEffect with chatService as dependency
rg "useEffect.*chatService|eventHandler" src/plugins/chat/public/components/ -A 10 -B 2

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 8488


🏁 Script executed:

#!/bin/bash
# Read the test file to understand mock setup and test structure
head -100 src/plugins/chat/public/components/chat_window_conversation_name.test.tsx

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 3711


🏁 Script executed:

#!/bin/bash
# Look at the renderWithContext function and how mocks are configured
rg "renderWithContext|mockChatService|mockCore|mockContextProvider" src/plugins/chat/public/components/chat_window_conversation_name.test.tsx -B 5 -A 10 | head -150

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 6026


🏁 Script executed:

#!/bin/bash
# Check if there's any setup in ChatProvider or its context that re-evaluates messages
rg "ChatProvider|useChatContext" src/plugins/chat/public/components/ -A 10 | grep -A 10 "getCurrentMessages"

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 1222


🏁 Script executed:

#!/bin/bash
# Look for any jest.act() or waitFor usage in the test file
rg "act\(|waitFor|flushPromises" src/plugins/chat/public/components/chat_window_conversation_name.test.tsx -B 2 -A 5

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 66


🏁 Script executed:

#!/bin/bash
# Get the specific test case mentioned in the review (lines 233-267)
sed -n '233,267p' src/plugins/chat/public/components/chat_window_conversation_name.test.tsx

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 1457


🏁 Script executed:

#!/bin/bash
# Look for the specific test in the file
rg "should update conversation name when new messages are added" src/plugins/chat/public/components/chat_window_conversation_name.test.tsx -A 40

Repository: opensearch-project/OpenSearch-Dashboards

Length of output: 1467


The rerender test does not trigger timeline update as expected due to stable dependency references.

The conversationName derives from timeline via useMemo, which is only populated by the restoreTimeline effect when its dependencies [chatService, eventHandler] change. Since the same mockChatService instance is reused throughout this test, the effect won't re-execute on rerender—leaving timeline empty and the title unrendered despite the mock returning new messages.

A more reliable approach would be to simulate sending a message (triggering setTimeline directly through event handling) rather than changing the mock return value across rerenders.

🤖 Prompt for AI Agents
In `@src/plugins/chat/public/components/chat_window_conversation_name.test.tsx`
around lines 233 - 267, The test fails because reuse of the same mockChatService
doesn't retrigger the restoreTimeline effect (dependencies chatService and
eventHandler are stable), so changing mockChatService.getCurrentMessages on
rerender won't populate timeline or conversationName; to fix, simulate a real
timeline update instead of swapping the mock return: in the test after mocking
messages, invoke the same event/handler that restoreTimeline subscribes to (or
directly call the setTimeline/eventHandler callback used by restoreTimeline) so
the component updates its timeline and recomputes conversationName (refer to
restoreTimeline, useMemo -> conversationName, setTimeline, and ChatWindow to
locate the logic to call).

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 12, 2026

Codecov Report

❌ Patch coverage is 86.66667% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.16%. Comparing base (527cb08) to head (609e232).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
src/plugins/chat/public/components/chat_header.tsx 50.00% 1 Missing ⚠️
...gins/chat/public/components/chat_header_button.tsx 66.66% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main   #11330   +/-   ##
=======================================
  Coverage   60.16%   60.16%           
=======================================
  Files        4652     4652           
  Lines      129576   129573    -3     
  Branches    22034    22031    -3     
=======================================
+ Hits        77954    77956    +2     
+ Misses      46067    46065    -2     
+ Partials     5555     5552    -3     
Flag Coverage Δ
Linux_1 24.80% <ø> (ø)
Linux_2 38.29% <ø> (ø)
Linux_3 40.05% <86.66%> (+0.01%) ⬆️
Linux_4 33.50% <ø> (+<0.01%) ⬆️
Windows_1 24.81% <ø> (-0.02%) ⬇️
Windows_2 38.27% <ø> (ø)
Windows_3 40.05% <86.66%> (+0.01%) ⬆️
Windows_4 33.51% <ø> (ø)

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.

@SuZhou-Joe SuZhou-Joe merged commit 4919aaf into opensearch-project:main Feb 12, 2026
83 of 85 checks passed
SuZhou-Joe added a commit to SuZhou-Joe/OpenSearch-Dashboards that referenced this pull request Feb 13, 2026
* feat: update chat-header look & feel

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

* Changeset file for PR opensearch-project#11330 created/updated

---------

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>
Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com>
markdboyd pushed a commit to cloud-gov/OpenSearch-Dashboards that referenced this pull request Mar 9, 2026
* feat: update chat-header look & feel

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

* Changeset file for PR opensearch-project#11330 created/updated

---------

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>
Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants