Skip to content

Commit

Permalink
Fix redirect new session when dock right (#36)
Browse files Browse the repository at this point in the history
* fix: change to new session after history deleted

Signed-off-by: Lin Wang <wonglam@amazon.com>

* test: add miss file and style mock

Signed-off-by: Lin Wang <wonglam@amazon.com>

* feat: add unit test for clear deleted old chat session data

Signed-off-by: Lin Wang <wonglam@amazon.com>

* refactor: change handleEditConversationConfirmModalClose to handleEditConversationModalClose

Signed-off-by: Lin Wang <wonglam@amazon.com>

* Utilize barrel file for cleaner imports

Example of using index.ts and importing one line instead of two.

Signed-off-by: Kawika Avilla <kavilla414@gmail.com>

* refactor: move hooks references to index.ts

Signed-off-by: Lin Wang <wonglam@amazon.com>

---------

Signed-off-by: Lin Wang <wonglam@amazon.com>
Signed-off-by: Kawika Avilla <kavilla414@gmail.com>
Co-authored-by: Kawika Avilla <kavilla414@gmail.com>
  • Loading branch information
wanglam and kavilla authored Dec 4, 2023
1 parent 28bbf34 commit 4faad30
Show file tree
Hide file tree
Showing 13 changed files with 139 additions and 27 deletions.
2 changes: 1 addition & 1 deletion public/chat_header_button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { ApplicationStart } from '../../../src/core/public';
import { ChatFlyout } from './chat_flyout';
import { ChatContext, IChatContext } from './contexts/chat_context';
import { SetContext } from './contexts/set_context';
import { ChatStateProvider } from './hooks/use_chat_state';
import { ChatStateProvider } from './hooks';
import './index.scss';
import chatIcon from './assets/chat.svg';
import { ActionExecutor, AssistantActions, ContentRenderer, UserAccount, TabId } from './types';
Expand Down
6 changes: 2 additions & 4 deletions public/components/chat_window_header_title.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ import {
EuiButtonIcon,
} from '@elastic/eui';
import React, { useCallback, useState } from 'react';
import { useChatContext } from '../contexts/chat_context';
import { useChatActions } from '../hooks/use_chat_actions';
import { useChatContext } from '../contexts';
import { useChatActions, useChatState, useSaveChat } from '../hooks';
import { NotebookNameModal } from './notebook/notebook_name_modal';
import { ChatExperimentalBadge } from './chat_experimental_badge';
import { useCore } from '../contexts/core_context';
import { useChatState } from '../hooks/use_chat_state';
import { useSaveChat } from '../hooks/use_save_chat';
import { EditConversationNameModal } from './edit_conversation_name_modal';

export const ChatWindowHeaderTitle = React.memo(() => {
Expand Down
7 changes: 7 additions & 0 deletions public/contexts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export { useChatContext } from './chat_context';
export { useCore } from './core_context';
2 changes: 1 addition & 1 deletion public/contexts/set_context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import React from 'react';
import { useChatActions } from '../hooks/use_chat_actions';
import { useChatActions } from '../hooks';
import { AssistantActions } from '../types';

interface SetContextProps {
Expand Down
8 changes: 8 additions & 0 deletions public/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export { useSaveChat } from './use_save_chat';
export { useChatState, ChatStateProvider } from './use_chat_state';
export { useChatActions } from './use_chat_actions';
7 changes: 3 additions & 4 deletions public/tabs/chat/chat_page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@
import { EuiFlyoutBody, EuiFlyoutFooter, EuiPage, EuiPageBody, EuiSpacer } from '@elastic/eui';
import React, { useCallback, useState } from 'react';
import cs from 'classnames';
import { useChatContext } from '../../contexts/chat_context';
import { useChatState } from '../../hooks/use_chat_state';
import { useObservable } from 'react-use';
import { useChatContext, useCore } from '../../contexts';
import { useChatState } from '../../hooks';
import { ChatPageContent } from './chat_page_content';
import { ChatInputControls } from './controls/chat_input_controls';
import { useObservable } from 'react-use';
import { useCore } from '../../contexts/core_context';

interface ChatPageProps {
className?: string;
Expand Down
5 changes: 2 additions & 3 deletions public/tabs/chat/chat_page_content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@ import {
import React, { useLayoutEffect, useRef } from 'react';
import { IMessage, ISuggestedAction } from '../../../common/types/chat_saved_object_attributes';
import { TermsAndConditions } from '../../components/terms_and_conditions';
import { useChatContext } from '../../contexts/chat_context';
import { useChatState } from '../../hooks/use_chat_state';
import { useChatContext } from '../../contexts';
import { useChatState, useChatActions } from '../../hooks';
import { ChatPageGreetings } from './chat_page_greetings';
import { MessageBubble } from './messages/message_bubble';
import { MessageContent } from './messages/message_content';
import { SuggestionBubble } from './suggestions/suggestion_bubble';
import { useChatActions } from '../../hooks/use_chat_actions';

interface ChatPageContentProps {
showGreetings: boolean;
Expand Down
6 changes: 3 additions & 3 deletions public/tabs/chat/controls/chat_input_controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { EuiButton, EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiTextArea } from '@elastic/eui';
import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiTextArea } from '@elastic/eui';
import autosize from 'autosize';
import React, { useRef } from 'react';
import { useEffectOnce } from 'react-use';
import { IMessage } from '../../../../common/types/chat_saved_object_attributes';
import { useChatContext } from '../../../contexts/chat_context';
import { useChatActions } from '../../../hooks/use_chat_actions';
import { useChatContext } from '../../../contexts';
import { useChatActions } from '../../../hooks';

interface ChatInputControlsProps {
disabled: boolean;
Expand Down
81 changes: 81 additions & 0 deletions public/tabs/history/__tests__/chat_history_page.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { act, fireEvent, render } from '@testing-library/react';
import { BehaviorSubject } from 'rxjs';
import { I18nProvider } from '@osd/i18n/react';

import * as useChatStateExports from '../../../hooks';
import * as contextsExports from '../../../contexts';

import { ChatHistoryPage } from '../chat_history_page';

const setup = () => {
const useCoreMock = {
services: {
sessions: {
sessions$: new BehaviorSubject({
objects: [
{
id: '1',
title: 'foo',
},
],
total: 1,
}),
status$: new BehaviorSubject('idle'),
load: jest.fn(),
},
sessionLoad: {},
},
};
const useChatStateMock = {
chatStateDispatch: jest.fn(),
};
const useChatContextMock = {
sessionId: '1',
setSessionId: jest.fn(),
setTitle: jest.fn(),
};
jest.spyOn(contextsExports, 'useCore').mockReturnValue(useCoreMock);
jest.spyOn(useChatStateExports, 'useChatState').mockReturnValue(useChatStateMock);
jest.spyOn(contextsExports, 'useChatContext').mockReturnValue(useChatContextMock);

const renderResult = render(
<I18nProvider>
<ChatHistoryPage shouldRefresh={false} />
</I18nProvider>
);

return {
useCoreMock,
useChatStateMock,
useChatContextMock,
renderResult,
};
};

describe('<ChatHistoryPage />', () => {
it('should clear old session data after current session deleted', async () => {
const { renderResult, useChatStateMock, useChatContextMock } = setup();

act(() => {
fireEvent.click(renderResult.getByLabelText('Delete conversation'));
});

expect(useChatContextMock.setSessionId).not.toHaveBeenCalled();
expect(useChatContextMock.setTitle).not.toHaveBeenCalled();
expect(useChatStateMock.chatStateDispatch).not.toHaveBeenCalled();

act(() => {
fireEvent.click(renderResult.getByTestId('confirmModalConfirmButton'));
});

expect(useChatContextMock.setSessionId).toHaveBeenLastCalledWith(undefined);
expect(useChatContextMock.setTitle).toHaveBeenLastCalledWith(undefined);
expect(useChatStateMock.chatStateDispatch).toHaveBeenLastCalledWith({ type: 'reset' });
});
});
22 changes: 15 additions & 7 deletions public/tabs/history/chat_history_page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { FormattedMessage } from '@osd/i18n/react';
import { useDebounce, useObservable } from 'react-use';
import cs from 'classnames';
import { useChatActions } from '../../hooks/use_chat_actions';
import { useChatContext } from '../../contexts/chat_context';
import { useCore } from '../../contexts/core_context';
import { useChatActions, useChatState } from '../../hooks';
import { useChatContext, useCore } from '../../contexts';
import { ChatHistorySearchList } from './chat_history_search_list';

interface ChatHistoryPageProps {
Expand All @@ -33,7 +32,14 @@ interface ChatHistoryPageProps {
export const ChatHistoryPage: React.FC<ChatHistoryPageProps> = React.memo((props) => {
const { services } = useCore();
const { loadChat } = useChatActions();
const { setSelectedTabId, flyoutFullScreen, sessionId } = useChatContext();
const { chatStateDispatch } = useChatState();
const {
setSelectedTabId,
flyoutFullScreen,
sessionId,
setSessionId,
setTitle,
} = useChatContext();
const [pageIndex, setPageIndex] = useState(0);
const [pageSize, setPageSize] = useState(10);
const [searchName, setSearchName] = useState<string>();
Expand Down Expand Up @@ -70,11 +76,13 @@ export const ChatHistoryPage: React.FC<ChatHistoryPageProps> = React.memo((props
const handleHistoryDeleted = useCallback(
(id: string) => {
if (sessionId === id) {
// Switch to new conversation when current session be deleted
loadChat();
// Clear old session chat states
setTitle(undefined);
setSessionId(undefined);
chatStateDispatch({ type: 'reset' });
}
},
[sessionId, loadChat]
[sessionId, setSessionId, setTitle, chatStateDispatch]
);

useDebounce(
Expand Down
8 changes: 4 additions & 4 deletions public/tabs/history/chat_history_search_list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const ChatHistorySearchList = ({
} | null>(null);
const [deletingConversation, setDeletingConversation] = useState<{ id: string } | null>(null);

const handleEditConversationCancel = useCallback(
const handleEditConversationModalClose = useCallback(
(status: 'updated' | string) => {
if (status === 'updated') {
onRefresh();
Expand All @@ -61,7 +61,7 @@ export const ChatHistorySearchList = ({
[setEditingConversation, onRefresh]
);

const handleDeleteConversationCancel = useCallback(
const handleDeleteConversationConfirmModalClose = useCallback(
(status: 'deleted' | string) => {
if (status === 'deleted') {
onRefresh();
Expand Down Expand Up @@ -108,15 +108,15 @@ export const ChatHistorySearchList = ({
/>
{editingConversation && (
<EditConversationNameModal
onClose={handleEditConversationCancel}
onClose={handleEditConversationModalClose}
sessionId={editingConversation.id}
defaultTitle={editingConversation.title}
/>
)}
{deletingConversation && (
<DeleteConversationConfirmModal
sessionId={deletingConversation.id}
onClose={handleDeleteConversationCancel}
onClose={handleDeleteConversationConfirmModalClose}
/>
)}
</>
Expand Down
6 changes: 6 additions & 0 deletions test/__mocks__/fileMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

module.exports = 'file-stub';
6 changes: 6 additions & 0 deletions test/__mocks__/styleMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

module.exports = {};

0 comments on commit 4faad30

Please sign in to comment.