Skip to content

Commit

Permalink
Add i18n Support for Chat Components (#1729)
Browse files Browse the repository at this point in the history
* Add translation path in NewChat.tsx

* Update newChatDialog strings in en-US.json

* Add translation path in ThreadList.tsx

* Update ThreadList strings in en-US.json

* Add translation path in AskFileButton.tsx

* Update askFIleButton strings in en-US.json

* Update time group labels in ThreadList.tsx

* feat: add Translator import in AskFileButton.tsx

Add missing import:
import { Translator } from '@components/i18n';

* add Translator import in NewChat.tsx

* add missing comma in en-US.json

* Revert placeholder text in ThreadList.tsx

* Fix props passing to Translator component

* Fix props passing to Translator component on askFileButton

* simplify translation in AskFileButton

* simplify translation in AskFileButton

* fix: update thread deletion test selector spec.cy.ts

Use role and button.bg-primary to find confirm button in alert dialog
- More reliable way to select buttons in open dialog
- Works with translated strings
  • Loading branch information
hexart authored Jan 17, 2025
1 parent 8954a46 commit 0904f0f
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 34 deletions.
36 changes: 31 additions & 5 deletions backend/chainlit/translations/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@
"removeAttachment": "Remove attachment"
},
"newChatDialog": {
"createNewChat": "Create new chat?",
"clearChat": "This will clear the current messages and start a new chat.",
"cancel": "Cancel",
"confirm": "Confirm"
"title": "Create New Chat",
"description": "This will clear your current chat history. Are you sure you want to continue?",
"cancelButton": "Cancel",
"confirmButton": "Confirm",
"tooltip": "New Chat"
},
"settingsModal": {
"settings": "Settings",
Expand Down Expand Up @@ -110,6 +111,11 @@
},
"organisms": {
"chat": {
"askFileButton": {
"dragAndDrop": "Drag and drop files here",
"sizeLimit": "Limit:",
"browseFiles": "Browse Files"
},
"history": {
"index": {
"showHistory": "Show history",
Expand Down Expand Up @@ -203,7 +209,27 @@
"today": "Today",
"yesterday": "Yesterday",
"previous7days": "Previous 7 days",
"previous30days": "Previous 30 days"
"previous30days": "Previous 30 days",
"noThreads": "No threads found",
"DeleteDialog": {
"title": "Confirm deletion",
"description": "This action cannot be undone",
"cancel": "Cancel",
"confirm": "Confirm"
},
"RenameDialog": {
"title": "Rename Thread",
"description": "Enter a new name for this thread",
"nameLabel": "Name",
"namePlaceholder": "Enter new name",
"cancel": "Cancel",
"confirm": "Rename"
},
"RenameThreadButton": {
"renamingThread": "Renaming thread",
"threadRenamed": "Thread renamed!"
},
"untitledConversation": "Untitled Conversation"
},
"TriggerButton": {
"closeSidebar": "Close sidebar",
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/data_layer/spec.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function threadList() {
cy.wait(100);
cy.get('#delete-thread').click();
cy.wait(100);
cy.get("[type='button']").contains('Confirm').click();
cy.get("[role='alertdialog'] button.bg-primary").click();
cy.wait(100);
cy.get('#thread-test1').should('not.exist');
// Close the thread options popover
Expand Down
44 changes: 27 additions & 17 deletions frontend/src/components/LeftSidebar/ThreadList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export function ThreadList({
if (!threadHistory || size(threadHistory?.timeGroupedThreads) === 0) {
return (
<Alert variant="info" className="m-3">
No threads found
<Translator path="components.organisms.threadHistory.threadList.noThreads" />
</Alert>
);
}
Expand Down Expand Up @@ -136,7 +136,9 @@ export function ThreadList({
if (!threadIdToRename || !threadNewName) return;

toast.promise(apiClient.renameThread(threadIdToRename, threadNewName), {
loading: 'Renaming thread',
loading: (
<Translator path="components.organisms.threadHistory.threadList.RenameThreadButton.renamingThread" />
),
success: () => {
setThreadNewName(undefined);
setThreadIdToRename(undefined);
Expand All @@ -157,7 +159,9 @@ export function ThreadList({
}
return next;
});
return <div>Thread renamed!</div>;
return <div>
<Translator path="components.organisms.threadHistory.threadList.RenameThreadButton.threadRenamed" />
</div>;
},
error: (err) => {
if (err instanceof ClientError) {
Expand All @@ -171,10 +175,10 @@ export function ThreadList({

const getTimeGroupLabel = (group: string) => {
const labels = {
Today: 'Today',
Yesterday: 'Yesterday',
'Previous 7 days': 'Last 7 Days',
'Previous 30 days': 'Last 30 Days'
Today: <Translator path="components.organisms.threadHistory.sidebar.ThreadList.today" />,
Yesterday: <Translator path="components.organisms.threadHistory.sidebar.ThreadList.yesterday" />,
'Previous 7 days': <Translator path="components.organisms.threadHistory.sidebar.ThreadList.previous7days" />,
'Previous 30 days': <Translator path="components.organisms.threadHistory.sidebar.ThreadList.previous30days" />
};
return labels[group as keyof typeof labels] || group;
};
Expand All @@ -187,15 +191,19 @@ export function ThreadList({
>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Confirm deletion</AlertDialogTitle>
<AlertDialogTitle>
<Translator path="components.organisms.threadHistory.threadList.DeleteDialog.title" />
</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone.
<Translator path="components.organisms.threadHistory.threadList.DeleteDialog.description" />
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter className="flex-row gap-2 sm:gap-0">
<AlertDialogCancel className="mt-0">Cancel</AlertDialogCancel>
<AlertDialogCancel className="mt-0">
<Translator path="components.organisms.threadHistory.threadList.DeleteDialog.cancel" />
</AlertDialogCancel>
<AlertDialogAction onClick={handleDeleteThread}>
Confirm
<Translator path="components.organisms.threadHistory.threadList.DeleteDialog.confirm" />
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
Expand All @@ -206,14 +214,16 @@ export function ThreadList({
>
<DialogContent>
<DialogHeader>
<DialogTitle>Rename Thread</DialogTitle>
<DialogTitle>
<Translator path="components.organisms.threadHistory.threadList.RenameDialog.title" />
</DialogTitle>
<DialogDescription>
Enter a new name for this thread.
<Translator path="components.organisms.threadHistory.threadList.RenameDialog.description" />
</DialogDescription>
</DialogHeader>
<div className="my-6">
<Label htmlFor="name" className="text-right">
Name
<Translator path="components.organisms.threadHistory.threadList.RenameDialog.nameLabel" />
</Label>
<Input
id="name"
Expand All @@ -232,10 +242,10 @@ export function ThreadList({
variant="outline"
onClick={() => setThreadIdToRename(undefined)}
>
Cancel
<Translator path="components.organisms.threadHistory.threadList.RenameDialog.cancel" />
</Button>
<Button type="button" onClick={handleRenameThread}>
Rename
<Translator path="components.organisms.threadHistory.threadList.RenameDialog.confirm" />
</Button>
</DialogFooter>
</DialogContent>
Expand All @@ -257,7 +267,7 @@ export function ThreadList({
isActive={isSelected}
className="relative truncate h-9 group/thread"
>
{thread.name || 'Untitled Conversation'}
{thread.name || (<Translator path="components.organisms.threadHistory.threadList.untitledConversation" />)}
<div
className={cn(
'absolute w-10 bottom-0 top-0 right-0 bg-gradient-to-l from-[hsl(var(--sidebar-background))] to-transparent'
Expand Down
10 changes: 6 additions & 4 deletions frontend/src/components/chat/Messages/Message/AskFileButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { IAsk, IFileRef } from '@chainlit/react-client';

import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';

import { Translator } from '@/components/i18n';
import { useUpload } from 'hooks/useUpload';

interface UploadState {
Expand Down Expand Up @@ -133,9 +133,11 @@ const _AskFileButton = ({
>
<input id="ask-button-input" {...getInputProps()} />
<div className="flex flex-col">
<p className="text-sm font-medium">Drag and drop files here</p>
<p className="text-sm font-medium">
<Translator path="components.organisms.chat.askFileButton.dragAndDrop" />
</p>
<p className="text-sm text-muted-foreground">
Limit {askUser.spec.max_size_mb}mb.
<Translator path="components.organisms.chat.askFileButton.sizeLimit" /> {askUser.spec.max_size_mb}mb
</p>
</div>
<Button
Expand All @@ -149,7 +151,7 @@ const _AskFileButton = ({
) : (
<>
<Upload className="w-4 h-4 mr-2" />
Browse Files
<Translator path="components.organisms.chat.askFileButton.browseFiles" />
</>
)}
</Button>
Expand Down
17 changes: 10 additions & 7 deletions frontend/src/components/header/NewChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from '@/components/ui/tooltip';

import { EditSquare } from '../icons/EditSquare';

import { Translator } from '@/components/i18n';
type NewChatDialogProps = {
open: boolean;
handleClose: () => void;
Expand All @@ -35,18 +35,19 @@ export const NewChatDialog = ({
<Dialog open={open} onOpenChange={handleClose}>
<DialogContent id="new-chat-dialog" className="sm:max-w-md">
<DialogHeader>
<DialogTitle>Create New Chat</DialogTitle>
<DialogTitle>
<Translator path="components.molecules.newChatDialog.title" />
</DialogTitle>
<DialogDescription>
This will clear your current chat history. Are you sure you want to
continue?
<Translator path="components.molecules.newChatDialog.description" />
</DialogDescription>
</DialogHeader>
<DialogFooter className="gap-2 sm:gap-0">
<Button variant="outline" onClick={handleClose}>
Cancel
<Translator path="components.molecules.newChatDialog.cancelButton" />
</Button>
<Button variant="default" onClick={handleConfirm} id="confirm">
Confirm
<Translator path="components.molecules.newChatDialog.confirmButton" />
</Button>
</DialogFooter>
</DialogContent>
Expand Down Expand Up @@ -92,7 +93,9 @@ const NewChatButton = ({ navigate, ...buttonProps }: Props) => {
<EditSquare className="!size-6" />
</Button>
</TooltipTrigger>
<TooltipContent>New Chat</TooltipContent>
<TooltipContent>
<Translator path="components.molecules.newChatDialog.tooltip" />
</TooltipContent>
</Tooltip>
</TooltipProvider>
<NewChatDialog
Expand Down

0 comments on commit 0904f0f

Please sign in to comment.