diff --git a/public/chat_flyout.test.tsx b/public/chat_flyout.test.tsx
new file mode 100644
index 00000000..85b00737
--- /dev/null
+++ b/public/chat_flyout.test.tsx
@@ -0,0 +1,149 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { render, screen, fireEvent } from '@testing-library/react';
+
+import { ChatFlyout } from './chat_flyout';
+import * as chatContextExports from './contexts/chat_context';
+import { TAB_ID } from './utils/constants';
+
+jest.mock('./tabs/chat/chat_page', () => ({
+ ChatPage: () =>
,
+}));
+
+jest.mock('./tabs/chat_window_header', () => ({
+ ChatWindowHeader: () => ,
+}));
+
+jest.mock('./tabs/history/chat_history_page', () => ({
+ ChatHistoryPage: () => ,
+}));
+
+jest.mock('./components/agent_framework_traces_flyout_body', () => ({
+ AgentFrameworkTracesFlyoutBody: () => (
+
+ ),
+}));
+
+describe('', () => {
+ beforeEach(() => {
+ jest.spyOn(chatContextExports, 'useChatContext').mockReturnValue({
+ setFlyoutVisible: jest.fn(),
+ selectedTabId: TAB_ID.CHAT,
+ traceId: 'chat_trace_id_mock',
+ });
+ });
+
+ afterEach(() => {
+ jest.resetAllMocks();
+ });
+
+ it('should only display chat panel when current tab is TAB_ID.CHAT under non-fullscreen mode', () => {
+ jest.spyOn(chatContextExports, 'useChatContext').mockReturnValue({
+ setFlyoutVisible: jest.fn(),
+ selectedTabId: TAB_ID.CHAT,
+ traceId: 'chat_trace_id_mock',
+ });
+
+ render(
+
+ );
+ expect(screen.getByLabelText('chat panel').classList).not.toContain('llm-chat-hidden');
+ expect(screen.getByLabelText('history panel').classList).toContain('llm-chat-hidden');
+ });
+
+ it('should only display history panel when current tab is TAB_ID.HISTORY under non-fullscreen mode', () => {
+ jest.spyOn(chatContextExports, 'useChatContext').mockReturnValue({
+ setFlyoutVisible: jest.fn(),
+ selectedTabId: TAB_ID.HISTORY,
+ traceId: 'chat_trace_id_mock',
+ });
+
+ render(
+
+ );
+ expect(screen.getByLabelText('chat panel').classList).toContain('llm-chat-hidden');
+ expect(screen.getByLabelText('history panel').classList).not.toContain('llm-chat-hidden');
+ });
+
+ it('should display chat history page', () => {
+ jest.spyOn(chatContextExports, 'useChatContext').mockReturnValue({
+ setFlyoutVisible: jest.fn(),
+ selectedTabId: TAB_ID.HISTORY,
+ traceId: 'chat_trace_id_mock',
+ });
+
+ render(
+
+ );
+
+ expect(screen.queryByLabelText('mock chat history page')).toBeInTheDocument();
+ expect(
+ screen.queryByLabelText('mock agent framework traces flyout body')
+ ).not.toBeInTheDocument();
+ });
+
+ it('should display traces page', () => {
+ jest.spyOn(chatContextExports, 'useChatContext').mockReturnValue({
+ setFlyoutVisible: jest.fn(),
+ selectedTabId: TAB_ID.TRACE,
+ traceId: 'chat_trace_id_mock',
+ });
+
+ render(
+
+ );
+
+ expect(screen.queryByLabelText('mock chat history page')).not.toBeInTheDocument();
+ expect(screen.queryByLabelText('mock agent framework traces flyout body')).toBeInTheDocument();
+ });
+
+ it('should always display chat panel when in fullscreen mode', () => {
+ jest.spyOn(chatContextExports, 'useChatContext').mockReturnValue({
+ setFlyoutVisible: jest.fn(),
+ // current tab is NOT chat
+ selectedTabId: TAB_ID.HISTORY,
+ traceId: 'chat_trace_id_mock',
+ });
+
+ render(
+
+ );
+
+ expect(screen.getByLabelText('chat panel').classList).not.toContain('llm-chat-hidden');
+ expect(screen.getByLabelText('history panel').classList).not.toContain('llm-chat-hidden');
+ });
+});
diff --git a/public/chat_flyout.tsx b/public/chat_flyout.tsx
index 42d6e32c..d4c2e234 100644
--- a/public/chat_flyout.tsx
+++ b/public/chat_flyout.tsx
@@ -5,7 +5,7 @@
import { EuiFlyout, EuiFlyoutHeader, EuiResizableContainer } from '@elastic/eui';
import cs from 'classnames';
-import React from 'react';
+import React, { useRef } from 'react';
import { useChatContext } from './contexts/chat_context';
import { ChatPage } from './tabs/chat/chat_page';
import { ChatWindowHeader } from './tabs/chat_window_header';
@@ -13,8 +13,6 @@ import { ChatHistoryPage } from './tabs/history/chat_history_page';
import { AgentFrameworkTracesFlyoutBody } from './components/agent_framework_traces_flyout_body';
import { TAB_ID } from './utils/constants';
-let chatHistoryPageLoaded = false;
-
interface ChatFlyoutProps {
flyoutVisible: boolean;
overrideComponent: React.ReactNode | null;
@@ -25,6 +23,7 @@ interface ChatFlyoutProps {
export const ChatFlyout: React.FC = (props) => {
const chatContext = useChatContext();
+ const chatHistoryPageLoadedRef = useRef(false);
let chatPageVisible = false;
let chatHistoryPageVisible = false;
@@ -54,7 +53,8 @@ export const ChatFlyout: React.FC = (props) => {
chatPageVisible = true;
}
- if (!chatHistoryPageLoaded && chatHistoryPageVisible) chatHistoryPageLoaded = true;
+ if (!chatHistoryPageLoadedRef.current && chatHistoryPageVisible)
+ chatHistoryPageLoadedRef.current = true;
const resizable = props.flyoutFullScreen && (chatHistoryPageVisible || chatTraceVisible);
const getLeftPanelSize = () => {
@@ -107,6 +107,7 @@ export const ChatFlyout: React.FC = (props) => {
{(Panel, Resizer) => (
<>
= (props) => {
<>
{resizable && }
= (props) => {
initialSize={resizable ? 30 : undefined}
paddingSize="none"
>
- {chatHistoryPageLoaded && (
+ {chatHistoryPageLoadedRef.current && (
', () => {
+ beforeEach(() => {
+ jest.spyOn(coreContextExports, 'useCore').mockReturnValue({
+ services: {
+ uiSettings: {
+ get: jest.fn().mockReturnValue('MMM D, YYYY @ HH:mm:ss.SSS'),
+ },
+ startDeps: {
+ dashboard: {
+ DashboardContainerByValueRenderer: () => ,
+ },
+ },
+ },
+ });
+ });
+
+ afterEach(() => {
+ jest.resetAllMocks();
+ });
+
+ it('should display visualization of last 15 minutes by default', () => {
+ render(
+
+ );
+ expect(screen.queryByText('Last 15 minutes')).toBeInTheDocument();
+ });
+});