Skip to content

Commit

Permalink
Add delete mutation to useChatSessions hook, hook up onDelete handlin…
Browse files Browse the repository at this point in the history
…g in menu and confirm dialog, and move session state to top module level
  • Loading branch information
mmichael0413 committed Jan 22, 2025
1 parent c19256b commit 7301fd0
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 19 deletions.
29 changes: 26 additions & 3 deletions src/modules/AieraChat/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Menu } from './panels/Menu';
import { Messages } from './components/Messages';
import { Sources } from './panels/Sources';
import { useChatStore } from './store';
import { useChatSessions } from './services/chats';
import { ChatMessage } from './services/messages';

export function AieraChat(): ReactElement {
Expand All @@ -19,6 +20,24 @@ export function AieraChat(): ReactElement {
const config = useConfig();
const virtuosoRef = useRef<VirtuosoMessageListMethods<ChatMessage>>(null);

const { deleteSession, sessions, isLoading } = useChatSessions();
const [deletedSessionId, setDeletedSessionId] = useState<string | null>(null);

const handleDeleteConfirm = useCallback(
(e: React.MouseEvent) => {
e.preventDefault();
if (deletedSessionId) {
deleteSession(Number(deletedSessionId))
.then(() => {
setDeletedSessionId(null);
setShowConfirm(false);
})
.catch(() => setShowConfirm(false));
}
},
[deletedSessionId, setDeletedSessionId]
);

const [animateTranscriptExit, setAnimateTranscriptExit] = useState(false);

const onOpenMenu = useCallback(() => {
Expand All @@ -37,11 +56,13 @@ export function AieraChat(): ReactElement {
setShowSources(false);
}, []);

const onOpenConfirm = useCallback(() => {
const onOpenConfirm = useCallback((sessionId: string) => {
setDeletedSessionId(sessionId);
setShowConfirm(true);
}, []);

const onCloseConfirm = useCallback(() => {
setDeletedSessionId(null);
setShowConfirm(false);
}, []);

Expand Down Expand Up @@ -95,8 +116,10 @@ export function AieraChat(): ReactElement {
<Header onOpenMenu={onOpenMenu} virtuosoRef={virtuosoRef} />
<Messages onOpenSources={onOpenSources} virtuosoRef={virtuosoRef} />
{showSources && <Sources onClose={onCloseSources} />}
{showMenu && <Menu onClose={onCloseMenu} onOpenConfirm={onOpenConfirm} />}
{showConfirm && <ConfirmDialog onClose={onCloseConfirm} />}
{showMenu && (
<Menu isLoading={isLoading} onClickIcon={onOpenConfirm} onClose={onCloseMenu} sessions={sessions} />
)}
{showConfirm && <ConfirmDialog onDelete={handleDeleteConfirm} onClose={onCloseConfirm} />}
</div>
</>
);
Expand Down
7 changes: 4 additions & 3 deletions src/modules/AieraChat/modals/ConfirmDialog/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import React, { MouseEvent, ReactElement } from 'react';
import { MicroTrash } from '@aiera/client-sdk/components/Svg/MicroTrash';
import React, { ReactElement } from 'react';
import { Modal } from '../Modal';
import { Button } from '@aiera/client-sdk/components/Button';

interface ConfirmDialogProps {
onDelete: (e: MouseEvent) => void;
onClose: () => void;
}

export function ConfirmDialog({ onClose }: ConfirmDialogProps): ReactElement {
export function ConfirmDialog({ onClose, onDelete }: ConfirmDialogProps): ReactElement {
return (
<Modal onClose={onClose} title="Confirm Delete" className="justify-center items-center" Icon={MicroTrash}>
<p className="text-base mt-1 leading-5 text-slate-600 text-balance text-center">
Are you sure you want to delete this chat?
</p>
<div className="flex items-center justify-center mt-6">
<Button kind="primary" onClick={onClose}>
<Button kind="primary" onClick={onDelete}>
Delete
</Button>
<Button kind="secondary" onClick={onClose} className="ml-2">
Expand Down
19 changes: 13 additions & 6 deletions src/modules/AieraChat/panels/Menu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,23 @@ import classNames from 'classnames';
import React, { useState } from 'react';
import { Panel } from '../Panel';
import { SearchInput } from '../../components/SearchInput';
import { useChatSessions } from '../../services/chats';
import { useChatStore } from '../../store';
import { ContentRow } from '../../components/ContentRow';
import { ChatSession } from '../../services/chats';

export function Menu({ onClose, onOpenConfirm }: { onOpenConfirm: () => void; onClose: () => void }) {
export function Menu({
isLoading,
onClickIcon,
onClose,
sessions,
}: {
isLoading: boolean;
onClickIcon: (sessionId: string) => void;
onClose: () => void;
sessions: ChatSession[];
}) {
const { chatId, onSelectChat, onNewChat } = useChatStore();
const [searchTerm, setSearchTerm] = useState<string | undefined>(undefined);
const { sessions, isLoading } = useChatSessions();

const filteredResults = sessions.filter(({ title }) =>
title.toLowerCase().includes(searchTerm?.toLowerCase() || '')
Expand All @@ -40,9 +49,7 @@ export function Menu({ onClose, onOpenConfirm }: { onOpenConfirm: () => void; on
onSelectChat(id, title);
onStartExit();
}}
onClickIcon={() => {
onOpenConfirm();
}}
onClickIcon={() => onClickIcon(id)}
Icon={MicroTrash}
iconClassName="text-slate-500 hover:text-rose-600"
className={classNames('mx-5', {
Expand Down
49 changes: 43 additions & 6 deletions src/modules/AieraChat/services/chats.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,61 @@
import gql from 'graphql-tag';
import { useState, useEffect, useCallback } from 'react';
import { useMutation } from 'urql';
import { useQuery } from '@aiera/client-sdk/api/client';
import { ChatSessionsQuery, ChatSessionsQueryVariables } from '@aiera/client-sdk/types/generated';
import {
ChatSessionsQuery,
ChatSessionsQueryVariables,
DeleteChatSessionMutation,
DeleteChatSessionMutationVariables,
} from '@aiera/client-sdk/types/generated';

interface ChatSession {
export interface ChatSession {
id: string;
title: string;
}

interface UseChatSessionsReturn {
sessions: ChatSession[];
isLoading: boolean;
deleteSession: (sessionId: number) => Promise<void>;
error: string | null;
isLoading: boolean;
refresh: () => void;
sessions: ChatSession[];
}

export const useChatSessions = (): UseChatSessionsReturn => {
const [sessions, setSessions] = useState<ChatSession[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);

const [_, deleteChatMutation] = useMutation<DeleteChatSessionMutation, DeleteChatSessionMutationVariables>(gql`
mutation DeleteChatSession($sessionId: Int!) {
deleteChatSession(sessionId: $sessionId) {
success
}
}
`);
const deleteSession = useCallback(
(sessionId: number) => {
setIsLoading(true);
return deleteChatMutation({ sessionId })
.then((resp) => {
if (resp.data?.deleteChatSession?.success) {
setSessions((prevSessions) =>
prevSessions.filter((session) => session.id.toString() !== sessionId.toString())
);
} else {
setError('Error deleting chat session');
}
})
.catch(() => {
setError('Error deleting chat session');
setIsLoading(false);
})
.finally(() => setIsLoading(false));
},
[deleteChatMutation, setError, setIsLoading, setSessions]
);

const query = useQuery<ChatSessionsQuery, ChatSessionsQueryVariables>({
query: gql`
query ChatSessions {
Expand Down Expand Up @@ -64,9 +100,10 @@ export const useChatSessions = (): UseChatSessionsReturn => {
};

return {
sessions,
isLoading,
deleteSession,
error,
isLoading,
refresh,
sessions,
};
};
2 changes: 1 addition & 1 deletion src/modules/Transcript/DownloadTooltip/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export function DownloadTooltipUI(props: DownloadTooltipUIProps): ReactElement {
)}
>
<button
data-testId="downloadButton"
data-testid="downloadButton"
className={classNames(
'ml-3',
'group flex h-8 w-8 items-center justify-center font-semibold rounded-lg',
Expand Down

0 comments on commit 7301fd0

Please sign in to comment.