Skip to content

Commit

Permalink
feat(ai chat): Delete Conversation Confirmation Dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
Douglashdaniel committed Jan 15, 2025
1 parent 22c3bf4 commit caf654e
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 2 deletions.
2 changes: 2 additions & 0 deletions components/ai_chat/core/browser/constants.cc
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ base::span<const webui::LocalizedString> GetLocalizedStrings() {
{"feedbackPremiumNote", IDS_CHAT_UI_FEEDBACK_PREMIUM_NOTE},
{"submitButtonLabel", IDS_CHAT_UI_SUBMIT_BUTTON_LABEL},
{"cancelButtonLabel", IDS_CHAT_UI_CANCEL_BUTTON_LABEL},
{"deleteButtonLabel", IDS_CHAT_UI_DELETE_BUTTON_LABEL},
{"deleteConversationWarning", IDS_CHAT_UI_DELETE_CONVERSATION_WARNING},
{"saveButtonLabel", IDS_CHAT_UI_SAVE_BUTTON_LABEL},
{"editedLabel", IDS_CHAT_UI_EDITED_LABEL},
{"editButtonLabel", IDS_CHAT_UI_EDIT_BUTTON_LABEL},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function ConversationItem(props: ConversationItemProps) {

const handleDelete: EventListener = (e) => {
e.preventDefault()
aiChatContext.service?.deleteConversation(uuid)
aiChatContext.setDeletingConversationId(uuid)
}

const isEditing = aiChatContext.editingConversationId === uuid
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* Copyright (c) 2025 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

import * as React from 'react'
import Button from '@brave/leo/react/button'
import Dialog from '@brave/leo/react/dialog'

// Utils
import { getLocale } from '$web-common/locale'

// Hooks
import { useAIChat } from '../../state/ai_chat_context'

// Styles
import styles from './style.module.scss'

export default function DeleteConversationModal() {
// Context
const aiChatContext = useAIChat()

// Computed
const title = aiChatContext.visibleConversations.find(
(conversation) =>
conversation.uuid === aiChatContext.deletingConversationId
)?.title || getLocale('conversationListUntitled')

return (
<Dialog
isOpen={!!aiChatContext.deletingConversationId}
showClose
onClose={() => aiChatContext.setDeletingConversationId(null)}
className={styles.deleteConversationDialog}
>
<div
slot='title'
className={styles.deleteConversationDialogTitle}
>
{getLocale('menuDeleteConversation')}
</div>
<div className={styles.deleteConversationBody}>
<div className={styles.conversationNameWrapper}>{title}</div>
{getLocale('deleteConversationWarning')}
</div>
<div
slot='actions'
className={styles.deleteConversationActionsRow}
>
<div className={styles.buttonsWrapper}>
<Button
kind='plain-faint'
size='medium'
onClick={() => aiChatContext.setDeletingConversationId(null)}
>
{getLocale('cancelButtonLabel')}
</Button>
<Button
kind='filled'
size='medium'
onClick={() => {
if (aiChatContext.deletingConversationId) {
aiChatContext.service?.deleteConversation(
aiChatContext.deletingConversationId
)
aiChatContext.setDeletingConversationId(null)
}
}}
>
{getLocale('deleteButtonLabel')}
</Button>
</div>
</div>
</Dialog>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) 2025 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at https://mozilla.org/MPL/2.0/.

.conversationNameWrapper {
display: flex;
align-items: flex-start;
justify-content: flex-start;
width: 100%;
padding: var(--leo-spacing-l);
border-radius: var(--leo-radius-m);
border: 1px solid var(--leo-color-divider-subtle);
font: var(--leo-font-heading-h4);
color: var(--leo-color-text-secondary);
}

.deleteConversationDialogTitle {
font: var(--leo-font-heading-h3);
}

.deleteConversationDialog {
--leo-dialog-padding: 24px;
}

.deleteConversationBody {
display: flex;
flex-direction: column;
gap: var(--leo-spacing-xl);
}

.deleteConversationActionsRow {
justify-content: flex-end;
}

.buttonsWrapper {
display: flex;
gap: var(--leo-spacing-m);
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export default function FeatureMenu(props: Props) {
</div>
</div>
</leo-menu-item>
<leo-menu-item onClick={() => aiChatContext.service?.deleteConversation(conversationContext.conversationUuid!)}>
<leo-menu-item onClick={() => aiChatContext.setDeletingConversationId(conversationContext.conversationUuid!)}>
<div className={classnames(
styles.menuItemWithIcon,
styles.menuItemMainItem
Expand Down
2 changes: 2 additions & 0 deletions components/ai_chat/resources/page/components/main/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import LongConversationInfo from '../alerts/long_conversation_info'
import NoticeConversationStorage from '../notices/notice_conversation_storage'
import WarningPremiumDisconnected from '../alerts/warning_premium_disconnected'
import ConversationsList from '../conversations_list'
import DeleteConversationModal from '../delete_conversation_modal'
import FeedbackForm from '../feedback_form'
import { ConversationHeader } from '../header'
import InputBox from '../input_box'
Expand Down Expand Up @@ -353,6 +354,7 @@ function Main() {
/>
</ToolsButtonMenu>
</div>
<DeleteConversationModal />
</main>
)
}
Expand Down
8 changes: 8 additions & 0 deletions components/ai_chat/resources/page/state/ai_chat_context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ type AIChatContextInternal = AIChatContextProps & {

editingConversationId: string | null
setEditingConversationId: (uuid: string | null) => void,
deletingConversationId: string | null
setDeletingConversationId: (uuid: string | null) => void

showSidebar: boolean,
toggleSidebar: () => void
Expand All @@ -52,6 +54,8 @@ const defaultContext: AIChatContext = {

editingConversationId: null,
setEditingConversationId: () => { },
deletingConversationId: null,
setDeletingConversationId: () => { },

showSidebar: false,
toggleSidebar: () => { },
Expand All @@ -71,6 +75,8 @@ export function AIChatContextProvider(props: React.PropsWithChildren<AIChatConte
const context = useAPIState(api, defaultContext)
const [editingConversationId, setEditingConversationId] =
React.useState<string | null>(null)
const [deletingConversationId, setDeletingConversationId] =
React.useState<string | null>(null)
const isSmall = useIsSmall()
const [showSidebar, setShowSidebar] = React.useState(isSmall)

Expand All @@ -87,6 +93,8 @@ export function AIChatContextProvider(props: React.PropsWithChildren<AIChatConte
service: api.service,
editingConversationId,
setEditingConversationId,
deletingConversationId,
setDeletingConversationId,
showSidebar,
toggleSidebar: () => setShowSidebar(s => !s),
conversationEntriesComponent: props.conversationEntriesComponent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ type CustomArgs = {
inputText: string
hasConversation: boolean
editingConversationId: string | null
deletingConversationId: string | null
visibleConversationListCount: number
hasSuggestedQuestions: boolean
hasSiteInfo: boolean
Expand Down Expand Up @@ -436,6 +437,7 @@ const args: CustomArgs = {
hasSuggestedQuestions: true,
hasSiteInfo: true,
editingConversationId: null,
deletingConversationId: null,
isFeedbackFormVisible: false,
isStorageNoticeDismissed: false,
canShowPremiumPrompt: false,
Expand Down Expand Up @@ -532,6 +534,7 @@ function StoryContext(props: React.PropsWithChildren<{args: CustomArgs, setArgs:
conversationEntriesComponent: StorybookConversationEntries,
initialized: options.args.initialized,
editingConversationId: options.args.editingConversationId,
deletingConversationId: options.args.deletingConversationId,
visibleConversations,
isStoragePrefEnabled: options.args.isStoragePrefEnabled,
hasAcceptedAgreement: options.args.hasAcceptedAgreement,
Expand All @@ -552,6 +555,7 @@ function StoryContext(props: React.PropsWithChildren<{args: CustomArgs, setArgs:
dismissPremiumPrompt: () => {},
userRefreshPremiumSession: () => {},
setEditingConversationId: (id: string | null) => setArgs({ editingConversationId: id }),
setDeletingConversationId: (id: string | null) => setArgs({ deletingConversationId: id }),
showSidebar: showSidebar,
toggleSidebar: () => setShowSidebar(s => !s)
}
Expand Down
6 changes: 6 additions & 0 deletions components/resources/ai_chat_ui_strings.grdp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,12 @@
<message name="IDS_CHAT_UI_CANCEL_BUTTON_LABEL" desc="Button label to cancel action">
Cancel
</message>
<message name="IDS_CHAT_UI_DELETE_BUTTON_LABEL" desc="Button label to delete conversation">
Delete
</message>
<message name="IDS_CHAT_UI_DELETE_CONVERSATION_WARNING" desc="A warning issued when the user is trying to delete a conversation">
Are you sure you want to delete this conversation? This action cannot be undone.
</message>
<message name="IDS_CHAT_UI_SAVE_BUTTON_LABEL" desc="Button label to save data/form">
Save
</message>
Expand Down

0 comments on commit caf654e

Please sign in to comment.