diff --git a/application/api/user/routes.py b/application/api/user/routes.py index 4bcbd7199..de701a574 100644 --- a/application/api/user/routes.py +++ b/application/api/user/routes.py @@ -551,7 +551,7 @@ def get(self): user = "local" data = [ { - "name": "default", + "name": "Default", "date": "default", "model": settings.EMBEDDINGS_NAME, "location": "remote", diff --git a/frontend/src/Hero.tsx b/frontend/src/Hero.tsx index 644848dc9..9fe965a12 100644 --- a/frontend/src/Hero.tsx +++ b/frontend/src/Hero.tsx @@ -37,12 +37,14 @@ export default function Hero({ ), diff --git a/frontend/src/Navigation.tsx b/frontend/src/Navigation.tsx index c29aaf20d..bba830372 100644 --- a/frontend/src/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -21,11 +21,10 @@ import { handleAbort, } from './conversation/conversationSlice'; import ConversationTile from './conversation/ConversationTile'; -import { useDarkTheme, useMediaQuery, useOutsideAlerter } from './hooks'; +import { useDarkTheme, useMediaQuery } from './hooks'; import useDefaultDocument from './hooks/useDefaultDocument'; import DeleteConvModal from './modals/DeleteConvModal'; import { ActiveState, Doc } from './models/misc'; -import APIKeyModal from './preferences/APIKeyModal'; import { getConversations, getDocs } from './preferences/preferenceApi'; import { selectApiKeyStatus, @@ -68,8 +67,6 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { const [isDocsListOpen, setIsDocsListOpen] = useState(false); const { t } = useTranslation(); const isApiKeySet = useSelector(selectApiKeyStatus); - const [apiKeyModalState, setApiKeyModalState] = - useState('INACTIVE'); const [uploadModalState, setUploadModalState] = useState('INACTIVE'); @@ -192,12 +189,6 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { console.error(err); }); } - useOutsideAlerter(navRef, () => { - if (isMobile && navOpen && apiKeyModalState === 'INACTIVE') { - setNavOpen(false); - setIsDocsListOpen(false); - } - }, [navOpen, isDocsListOpen, apiKeyModalState]); /* Needed to fix bug where if mobile nav was closed and then window was resized to desktop, nav would still be closed but the button to open would be gone, as per #1 on issue #146 @@ -220,7 +211,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { > menu toggle open new chat icon @@ -263,7 +254,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { }} > - + DocsGPT Logo

DocsGPT

@@ -275,7 +266,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { > menu toggle new

@@ -314,7 +305,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { Loading... )} @@ -365,6 +356,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { Upload document { setUploadModalState('ACTIVE'); if (isMobile) { @@ -392,7 +384,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { > icon

@@ -414,7 +406,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { > discord @@ -427,7 +419,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { > x @@ -440,7 +432,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { > github @@ -457,18 +449,13 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { > menu toggle

DocsGPT
- {
@@ -67,16 +68,22 @@ const SettingsBar = ({ setActiveTab, activeTab }: SettingsBarProps) => {
{tabs.map((tab, index) => ( @@ -85,7 +92,8 @@ const SettingsBar = ({ setActiveTab, activeTab }: SettingsBarProps) => {
diff --git a/frontend/src/conversation/Conversation.tsx b/frontend/src/conversation/Conversation.tsx index 8a36ea5f9..f4511fc30 100644 --- a/frontend/src/conversation/Conversation.tsx +++ b/frontend/src/conversation/Conversation.tsx @@ -386,13 +386,19 @@ export default function Conversation() { {...getRootProps()} className="flex w-full items-center rounded-[40px] border border-silver bg-white dark:bg-raisin-black" > - + + + {status === 'loading' ? ( + alt={t('loading')} + /> ) : (
- handleQuestionSubmission()} - src={isDarkTheme ? SendDark : Send} - > + aria-label={t('send')} + className="flex items-center justify-center" + > + {t('send')} +
)}
diff --git a/frontend/src/conversation/ConversationBubble.tsx b/frontend/src/conversation/ConversationBubble.tsx index d88b249e6..e410b7c57 100644 --- a/frontend/src/conversation/ConversationBubble.tsx +++ b/frontend/src/conversation/ConversationBubble.tsx @@ -8,6 +8,7 @@ import { vscDarkPlus } from 'react-syntax-highlighter/dist/cjs/styles/prism'; import rehypeKatex from 'rehype-katex'; import remarkGfm from 'remark-gfm'; import remarkMath from 'remark-math'; +import { useTranslation } from 'react-i18next'; import DocsGPT3 from '../assets/cute_docsgpt3.svg'; import Dislike from '../assets/dislike.svg?react'; @@ -62,6 +63,7 @@ const ConversationBubble = forwardRef< }, ref, ) { + const { t } = useTranslation(); // const bubbleRef = useRef(null); const chunks = useSelector(selectChunks); const selectedDocs = useSelector(selectSelectedDocs); @@ -113,13 +115,13 @@ const ConversationBubble = forwardRef< {isEditClicked && (
@@ -104,8 +114,9 @@ function EditPrompt({ onClick={() => { setModalState('INACTIVE'); }} + aria-label="Close edit prompt modal" > - + Close modal

@@ -115,13 +126,17 @@ function EditPrompt({ Edit your custom prompt and save it to DocsGPT

+ setEditPromptName(e.target.value)} - > + />
Prompt Name @@ -132,10 +147,15 @@ function EditPrompt({ Prompt Text
+
diff --git a/frontend/src/settings/APIKeys.tsx b/frontend/src/settings/APIKeys.tsx index 6775ba87e..038e4bbb4 100644 --- a/frontend/src/settings/APIKeys.tsx +++ b/frontend/src/settings/APIKeys.tsx @@ -115,12 +115,20 @@ export default function APIKeys() { - - + - - + + @@ -146,7 +154,7 @@ export default function APIKeys() {
{t('settings.apiKeys.name')} + + {t('settings.apiKeys.name')} + {t('settings.apiKeys.sourceDoc')} {t('settings.apiKeys.key')} + {t('settings.apiKeys.key')} +
Delete handleDeleteKey(element.id)} diff --git a/frontend/src/settings/Analytics.tsx b/frontend/src/settings/Analytics.tsx index 8baad361d..ccb5ffcba 100644 --- a/frontend/src/settings/Analytics.tsx +++ b/frontend/src/settings/Analytics.tsx @@ -164,7 +164,7 @@ export default function Analytics() {
-

+

Filter by chatbot

diff --git a/frontend/src/settings/Documents.tsx b/frontend/src/settings/Documents.tsx index 8e68f226e..cdde16fed 100644 --- a/frontend/src/settings/Documents.tsx +++ b/frontend/src/settings/Documents.tsx @@ -54,10 +54,10 @@ const Documents: React.FC = ({ const [totalPages, setTotalPages] = useState(1); const currentDocuments = paginatedDocuments ?? []; const syncOptions = [ - { label: 'Never', value: 'never' }, - { label: 'Daily', value: 'daily' }, - { label: 'Weekly', value: 'weekly' }, - { label: 'Monthly', value: 'monthly' }, + { label: t('settings.documents.syncFrequency.never'), value: 'never' }, + { label: t('settings.documents.syncFrequency.daily'), value: 'daily' }, + { label: t('settings.documents.syncFrequency.weekly'), value: 'weekly' }, + { label: t('settings.documents.syncFrequency.monthly'), value: 'monthly' }, ]; const refreshDocs = useCallback( @@ -151,9 +151,12 @@ const Documents: React.FC = ({
+ = ({ onChange={(e) => { setSearchTerm(e.target.value); setCurrentPage(1); - // refreshDocs(sortField, 1, rowsPerPage); - // do not call refreshDocs here the state is async - // so it will not have the updated value - }} // Handle search input change + }} />
{loading ? ( ) : ( -
+
@@ -225,8 +225,9 @@ const Documents: React.FC = ({ @@ -270,7 +271,7 @@ const Documents: React.FC = ({ {document.type !== 'remote' && ( Delete { @@ -282,7 +283,7 @@ const Documents: React.FC = ({ {document.syncFrequency && (
{ handleManageSync(document, value); diff --git a/frontend/src/settings/General.tsx b/frontend/src/settings/General.tsx index 4868d252c..216ec1e0f 100644 --- a/frontend/src/settings/General.tsx +++ b/frontend/src/settings/General.tsx @@ -21,33 +21,15 @@ export default function General() { t, i18n: { changeLanguage, language }, } = useTranslation(); - const themes = ['Light', 'Dark']; + const themes = [t('settings.general.light'), t('settings.general.dark')]; const languageOptions = [ - { - label: 'English', - value: 'en', - }, - { - label: 'Spanish', - value: 'es', - }, - { - label: 'Japanese', - value: 'jp', - }, - { - label: 'Mandarin', - value: 'zh', - }, - { - label: 'Traditional Chinese', - value: 'zhTW', - }, - { - label: 'Russian', - value: 'ru', - }, + { label: 'English', value: 'en' }, + { label: 'Español', value: 'es' }, + { label: '日本語', value: 'jp' }, + { label: '普通话', value: 'zh' }, + { label: '繁體中文(臺灣)', value: 'zhTW' }, + { label: 'Русский', value: 'ru' }, ]; const chunks = ['0', '2', '4', '6', '8', '10']; const token_limits = new Map([ @@ -99,9 +81,9 @@ export default function General() { return (
-

+

+
-

+

+ @@ -133,9 +115,9 @@ export default function General() { />
-

+

+
-

+

+ ({ value: value, @@ -181,16 +163,14 @@ export default function General() { />
-

+

+
diff --git a/frontend/src/settings/Logs.tsx b/frontend/src/settings/Logs.tsx index 1e248d460..f1ebfe72d 100644 --- a/frontend/src/settings/Logs.tsx +++ b/frontend/src/settings/Logs.tsx @@ -1,4 +1,5 @@ import React, { useState, useEffect, useRef, useCallback } from 'react'; +import { useTranslation } from 'react-i18next'; import userService from '../api/services/userService'; import ChevronRight from '../assets/chevron-right.svg'; @@ -8,6 +9,7 @@ import { APIKeyData, LogData } from './types'; import CoppyButton from '../components/CopyButton'; export default function Logs() { + const { t } = useTranslation(); const [chatbots, setChatbots] = useState([]); const [selectedChatbot, setSelectedChatbot] = useState(); const [logs, setLogs] = useState([]); @@ -65,9 +67,12 @@ export default function Logs() {
-

- Filter by chatbot -

+ {loadingChatbots ? ( ) : ( @@ -78,9 +83,9 @@ export default function Logs() { label: chatbot.name, value: chatbot.id, })), - { label: 'None', value: '' }, + { label: t('settings.logs.none'), value: '' }, ]} - placeholder="Select chatbot" + placeholder={t('settings.logs.selectChatbotPlaceholder')} onSelect={(chatbot: { label: string; value: string }) => { setSelectedChatbot( chatbots.find((item) => item.id === chatbot.value), @@ -120,6 +125,7 @@ type LogsTableProps = { }; function LogsTable({ logs, setPage }: LogsTableProps) { + const { t } = useTranslation(); const observerRef = useRef(); const firstObserver = useCallback((node: HTMLDivElement) => { if (observerRef.current) { @@ -134,7 +140,7 @@ function LogsTable({ logs, setPage }: LogsTableProps) {

- API generated / chatbot conversations + {t('settings.logs.apiGeneratedConversations')}

@@ -98,10 +103,10 @@ export default function Tools() {
No tools found - No tools found + {t('settings.tools.noToolsFound')}
) : ( userTools @@ -119,15 +124,19 @@ export default function Tools() {
{`${tool.displayName} @@ -146,6 +155,11 @@ export default function Tools() { htmlFor={`toolToggle-${index}`} className="relative inline-block h-6 w-10 cursor-pointer rounded-full bg-gray-300 dark:bg-[#D2D5DA33]/20 transition [-webkit-tap-highlight-color:_transparent] has-[:checked]:bg-[#0C9D35CC] has-[:checked]:dark:bg-[#0C9D35CC]" > + + {t('settings.tools.toggleToolAria', { + toolName: tool.displayName, + })} +
); case t('settings.apiKeys.label'):
- {' '} + {t('settings.documents.actions')}