From 4fcc80719e1c0e069d1524c89d60fb79344e53b5 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Tue, 28 May 2024 01:39:37 +0530 Subject: [PATCH 1/6] feat(i18n): settings static content --- frontend/package-lock.json | 83 +++++++++++++++++++--- frontend/package.json | 3 +- frontend/src/App.tsx | 1 + frontend/src/conversation/Conversation.tsx | 2 +- frontend/src/locale/en.json | 39 ++++++++++ frontend/src/locale/es.json | 39 ++++++++++ frontend/src/locale/i18n.ts | 21 ++++++ frontend/src/modals/index.tsx | 4 +- frontend/src/settings/APIKeys.tsx | 15 ++-- frontend/src/settings/Documents.tsx | 18 +++-- frontend/src/settings/General.tsx | 57 +++++++++++---- frontend/src/settings/Prompts.tsx | 14 ++-- frontend/src/settings/index.tsx | 16 +++-- 13 files changed, 267 insertions(+), 45 deletions(-) create mode 100644 frontend/src/locale/en.json create mode 100644 frontend/src/locale/es.json create mode 100644 frontend/src/locale/i18n.ts diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 98aedce..c39f8bf 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -10,10 +10,12 @@ "dependencies": { "@reduxjs/toolkit": "^1.9.2", "@vercel/analytics": "^0.1.10", + "i18next": "^23.11.5", "react": "^18.2.0", "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", + "react-i18next": "^14.1.2", "react-markdown": "^8.0.7", "react-redux": "^8.0.5", "react-router-dom": "^6.8.1", @@ -354,11 +356,12 @@ } }, "node_modules/@babel/runtime": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", - "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.6.tgz", + "integrity": "sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==", + "license": "MIT", "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -1485,7 +1488,7 @@ "version": "18.0.10", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz", "integrity": "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==", - "devOptional": true, + "dev": true, "dependencies": { "@types/react": "*" } @@ -4134,6 +4137,15 @@ "react-is": "^16.7.0" } }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "license": "MIT", + "dependencies": { + "void-elements": "3.1.0" + } + }, "node_modules/human-signals": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz", @@ -4158,6 +4170,29 @@ "url": "https://github.com/sponsors/typicode" } }, + "node_modules/i18next": { + "version": "23.11.5", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.11.5.tgz", + "integrity": "sha512-41pvpVbW9rhZPk5xjCX2TPJi2861LEig/YRhUkY+1FQ2IQPS0bKUDYnEqY8XPPbB48h1uIwLnP9iiEfuSl20CA==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -6678,6 +6713,28 @@ "react": ">= 16.8 || 18.0.0" } }, + "node_modules/react-i18next": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.2.tgz", + "integrity": "sha512-FSIcJy6oauJbGEXfhUgVeLzvWBhIBIS+/9c6Lj4niwKZyGaGb4V4vUbATXSlsHJDXXB+ociNxqFNiFuV1gmoqg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 23.2.3", + "react": ">= 16.8.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -6875,9 +6932,10 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" }, "node_modules/regexp.prototype.flags": { "version": "1.4.3", @@ -7923,6 +7981,15 @@ "vite": "^2.6.0 || 3 || 4 || 5" } }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/frontend/package.json b/frontend/package.json index 5c6ef82..ebcbb3f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -21,10 +21,12 @@ "dependencies": { "@reduxjs/toolkit": "^1.9.2", "@vercel/analytics": "^0.1.10", + "i18next": "^23.11.5", "react": "^18.2.0", "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", + "react-i18next": "^14.1.2", "react-markdown": "^8.0.7", "react-redux": "^8.0.5", "react-router-dom": "^6.8.1", @@ -58,5 +60,4 @@ "vite": "^5.0.13", "vite-plugin-svgr": "^4.2.0" } - } diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 4a8ef6c..3083f1f 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -7,6 +7,7 @@ import { inject } from '@vercel/analytics'; import { useMediaQuery } from './hooks'; import { useState } from 'react'; import Setting from './settings'; +import './locale/i18n'; inject(); diff --git a/frontend/src/conversation/Conversation.tsx b/frontend/src/conversation/Conversation.tsx index 05c8638..218e853 100644 --- a/frontend/src/conversation/Conversation.tsx +++ b/frontend/src/conversation/Conversation.tsx @@ -14,7 +14,7 @@ import { import Send from './../assets/send.svg'; import SendDark from './../assets/send_dark.svg'; import Spinner from './../assets/spinner.svg'; -import SpinnerDark from './../assets/spinner-dark.svg' +import SpinnerDark from './../assets/spinner-dark.svg'; import { FEEDBACK, Query } from './conversationModels'; import { sendFeedback } from './conversationApi'; import ArrowDown from './../assets/arrow-down.svg'; diff --git a/frontend/src/locale/en.json b/frontend/src/locale/en.json new file mode 100644 index 0000000..22a51a2 --- /dev/null +++ b/frontend/src/locale/en.json @@ -0,0 +1,39 @@ +{ + "language": "English", + "chat":"Chat", + "newChat":"New Chat", + "myPlan":"My Plan", + "about":"About", + "inputPlaceholder":"Type your message here...", + "tagline":"DocsGPT uses GenAI, please review critial information using sources.", + "sourceDocs":"Source Docs", + "settings":{ + "label":"Settings", + "general":{ + "label":"General", + "selectTheme":"Select Theme", + "light":"Light", + "dark":"Dark", + "selectLanguage":"Select Language", + "chunks":"Chunks processed per query", + "prompt":"Active Prompt", + "deleteAllLabel":"Delete all Conversation", + "deleteAllBtn":"Delete all", + "addNew":"Add New" + }, + "documents":{ + "label":"Documents", + "name":"Document Name", + "date":"Vector Date", + "type":"Type", + "tokenUsage":"Token Usage" + }, + "apiKeys":{ + "label":"API Keys", + "name":"Name", + "key":"API Key", + "sourceDoc":"Source Document", + "createNew":"Create New" + } + } +} diff --git a/frontend/src/locale/es.json b/frontend/src/locale/es.json new file mode 100644 index 0000000..3d03bc3 --- /dev/null +++ b/frontend/src/locale/es.json @@ -0,0 +1,39 @@ +{ + "language": "Spanish", + "chat": "Chat", + "newChat": "Nuevo Chat", + "myPlan": "Mi Plan", + "about": "Acerca de", + "inputPlaceholder": "Escribe tu mensaje aquí...", + "tagline": "DocsGPT utiliza GenAI, por favor revisa información crítica utilizando fuentes.", + "sourceDocs": "Documentos Fuente", + "settings": { + "label": "Configuración", + "general": { + "label":"General", + "selectTheme": "Seleccionar Tema", + "light":"de luz", + "dark":"oscura", + "selectLanguage": "Seleccionar Idioma", + "chunks": "Trozos procesados por consulta", + "prompt": "Prompt Activo", + "deleteAllLabel": "Eliminar toda la Conversación", + "deleteAllBtn": "Eliminar todo", + "addNew": "Agregar Nuevo" + }, + "documents": { + "label":"Documentos", + "name": "Nombre del Documento", + "date": "Fecha Vector", + "type": "Tipo", + "tokenUsage": "Uso de Tokens" + }, + "apiKeys": { + "label":"Claves API", + "name": "Nombre", + "key": "Clave de API", + "sourceDoc": "Documento Fuente", + "createNew": "Crear Nuevo" + } + } +} diff --git a/frontend/src/locale/i18n.ts b/frontend/src/locale/i18n.ts new file mode 100644 index 0000000..6c170f8 --- /dev/null +++ b/frontend/src/locale/i18n.ts @@ -0,0 +1,21 @@ +import i18n from 'i18next'; +import { initReactI18next } from 'react-i18next'; + +import en from './en.json'; //English +import es from './es.json'; //Spanish + +i18n.use(initReactI18next).init({ + resources: { + en: { + translation: en, + }, + es: { + translation: es, + }, + }, +}); + +const locale = localStorage.getItem('docsgpt-locale') ?? 'en'; +i18n.changeLanguage(locale); + +export default i18n; diff --git a/frontend/src/modals/index.tsx b/frontend/src/modals/index.tsx index a13d703..235162a 100644 --- a/frontend/src/modals/index.tsx +++ b/frontend/src/modals/index.tsx @@ -19,11 +19,11 @@ const Modal = (props: ModalProps) => { } absolute z-30 h-screen w-screen bg-gray-alpha`} > {props.render()} -
+
diff --git a/frontend/src/settings/APIKeys.tsx b/frontend/src/settings/APIKeys.tsx index b7a98c8..54a54dd 100644 --- a/frontend/src/settings/APIKeys.tsx +++ b/frontend/src/settings/APIKeys.tsx @@ -9,13 +9,14 @@ import { import { selectSourceDocs } from '../preferences/preferenceSlice'; import Exit from '../assets/exit.svg'; import Trash from '../assets/trash.svg'; - +import { useTranslation } from 'react-i18next'; const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com'; const embeddingsName = import.meta.env.VITE_EMBEDDINGS_NAME || 'huggingface_sentence-transformers/all-mpnet-base-v2'; const APIKeys: React.FC = () => { + const { t } = useTranslation(); const [isCreateModalOpen, setCreateModal] = React.useState(false); const [isSaveKeyModalOpen, setSaveKeyModal] = React.useState(false); const [newKey, setNewKey] = React.useState(''); @@ -97,7 +98,7 @@ const APIKeys: React.FC = () => { onClick={() => setCreateModal(true)} className="rounded-full bg-purple-30 px-4 py-3 text-white hover:bg-[#6F3FD1]" > - Create new + {t('settings.apiKeys.createNew')}
{isCreateModalOpen && ( @@ -117,11 +118,15 @@ const APIKeys: React.FC = () => { - + + - diff --git a/frontend/src/settings/Documents.tsx b/frontend/src/settings/Documents.tsx index c7e7e83..e73ce73 100644 --- a/frontend/src/settings/Documents.tsx +++ b/frontend/src/settings/Documents.tsx @@ -1,10 +1,12 @@ import { DocumentsProps } from '../models/misc'; import Trash from '../assets/trash.svg'; import PropTypes from 'prop-types'; +import { useTranslation } from 'react-i18next'; const Documents: React.FC = ({ documents, handleDeleteDocument, }) => { + const { t } = useTranslation(); return (
@@ -12,10 +14,18 @@ const Documents: React.FC = ({
Name + {t('settings.apiKeys.name')} + + {t('settings.apiKeys.sourceDoc')} + - Source document + {t('settings.apiKeys.key')} API Key
- - - - + + + + diff --git a/frontend/src/settings/General.tsx b/frontend/src/settings/General.tsx index 8801376..470b6d3 100644 --- a/frontend/src/settings/General.tsx +++ b/frontend/src/settings/General.tsx @@ -1,7 +1,8 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import Prompts from './Prompts'; import { useDarkTheme } from '../hooks'; +import { useTranslation } from 'react-i18next'; import Dropdown from '../components/Dropdown'; import { selectPrompt, @@ -14,8 +15,22 @@ import { const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com'; const General: React.FC = () => { - const themes = ['Light', 'Dark']; - const languages = ['English']; + const { + t, + i18n: { changeLanguage, language }, + } = useTranslation(); + const themes = [t('settings.general.light'), t('settings.general.dark')]; + + const languageOptions = [ + { + label: 'English', + value: 'en', + }, + { + label: 'Spanish', + value: 'es', + }, + ]; const chunks = ['0', '2', '4', '6', '8', '10']; const [prompts, setPrompts] = React.useState< { name: string; id: string; type: string }[] @@ -23,12 +38,18 @@ const General: React.FC = () => { const selectedChunks = useSelector(selectChunks); const [isDarkTheme, toggleTheme] = useDarkTheme(); const [selectedTheme, setSelectedTheme] = React.useState( - isDarkTheme ? 'Dark' : 'Light', + isDarkTheme ? t('settings.general.dark') : t('settings.general.light'), ); const dispatch = useDispatch(); - const [selectedLanguage, setSelectedLanguage] = React.useState(languages[0]); + const locale = localStorage.getItem('docsgpt-locale'); + const [selectedLanguage, setSelectedLanguage] = React.useState( + locale ? languageOptions.find((option) => option.value === locale) : 'en', + ); const selectedPrompt = useSelector(selectPrompt); - + useEffect(() => { + console.log(selectedLanguage); + console.log(language); + }, [selectedLanguage]); React.useEffect(() => { const fetchPrompts = async () => { try { @@ -48,7 +69,9 @@ const General: React.FC = () => { return (
-

Select Theme

+

+ {t('settings.general.selectTheme')} +

{

- Select Language + {t('settings.general.selectLanguage')}

{ + setSelectedLanguage(selectedOption); + changeLanguage(selectedOption.value); + localStorage.setItem('docsgpt-locale', selectedOption.value); + }} size="w-56" rounded="3xl" border="border" @@ -76,7 +103,7 @@ const General: React.FC = () => {

- Chunks processed per query + {t('settings.general.chunks')}

{

- Delete all conversations + {t('settings.general.deleteAllLabel')}

diff --git a/frontend/src/settings/Prompts.tsx b/frontend/src/settings/Prompts.tsx index e5af189..2bae07e 100644 --- a/frontend/src/settings/Prompts.tsx +++ b/frontend/src/settings/Prompts.tsx @@ -2,9 +2,8 @@ import React from 'react'; import { PromptProps, ActiveState } from '../models/misc'; import Dropdown from '../components/Dropdown'; import PromptsModal from '../preferences/PromptsModal'; - +import { useTranslation } from 'react-i18next'; const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com'; - const Prompts: React.FC = ({ prompts, selectedPrompt, @@ -34,7 +33,10 @@ const Prompts: React.FC = ({ }); const [modalType, setModalType] = React.useState<'ADD' | 'EDIT'>('ADD'); const [modalState, setModalState] = React.useState('INACTIVE'); - + const { + t, + i18n: { changeLanguage, language }, + } = useTranslation(); const handleAddPrompt = async () => { try { const response = await fetch(`${apiHost}/api/create_prompt`, { @@ -158,7 +160,9 @@ const Prompts: React.FC = ({
-

Active Prompt

+

+ {t('settings.general.prompt')} +

= ({ setModalState('ACTIVE'); }} > - Add new + {t('settings.general.addNew')}
diff --git a/frontend/src/settings/index.tsx b/frontend/src/settings/index.tsx index 1c0fb82..9c0714c 100644 --- a/frontend/src/settings/index.tsx +++ b/frontend/src/settings/index.tsx @@ -11,12 +11,18 @@ import { import { Doc } from '../preferences/preferenceApi'; import ArrowLeft from '../assets/arrow-left.svg'; import ArrowRight from '../assets/arrow-right.svg'; +import { useTranslation } from 'react-i18next'; const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com'; const Settings: React.FC = () => { const dispatch = useDispatch(); - const tabs = ['General', 'Documents', 'API Keys']; + const { t } = useTranslation(); + const tabs = [ + t('settings.general.label'), + t('settings.documents.label'), + t('settings.apiKeys.label'), + ]; const [activeTab, setActiveTab] = React.useState('General'); const [widgetScreenshot, setWidgetScreenshot] = React.useState( null, @@ -45,7 +51,7 @@ const Settings: React.FC = () => { return (

- Settings + {t('settings.label')}

@@ -100,9 +106,9 @@ const Settings: React.FC = () => { function renderActiveTab() { switch (activeTab) { - case 'General': + case t('settings.general.label'): return ; - case 'Documents': + case t('settings.documents.label'): return ( { onWidgetScreenshotChange={updateWidgetScreenshot} // Add this line /> ); - case 'API Keys': + case t('settings.apiKeys.label'): return ; default: return null; From 99952a393ff332cff01ba4e8f073d6986d530d2e Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Tue, 28 May 2024 20:50:07 +0530 Subject: [PATCH 2/6] feat(i18n): modals, Hero, Nav --- frontend/src/Hero.tsx | 55 ++++----- frontend/src/Navigation.tsx | 13 ++- frontend/src/components/SourceDropdown.tsx | 6 +- frontend/src/conversation/Conversation.tsx | 6 +- frontend/src/locale/en.json | 126 +++++++++++++++------ frontend/src/locale/es.json | 66 ++++++++++- frontend/src/modals/DeleteConvModal.tsx | 8 +- frontend/src/settings/APIKeys.tsx | 26 +++-- frontend/src/settings/General.tsx | 11 +- frontend/src/upload/Upload.tsx | 45 ++++---- 10 files changed, 239 insertions(+), 123 deletions(-) diff --git a/frontend/src/Hero.tsx b/frontend/src/Hero.tsx index cd6d439..a58327e 100644 --- a/frontend/src/Hero.tsx +++ b/frontend/src/Hero.tsx @@ -1,28 +1,15 @@ import DocsGPT3 from './assets/cute_docsgpt3.svg'; -const demos: { header: string; query: string }[] = [ - { - header: 'Learn about DocsGPT', - query: 'What is DocsGPT?', - }, - { - header: 'Summarise documentation', - query: 'Summarise current context', - }, - { - header: 'Write Code', - query: 'Write code for api request to /api/answer', - }, - { - header: 'Learning Assistance', - query: 'Write potential questions for context', - }, -]; - +import { useTranslation } from 'react-i18next'; export default function Hero({ handleQuestion, }: { handleQuestion: (question: string) => void; }) { + const { t } = useTranslation(); + const demos = t('demo', { returnObjects: true }) as Array<{ + header: string; + query: string; + }>; return (
- {demos.map((demo) => ( - <> - - - ))} + {demos?.map( + (demo: { header: string; query: string }) => + demo.header && + demo.query && ( + <> + + + ), + )}
); diff --git a/frontend/src/Navigation.tsx b/frontend/src/Navigation.tsx index 9c5df17..76e0960 100644 --- a/frontend/src/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -39,7 +39,7 @@ import SelectDocsModal from './preferences/SelectDocsModal'; import ConversationTile from './conversation/ConversationTile'; import { useDarkTheme } from './hooks'; import SourceDropdown from './components/SourceDropdown'; - +import { useTranslation } from 'react-i18next'; interface NavigationProps { navOpen: boolean; setNavOpen: React.Dispatch>; @@ -70,6 +70,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { const { isMobile } = useMediaQuery(); const [isDarkTheme] = useDarkTheme(); const [isDocsListOpen, setIsDocsListOpen] = useState(false); + const { t } = useTranslation(); const isApiKeySet = useSelector(selectApiKeyStatus); const [apiKeyModalState, setApiKeyModalState] = @@ -265,14 +266,14 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { className="opacity-80 group-hover:opacity-100" />

- New Chat + {t('newChat')}

{conversations && conversations.length > 0 ? (
-

Chats

+

{t('chats')}

{conversations?.map((conversation) => ( @@ -310,7 +311,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { onClick={() => setUploadModalState('ACTIVE')} >
-

Source Docs

+

{t('sourceDocs')}

- Settings + {t('settings.label')}

@@ -345,7 +346,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { alt="icon" className="ml-2 w-5 filter dark:invert" /> -

About

+

{t('about')}

diff --git a/frontend/src/conversation/Conversation.tsx b/frontend/src/conversation/Conversation.tsx index 218e853..cf4949e 100644 --- a/frontend/src/conversation/Conversation.tsx +++ b/frontend/src/conversation/Conversation.tsx @@ -17,6 +17,7 @@ import Spinner from './../assets/spinner.svg'; import SpinnerDark from './../assets/spinner-dark.svg'; import { FEEDBACK, Query } from './conversationModels'; import { sendFeedback } from './conversationApi'; +import { useTranslation } from 'react-i18next'; import ArrowDown from './../assets/arrow-down.svg'; export default function Conversation() { const queries = useSelector(selectQueries); @@ -28,6 +29,7 @@ export default function Conversation() { const [hasScrolledToLast, setHasScrolledToLast] = useState(true); const fetchStream = useRef(null); const [eventInterrupt, setEventInterrupt] = useState(false); + const { t } = useTranslation(); const handleUserInterruption = () => { if (!eventInterrupt && status === 'loading') setEventInterrupt(true); @@ -177,7 +179,7 @@ export default function Conversation() { id="inputbox" ref={inputRef} tabIndex={1} - placeholder="Type your message here..." + placeholder={t('inputPlaceholder')} contentEditable onPaste={handlePaste} className={`max-h-24 min-h-[3.8rem] w-full overflow-y-auto overflow-x-hidden whitespace-pre-wrap rounded-full bg-white py-2 pl-4 pr-9 text-base leading-10 opacity-100 focus:outline-none dark:bg-raisin-black dark:text-bright-gray`} @@ -212,7 +214,7 @@ export default function Conversation() { )}

- DocsGPT uses GenAI, please review critial information using sources. + {t('tagline')}

diff --git a/frontend/src/locale/en.json b/frontend/src/locale/en.json index 22a51a2..6d4fe8e 100644 --- a/frontend/src/locale/en.json +++ b/frontend/src/locale/en.json @@ -1,39 +1,99 @@ { "language": "English", - "chat":"Chat", - "newChat":"New Chat", - "myPlan":"My Plan", - "about":"About", - "inputPlaceholder":"Type your message here...", - "tagline":"DocsGPT uses GenAI, please review critial information using sources.", - "sourceDocs":"Source Docs", - "settings":{ - "label":"Settings", - "general":{ - "label":"General", - "selectTheme":"Select Theme", - "light":"Light", - "dark":"Dark", - "selectLanguage":"Select Language", - "chunks":"Chunks processed per query", - "prompt":"Active Prompt", - "deleteAllLabel":"Delete all Conversation", - "deleteAllBtn":"Delete all", - "addNew":"Add New" - }, - "documents":{ - "label":"Documents", - "name":"Document Name", - "date":"Vector Date", - "type":"Type", - "tokenUsage":"Token Usage" - }, - "apiKeys":{ - "label":"API Keys", + "chat": "Chat", + "newChat": "New Chat", + "myPlan": "My Plan", + "about": "About", + "inputPlaceholder": "Type your message here...", + "tagline": "DocsGPT uses GenAI, please review critial information using sources.", + "sourceDocs": "Source Docs", + "none":"None", + "demo":[ + { + "header": "Learn about DocsGPT", + "query": "What is DocsGPT?" + }, + { + "header": "Summarise documentation", + "query": "Summarise current context" + }, + { + "header": "Write Code", + "query": "Write code for api request to /api/answer" + }, + { + "header": "Learning Assistance", + "query": "Write potential questions for context" + } + ], + "settings": { + "label": "Settings", + "general": { + "label": "General", + "selectTheme": "Select Theme", + "light": "Light", + "dark": "Dark", + "selectLanguage": "Select Language", + "chunks": "Chunks processed per query", + "prompt": "Active Prompt", + "deleteAllLabel": "Delete all Conversation", + "deleteAllBtn": "Delete all", + "addNew": "Add New" + }, + "documents": { + "label": "Documents", + "name": "Document Name", + "date": "Vector Date", + "type": "Type", + "tokenUsage": "Token Usage" + }, + "apiKeys": { + "label": "API Keys", + "name": "Name", + "key": "API Key", + "sourceDoc": "Source Document", + "createNew": "Create New" + } + }, + "modals":{ + "uploadDoc":{ + "label":"Upload New Documentation", + "file":"From File", + "remote":"Remote", "name":"Name", - "key":"API Key", - "sourceDoc":"Source Document", - "createNew":"Create New" + "choose":"Choose Files", + "info":"Please upload .pdf, .txt, .rst, .docx, .md, .zip limited to 25mb", + "uploadedFiles":"Uploaded Files", + "cancel":"Cancel", + "train":"Train", + "link":"Link", + "urlLink":"URL Link", + "reddit":{ + "id":"Client ID", + "secret":"Client Secret", + "agent":"User agent", + "searchQueries":"Search queries", + "numberOfPosts":"Number of posts" + } + }, + "createAPIKey":{ + "label":"Create New API Key", + "apiKeyName":"API Key Name", + "chunks":"Chunks processed per query", + "prompt":"Select active prompt", + "sourceDoc":"Source document", + "create":"Create" + }, + "saveKey":{ + "note":"Please save your Key", + "disclaimer":"This is the only time your key will be shown.", + "copy":"Copy", + "copied":"Copied", + "confirm":"I saved the Key" + }, + "deleteConv":{ + "confirm":"Are you sure you want to delete all the conversations?", + "delete":"Delete" } } } diff --git a/frontend/src/locale/es.json b/frontend/src/locale/es.json index 3d03bc3..f643b1d 100644 --- a/frontend/src/locale/es.json +++ b/frontend/src/locale/es.json @@ -7,13 +7,32 @@ "inputPlaceholder": "Escribe tu mensaje aquí...", "tagline": "DocsGPT utiliza GenAI, por favor revisa información crítica utilizando fuentes.", "sourceDocs": "Documentos Fuente", + "none": "Nada", + "demo": [ + { + "header": "Aprende sobre DocsGPT", + "query": "¿Qué es DocsGPT?" + }, + { + "header": "Resumir documentación", + "query": "Resumir contexto actual" + }, + { + "header": "Escribir Código", + "query": "Escribir código para solicitud de API a /api/answer" + }, + { + "header": "Asistencia de Aprendizaje", + "query": "Escribe posibles preguntas para el contexto" + } + ], "settings": { "label": "Configuración", "general": { - "label":"General", + "label": "General", "selectTheme": "Seleccionar Tema", - "light":"de luz", - "dark":"oscura", + "light": "de luz", + "dark": "oscura", "selectLanguage": "Seleccionar Idioma", "chunks": "Trozos procesados por consulta", "prompt": "Prompt Activo", @@ -22,18 +41,55 @@ "addNew": "Agregar Nuevo" }, "documents": { - "label":"Documentos", + "label": "Documentos", "name": "Nombre del Documento", "date": "Fecha Vector", "type": "Tipo", "tokenUsage": "Uso de Tokens" }, "apiKeys": { - "label":"Claves API", + "label": "Claves API", "name": "Nombre", "key": "Clave de API", "sourceDoc": "Documento Fuente", "createNew": "Crear Nuevo" } + }, + "modals": { + "uploadDoc": { + "label": "Subir Nueva Documentación", + "file": "Desde Archivo", + "remote": "Remota", + "name": "Nombre", + "choose": "Seleccionar Archivos", + "info": "Por favor, suba archivos .pdf, .txt, .rst, .docx, .md, .zip limitados a 25 MB", + "uploadedFiles": "Archivos Subidos", + "cancel": "Cancelar", + "train": "Entrenar", + "link": "Enlace", + "urlLink": "Enlace URL", + "reddit": { + "id": "ID de Cliente", + "secret": "Secreto de Cliente", + "agent": "Agente de Usuario", + "searchQueries": "Consultas de Búsqueda", + "numberOfPosts": "Número de publicaciones" + } + }, + "createAPIKey": { + "label": "Crear Nueva Clave de API", + "apiKeyName": "Nombre de la Clave de API", + "chunks": "Fragmentos procesados por consulta", + "prompt": "Seleccione el prompt activo", + "sourceDoc": "Documento Fuente", + "create": "Crear" + }, + "saveKey": { + "note": "Por favor, guarde su Clave", + "disclaimer": "Esta es la única vez que se mostrará su clave.", + "copy": "Copiar", + "copied": "Copiado", + "confirm": "He guardado la Clave" + } } } diff --git a/frontend/src/modals/DeleteConvModal.tsx b/frontend/src/modals/DeleteConvModal.tsx index 4371fc1..c2fc5e3 100644 --- a/frontend/src/modals/DeleteConvModal.tsx +++ b/frontend/src/modals/DeleteConvModal.tsx @@ -3,7 +3,7 @@ import { useDispatch } from 'react-redux'; import { ActiveState } from '../models/misc'; import { useMediaQuery, useOutsideAlerter } from '../hooks'; import ConfirmationModal from './ConfirmationModal'; - +import { useTranslation } from 'react-i18next'; import { Action } from '@reduxjs/toolkit'; export default function DeleteConvModal({ @@ -18,7 +18,7 @@ export default function DeleteConvModal({ const modalRef = React.useRef(null); const dispatch = useDispatch(); const { isMobile } = useMediaQuery(); - + const { t } = useTranslation(); useOutsideAlerter( modalRef, () => { @@ -40,10 +40,10 @@ export default function DeleteConvModal({ return ( diff --git a/frontend/src/settings/APIKeys.tsx b/frontend/src/settings/APIKeys.tsx index 54a54dd..8264af0 100644 --- a/frontend/src/settings/APIKeys.tsx +++ b/frontend/src/settings/APIKeys.tsx @@ -221,7 +221,7 @@ const CreateAPIKeyModal: React.FC = ({ }; }) : []; - + const { t } = useTranslation(); return (
@@ -230,12 +230,12 @@ const CreateAPIKeyModal: React.FC = ({
- Create New API Key + {t('modals.createAPIKey.label')}
- API Key Name + {t('modals.createAPIKey.apiKeyName')} = ({
setSourcePath(selection) @@ -260,7 +260,7 @@ const CreateAPIKeyModal: React.FC = ({ setPrompt(value) } @@ -269,7 +269,7 @@ const CreateAPIKeyModal: React.FC = ({

- Chunks processed per query + {t('modals.createAPIKey.chunks')}

= ({ } className="float-right mt-4 rounded-full bg-purple-30 px-5 py-2 text-sm text-white hover:bg-[#6F3FD1] disabled:opacity-50" > - Create + {t('modals.createAPIKey.create')}
@@ -301,6 +301,7 @@ const CreateAPIKeyModal: React.FC = ({ const SaveAPIKeyModal: React.FC = ({ apiKey, close }) => { const [isCopied, setIsCopied] = React.useState(false); + const { t } = useTranslation(); const handleCopyKey = () => { navigator.clipboard.writeText(apiKey); setIsCopied(true); @@ -311,9 +312,12 @@ const SaveAPIKeyModal: React.FC = ({ apiKey, close }) => { -

Please save your Key

+

+ {' '} + {t('modals.saveKey.note')} +

- This is the only time your key will be shown. + {t('modals.saveKey.disclaimer')}

@@ -324,14 +328,14 @@ const SaveAPIKeyModal: React.FC = ({ apiKey, close }) => { className="my-1 h-10 w-20 rounded-full border border-solid border-purple-30 p-2 text-sm text-purple-30 hover:bg-purple-30 hover:text-white" onClick={handleCopyKey} > - {isCopied ? 'Copied' : 'Copy'} + {isCopied ? t('modals.saveKey.copied') : t('modals.saveKey.copy')}
diff --git a/frontend/src/settings/General.tsx b/frontend/src/settings/General.tsx index 470b6d3..82693aa 100644 --- a/frontend/src/settings/General.tsx +++ b/frontend/src/settings/General.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React from 'react'; import { useSelector, useDispatch } from 'react-redux'; import Prompts from './Prompts'; import { useDarkTheme } from '../hooks'; @@ -19,7 +19,7 @@ const General: React.FC = () => { t, i18n: { changeLanguage, language }, } = useTranslation(); - const themes = [t('settings.general.light'), t('settings.general.dark')]; + const themes = ['Light', 'Dark']; const languageOptions = [ { @@ -38,7 +38,7 @@ const General: React.FC = () => { const selectedChunks = useSelector(selectChunks); const [isDarkTheme, toggleTheme] = useDarkTheme(); const [selectedTheme, setSelectedTheme] = React.useState( - isDarkTheme ? t('settings.general.dark') : t('settings.general.light'), + isDarkTheme ? 'Dark' : 'Light', ); const dispatch = useDispatch(); const locale = localStorage.getItem('docsgpt-locale'); @@ -46,10 +46,7 @@ const General: React.FC = () => { locale ? languageOptions.find((option) => option.value === locale) : 'en', ); const selectedPrompt = useSelector(selectPrompt); - useEffect(() => { - console.log(selectedLanguage); - console.log(language); - }, [selectedLanguage]); + React.useEffect(() => { const fetchPrompts = async () => { try { diff --git a/frontend/src/upload/Upload.tsx b/frontend/src/upload/Upload.tsx index 605b4fa..6437acc 100644 --- a/frontend/src/upload/Upload.tsx +++ b/frontend/src/upload/Upload.tsx @@ -6,7 +6,7 @@ import { ActiveState } from '../models/misc'; import { getDocs } from '../preferences/preferenceApi'; import { setSourceDocs } from '../preferences/preferenceSlice'; import Dropdown from '../components/Dropdown'; - +import { useTranslation } from 'react-i18next'; export default function Upload({ modalState, setModalState, @@ -24,6 +24,7 @@ export default function Upload({ search_queries: [''], number_posts: 10, }); + const { t } = useTranslation(); const urlOptions: { label: string; value: string }[] = [ { label: 'Crawler', value: 'crawler' }, // { label: 'Sitemap', value: 'sitemap' }, @@ -238,7 +239,7 @@ export default function Upload({ view = ( <>

- Upload New Documentation + {t('modals.uploadDoc.label')}

{activeTab === 'file' && ( @@ -272,21 +273,21 @@ export default function Upload({ >
- Name + {t('modals.uploadDoc.name')}
- Choose Files + {t('modals.uploadDoc.choose')}

- Please upload .pdf, .txt, .rst, .docx, .md, .zip limited to 25mb + {t('modals.uploadDoc.info')}

- Uploaded Files + {t('modals.uploadDoc.uploadedFiles')}

{files.map((file) => (

@@ -294,7 +295,9 @@ export default function Upload({

))} {files.length === 0 && ( -

None

+

+ {t('none')} +

)}
@@ -313,7 +316,7 @@ export default function Upload({ {urlType.label !== 'Reddit' ? ( <>
- Name + {t('modals.uploadDoc.name')}
- Link + {t('modals.uploadDoc.link')}
@@ -349,7 +352,7 @@ export default function Upload({ >
- Client ID + {t('modals.uploadDoc.reddit.id')}
- Client secret + {t('modals.uploadDoc.reddit.secret')}
- User agent + {t('modals.uploadDoc.reddit.agent')}
- Search queries + {t('modals.uploadDoc.reddit.searchQueries')}
- Number of posts + {t('modals.uploadDoc.reddit.numberOfPosts')}
@@ -422,14 +425,14 @@ export default function Upload({ activeTab === 'file' } > - Train + {t('modals.uploadDoc.train')} ) : ( )} From fa3a9fe70eaef38ec29bab984322492f5b2f7adc Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Tue, 28 May 2024 21:35:10 +0530 Subject: [PATCH 3/6] fix: minor changes --- docs/package-lock.json | 169 ------------------------------ frontend/src/Hero.tsx | 7 +- frontend/src/locale/en.json | 75 ++++++------- frontend/src/locale/es.json | 7 +- frontend/src/modals/index.tsx | 5 +- frontend/src/settings/General.tsx | 4 +- 6 files changed, 54 insertions(+), 213 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 9c3b0b3..448e181 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -4266,69 +4266,6 @@ "node": ">=4" } }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "optional": true, - "peer": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-select/node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "optional": true, - "peer": true, - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/css-select/node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "optional": true, - "peer": true, - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/css-select/node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "optional": true, - "peer": true, - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, "node_modules/css-to-react-native": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", @@ -4339,20 +4276,6 @@ "postcss-value-parser": "^4.0.2" } }, - "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "optional": true, - "peer": true, - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, "node_modules/css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", @@ -4364,42 +4287,6 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "optional": true, - "peer": true, - "dependencies": { - "css-tree": "~2.2.0" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "optional": true, - "peer": true, - "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "optional": true, - "peer": true - }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -7078,13 +6965,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "optional": true, - "peer": true - }, "node_modules/mermaid": { "version": "10.6.1", "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.6.1.tgz", @@ -11728,42 +11608,6 @@ "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" }, - "node_modules/svgo": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz", - "integrity": "sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==", - "optional": true, - "peer": true, - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^5.1.0", - "css-tree": "^2.3.1", - "css-what": "^6.1.0", - "csso": "^5.0.5", - "picocolors": "^1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/svgo" - } - }, - "node_modules/svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "optional": true, - "peer": true, - "engines": { - "node": ">= 10" - } - }, "node_modules/term-size": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", @@ -11868,19 +11712,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, "node_modules/unified": { "version": "10.1.2", "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", diff --git a/frontend/src/Hero.tsx b/frontend/src/Hero.tsx index a58327e..69bf23a 100644 --- a/frontend/src/Hero.tsx +++ b/frontend/src/Hero.tsx @@ -1,3 +1,4 @@ +import { Fragment } from 'react'; import DocsGPT3 from './assets/cute_docsgpt3.svg'; import { useTranslation } from 'react-i18next'; export default function Hero({ @@ -24,10 +25,10 @@ export default function Hero({
{demos?.map( - (demo: { header: string; query: string }) => + (demo: { header: string; query: string }, key: number) => demo.header && demo.query && ( - <> + - + ), )}
diff --git a/frontend/src/locale/en.json b/frontend/src/locale/en.json index 6d4fe8e..4a427c6 100644 --- a/frontend/src/locale/en.json +++ b/frontend/src/locale/en.json @@ -7,8 +7,8 @@ "inputPlaceholder": "Type your message here...", "tagline": "DocsGPT uses GenAI, please review critial information using sources.", "sourceDocs": "Source Docs", - "none":"None", - "demo":[ + "none": "None", + "demo": [ { "header": "Learn about DocsGPT", "query": "What is DocsGPT?" @@ -55,45 +55,46 @@ "createNew": "Create New" } }, - "modals":{ - "uploadDoc":{ - "label":"Upload New Documentation", - "file":"From File", - "remote":"Remote", - "name":"Name", - "choose":"Choose Files", - "info":"Please upload .pdf, .txt, .rst, .docx, .md, .zip limited to 25mb", - "uploadedFiles":"Uploaded Files", - "cancel":"Cancel", - "train":"Train", - "link":"Link", - "urlLink":"URL Link", - "reddit":{ - "id":"Client ID", - "secret":"Client Secret", - "agent":"User agent", - "searchQueries":"Search queries", - "numberOfPosts":"Number of posts" + "modals": { + "uploadDoc": { + "label": "Upload New Documentation", + "file": "From File", + "remote": "Remote", + "name": "Name", + "choose": "Choose Files", + "info": "Please upload .pdf, .txt, .rst, .docx, .md, .zip limited to 25mb", + "uploadedFiles": "Uploaded Files", + "cancel": "Cancel", + "train": "Train", + "link": "Link", + "urlLink": "URL Link", + "reddit": { + "id": "Client ID", + "secret": "Client Secret", + "agent": "User agent", + "searchQueries": "Search queries", + "numberOfPosts": "Number of posts" } }, - "createAPIKey":{ - "label":"Create New API Key", - "apiKeyName":"API Key Name", - "chunks":"Chunks processed per query", - "prompt":"Select active prompt", - "sourceDoc":"Source document", - "create":"Create" + "createAPIKey": { + "label": "Create New API Key", + "apiKeyName": "API Key Name", + "chunks": "Chunks processed per query", + "prompt": "Select active prompt", + "sourceDoc": "Source document", + "create": "Create" }, - "saveKey":{ - "note":"Please save your Key", - "disclaimer":"This is the only time your key will be shown.", - "copy":"Copy", - "copied":"Copied", - "confirm":"I saved the Key" + "saveKey": { + "note": "Please save your Key", + "disclaimer": "This is the only time your key will be shown.", + "copy": "Copy", + "copied": "Copied", + "confirm": "I saved the Key" }, - "deleteConv":{ - "confirm":"Are you sure you want to delete all the conversations?", - "delete":"Delete" + "deleteConv": { + "confirm": "Are you sure you want to delete all the conversations?", + "delete": "Delete", + "cancel":"Cancel" } } } diff --git a/frontend/src/locale/es.json b/frontend/src/locale/es.json index f643b1d..820e8b7 100644 --- a/frontend/src/locale/es.json +++ b/frontend/src/locale/es.json @@ -8,6 +8,7 @@ "tagline": "DocsGPT utiliza GenAI, por favor revisa información crítica utilizando fuentes.", "sourceDocs": "Documentos Fuente", "none": "Nada", + "cancel":"Cancelar", "demo": [ { "header": "Aprende sobre DocsGPT", @@ -90,6 +91,10 @@ "copy": "Copiar", "copied": "Copiado", "confirm": "He guardado la Clave" - } + }, + "deleteConv": { + "confirm": "¿Está seguro de que desea eliminar todas las conversaciones?", + "delete": "Eliminar" + } } } diff --git a/frontend/src/modals/index.tsx b/frontend/src/modals/index.tsx index 235162a..1dcffd6 100644 --- a/frontend/src/modals/index.tsx +++ b/frontend/src/modals/index.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; - +import { useTranslation } from 'react-i18next'; interface ModalProps { handleSubmit: () => void; isCancellable: boolean; @@ -12,6 +12,7 @@ interface ModalProps { } const Modal = (props: ModalProps) => { + const { t } = useTranslation(); return (
{ onClick={() => props.handleCancel && props.handleCancel()} className="cursor-pointer rounded-3xl px-5 py-2 text-sm font-medium hover:bg-gray-100 dark:bg-transparent dark:text-light-gray dark:hover:bg-[#767183]/50" > - Cancel + {t('cancel')} )}
diff --git a/frontend/src/settings/General.tsx b/frontend/src/settings/General.tsx index 82693aa..155a7fc 100644 --- a/frontend/src/settings/General.tsx +++ b/frontend/src/settings/General.tsx @@ -43,7 +43,9 @@ const General: React.FC = () => { const dispatch = useDispatch(); const locale = localStorage.getItem('docsgpt-locale'); const [selectedLanguage, setSelectedLanguage] = React.useState( - locale ? languageOptions.find((option) => option.value === locale) : 'en', + locale + ? languageOptions.find((option) => option.value === locale) + : languageOptions[0], ); const selectedPrompt = useSelector(selectPrompt); From a585fe4d54a17e0113a2039d667a5872b77d36f7 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Tue, 28 May 2024 21:38:42 +0530 Subject: [PATCH 4/6] refactored locale json --- frontend/src/locale/en.json | 4 ++-- frontend/src/locale/es.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/locale/en.json b/frontend/src/locale/en.json index 4a427c6..414e14b 100644 --- a/frontend/src/locale/en.json +++ b/frontend/src/locale/en.json @@ -8,6 +8,7 @@ "tagline": "DocsGPT uses GenAI, please review critial information using sources.", "sourceDocs": "Source Docs", "none": "None", + "cancel":"Cancel", "demo": [ { "header": "Learn about DocsGPT", @@ -93,8 +94,7 @@ }, "deleteConv": { "confirm": "Are you sure you want to delete all the conversations?", - "delete": "Delete", - "cancel":"Cancel" + "delete": "Delete" } } } diff --git a/frontend/src/locale/es.json b/frontend/src/locale/es.json index 820e8b7..5caa315 100644 --- a/frontend/src/locale/es.json +++ b/frontend/src/locale/es.json @@ -8,7 +8,7 @@ "tagline": "DocsGPT utiliza GenAI, por favor revisa información crítica utilizando fuentes.", "sourceDocs": "Documentos Fuente", "none": "Nada", - "cancel":"Cancelar", + "cancel": "Cancelar", "demo": [ { "header": "Aprende sobre DocsGPT", @@ -95,6 +95,6 @@ "deleteConv": { "confirm": "¿Está seguro de que desea eliminar todas las conversaciones?", "delete": "Eliminar" - } + } } } From 1ae777129087dcb42f71e599da11f5e8418fab61 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Wed, 29 May 2024 03:27:53 +0530 Subject: [PATCH 5/6] add spacing in general, minor change --- frontend/src/modals/ConfirmationModal.tsx | 5 +++-- frontend/src/settings/General.tsx | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/frontend/src/modals/ConfirmationModal.tsx b/frontend/src/modals/ConfirmationModal.tsx index c5b4cf4..0b39440 100644 --- a/frontend/src/modals/ConfirmationModal.tsx +++ b/frontend/src/modals/ConfirmationModal.tsx @@ -1,6 +1,6 @@ import Exit from '../assets/exit.svg'; import { ActiveState } from '../models/misc'; - +import { useTranslation } from 'react-i18next'; function ConfirmationModal({ message, modalState, @@ -18,6 +18,7 @@ function ConfirmationModal({ cancelLabel?: string; handleCancel?: () => void; }) { + const { t } = useTranslation(); return (
- {cancelLabel ? cancelLabel : 'Cancel'} + {cancelLabel ? cancelLabel : t('cancel')} diff --git a/frontend/src/settings/General.tsx b/frontend/src/settings/General.tsx index 155a7fc..2c894c9 100644 --- a/frontend/src/settings/General.tsx +++ b/frontend/src/settings/General.tsx @@ -84,7 +84,7 @@ const General: React.FC = () => { />
-

+

{t('settings.general.selectLanguage')}

Date: Wed, 29 May 2024 11:29:00 +0100 Subject: [PATCH 6/6] chats word in translations --- frontend/src/locale/en.json | 1 + frontend/src/locale/es.json | 1 + 2 files changed, 2 insertions(+) diff --git a/frontend/src/locale/en.json b/frontend/src/locale/en.json index 414e14b..c4a9309 100644 --- a/frontend/src/locale/en.json +++ b/frontend/src/locale/en.json @@ -1,6 +1,7 @@ { "language": "English", "chat": "Chat", + "chats": "Chats", "newChat": "New Chat", "myPlan": "My Plan", "about": "About", diff --git a/frontend/src/locale/es.json b/frontend/src/locale/es.json index 5caa315..04e1bdf 100644 --- a/frontend/src/locale/es.json +++ b/frontend/src/locale/es.json @@ -1,6 +1,7 @@ { "language": "Spanish", "chat": "Chat", + "chats": "Chats", "newChat": "Nuevo Chat", "myPlan": "Mi Plan", "about": "Acerca de",
Document NameVector DateToken usageType + {t('settings.documents.name')} + + {t('settings.documents.date')} + + {t('settings.documents.tokenUsage')} + + {t('settings.documents.type')} +