diff --git a/frontend/src/About.tsx b/frontend/src/About.tsx deleted file mode 100644 index d2bbaac4..00000000 --- a/frontend/src/About.tsx +++ /dev/null @@ -1,99 +0,0 @@ -//TODO - Add hyperlinks to text -//TODO - Styling -import DocsGPT3 from './assets/cute_docsgpt3.svg'; - -export default function About() { - return ( -
-
-
-

About DocsGPT

- DocsGPT -
-

- Find the information in your documentation through AI-powered - - {' '} - open-source{' '} - - chatbot. Powered by GPT-3, Faiss and LangChain. -

- -
-

- If you want to add your own documentation, please follow the - instruction below: -

-

- 1. Navigate to{' '} - - {' '} - /application - {' '} - folder -

-

- 2. Install dependencies from{' '} - - pip install -r requirements.txt - -

-

- 3. Prepare a{' '} - .env{' '} - file. Copy{' '} - - .env_sample - {' '} - and create{' '} - .env{' '} - with your OpenAI API token -

-

- 4. Run the app with{' '} - - python app.py - -

-
- -

- Currently It uses{' '} - DocsGPT{' '} - documentation, so it will respond to information relevant to{' '} - DocsGPT. If you - want to train it on different documentation - please follow - - {' '} - this guide - - . -

- -

- If you want to launch it on your own server - follow - - {' '} - this guide - - . -

-
-
- ); -} diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 1bba5f44..0d1166b7 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -2,8 +2,6 @@ import './locale/i18n'; import { useState } from 'react'; import { Outlet, Route, Routes } from 'react-router-dom'; - -import About from './About'; import Spinner from './components/Spinner'; import Conversation from './conversation/Conversation'; import { SharedConversation } from './conversation/SharedConversation'; @@ -29,8 +27,8 @@ function AuthWrapper({ children }: { children: React.ReactNode }) { } function MainLayout() { - const { isMobile } = useMediaQuery(); - const [navOpen, setNavOpen] = useState(!isMobile); + const { isMobile, isTablet } = useMediaQuery(); + const [navOpen, setNavOpen] = useState(!(isMobile || isTablet)); return (
@@ -38,7 +36,7 @@ function MainLayout() {
} /> - } /> } /> } /> diff --git a/frontend/src/Navigation.tsx b/frontend/src/Navigation.tsx index f545d38c..57c5de45 100644 --- a/frontend/src/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -71,7 +71,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { const sharedAgents = useSelector(selectSharedAgents); const selectedAgent = useSelector(selectSelectedAgent); - const { isMobile } = useMediaQuery(); + const { isMobile, isTablet } = useMediaQuery(); const [isDarkTheme] = useDarkTheme(); const { showTokenModal, handleTokenSubmit } = useTokenAuth(); @@ -162,7 +162,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { const handleAgentClick = (agent: Agent) => { resetConversation(); dispatch(setSelectedAgent(agent)); - if (isMobile) setNavOpen(!navOpen); + if (isMobile || isTablet) setNavOpen(!navOpen); navigate('/'); }; @@ -197,6 +197,9 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { query: { conversationId: index }, }), ); + if (isMobile || isTablet) { + setNavOpen(false); + } if (data.agent_id) { if (data.is_shared_usage) { userService @@ -271,8 +274,8 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { } useEffect(() => { - setNavOpen(!isMobile); - }, [isMobile]); + setNavOpen(!(isMobile || isTablet)); + }, [isMobile, isTablet]); useDefaultDocument(); return ( @@ -352,7 +355,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { { - if (isMobile) { + if (isMobile || isTablet) { setNavOpen(!navOpen); } resetConversation(); @@ -415,7 +418,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {

- Manage Agents + {t('manageAgents')}

@@ -456,7 +462,13 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { ) : (
navigate('/agents')} + onClick={() => { + if (isMobile || isTablet) { + setNavOpen(false); + } + dispatch(setSelectedAgent(null)); + navigate('/agents'); + }} >

- Manage Agents + {t('manageAgents')}

)} @@ -502,8 +514,8 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
{ - if (isMobile) { - setNavOpen(!navOpen); + if (isMobile || isTablet) { + setNavOpen(false); } resetConversation(); }} diff --git a/frontend/src/components/SourcesPopup.tsx b/frontend/src/components/SourcesPopup.tsx index 83966730..bdfb7538 100644 --- a/frontend/src/components/SourcesPopup.tsx +++ b/frontend/src/components/SourcesPopup.tsx @@ -207,7 +207,7 @@ export default function SourcesPopup({ className="inline-flex items-center gap-2 text-base font-medium text-violets-are-blue" onClick={onClose} > - Go to Documents + {t('settings.documents.goToDocuments')} Redirect
@@ -217,7 +217,7 @@ export default function SourcesPopup({ onClick={handleUploadClick} className="w-auto rounded-full border border-violets-are-blue px-4 py-2 text-[14px] font-medium text-violets-are-blue transition-colors duration-200 hover:bg-violets-are-blue hover:text-white" > - Upload new + {t('settings.documents.uploadNew')} diff --git a/frontend/src/hooks/index.ts b/frontend/src/hooks/index.ts index bffcfb5c..1b9f9b87 100644 --- a/frontend/src/hooks/index.ts +++ b/frontend/src/hooks/index.ts @@ -35,8 +35,8 @@ export function useOutsideAlerter( export function useMediaQuery() { const mobileQuery = '(max-width: 768px)'; - const tabletQuery = '(max-width: 1024px)'; // Tablet breakpoint at 1024px - const desktopQuery = '(min-width: 1025px)'; // Desktop starts after tablet + const tabletQuery = '(max-width: 1023px)'; + const desktopQuery = '(min-width: 1024px)'; const [isMobile, setIsMobile] = useState(false); const [isTablet, setIsTablet] = useState(false); const [isDesktop, setIsDesktop] = useState(false); diff --git a/frontend/src/locale/en.json b/frontend/src/locale/en.json index d5aa7d85..7fda12c8 100644 --- a/frontend/src/locale/en.json +++ b/frontend/src/locale/en.json @@ -77,7 +77,9 @@ "backToAll": "Back to all documents", "chunks": "Chunks", "noChunks": "No chunks found", - "noChunksAlt": "No chunks found" + "noChunksAlt": "No chunks found", + "goToDocuments": "Go to Documents", + "uploadNew": "Upload new" }, "apiKeys": { "label": "Chatbots", @@ -138,7 +140,7 @@ "addAction": "Add action", "noActionsFound": "No actions found", "url": "URL", - "urlPlaceholder": "Enter url", + "urlPlaceholder": "Enter URL", "method": "Method", "description": "Description", "descriptionPlaceholder": "Enter description", @@ -146,15 +148,20 @@ "queryParameters": "Query Parameters", "body": "Body", "deleteActionWarning": "Are you sure you want to delete the action \"{{name}}\"?", - "backToTools": "Back to Tools", + "backToAllTools": "Back to all tools", "save": "Save", - "name": "Name", - "type": "Type", + "fieldName": "Field Name", + "fieldType": "Field Type", "filledByLLM": "Filled by LLM", + "fieldDescription": "Field description", "value": "Value", "addProperty": "Add property", - "propertyName": "Property name", - "noProperties": "No properties" + "propertyName": "New property key", + "add": "Add", + "cancel": "Cancel", + "addNew": "Add New", + "name": "Name", + "type": "Type" } }, "modals": { @@ -239,6 +246,18 @@ "promptText": "Prompt Text", "save": "Save", "nameExists": "Name already exists" + }, + "chunk": { + "add": "Add Chunk", + "edit": "Edit Chunk", + "title": "Title", + "enterTitle": "Enter title", + "bodyText": "Body text", + "promptText": "Prompt Text", + "update": "Update", + "close": "Close", + "delete": "Delete", + "deleteConfirmation": "Are you sure you want to delete this chunk?" } }, "sharedConv": { diff --git a/frontend/src/locale/es.json b/frontend/src/locale/es.json index 90ce0844..2f0260b0 100644 --- a/frontend/src/locale/es.json +++ b/frontend/src/locale/es.json @@ -11,6 +11,7 @@ "help": "Asistencia", "emailUs": "Envíanos un correo", "documentation": "Documentación", + "manageAgents": "Administrar Agentes", "demo": [ { "header": "Aprende sobre DocsGPT", @@ -48,7 +49,8 @@ "medium": "Medio", "high": "Alto", "unlimited": "Ilimitado", - "default": "Predeterminado" + "default": "Predeterminado", + "addNew": "Añadir Nuevo" }, "documents": { "title": "Esta tabla contiene todos los documentos que están disponibles para ti y los que has subido", @@ -75,7 +77,9 @@ "backToAll": "Volver a todos los documentos", "chunks": "Fragmentos", "noChunks": "No se encontraron fragmentos", - "noChunksAlt": "No se encontraron fragmentos" + "noChunksAlt": "No se encontraron fragmentos", + "goToDocuments": "Ir a Documentos", + "uploadNew": "Subir nuevo" }, "apiKeys": { "label": "Chatbots", @@ -144,15 +148,20 @@ "queryParameters": "Parámetros de Consulta", "body": "Cuerpo", "deleteActionWarning": "¿Estás seguro de que deseas eliminar la acción \"{{name}}\"?", - "backToTools": "Volver a Herramientas", "save": "Guardar", "name": "Nombre", "type": "Tipo", "filledByLLM": "Completado por LLM", "value": "Valor", "addProperty": "Agregar propiedad", - "propertyName": "Nombre de propiedad", - "noProperties": "Sin propiedades" + "propertyName": "Nueva clave de propiedad", + "backToAllTools": "Volver a todas las herramientas", + "fieldName": "Nombre del campo", + "fieldType": "Tipo de campo", + "fieldDescription": "Descripción del campo", + "add": "Añadir", + "cancel": "Cancelar", + "addNew": "Añadir Nuevo" } }, "modals": { @@ -237,6 +246,18 @@ "promptText": "Texto del Prompt", "save": "Guardar", "nameExists": "El nombre ya existe" + }, + "chunk": { + "add": "Agregar Fragmento", + "edit": "Editar Fragmento", + "title": "Título", + "enterTitle": "Ingresar título", + "bodyText": "Texto del cuerpo", + "promptText": "Texto del prompt", + "update": "Actualizar", + "close": "Cerrar", + "delete": "Eliminar", + "deleteConfirmation": "¿Estás seguro de que deseas eliminar este fragmento?" } }, "sharedConv": { @@ -270,9 +291,9 @@ }, "sources": { "title": "Fuentes", - "text": "Texto fuente", "link": "Enlace fuente", - "view_more": "Ver {{count}} más fuentes" + "view_more": "Ver {{count}} más fuentes", + "text": "Elegir tus fuentes" }, "attachments": { "attach": "Adjuntar", diff --git a/frontend/src/locale/jp.json b/frontend/src/locale/jp.json index 18e3bf4f..3c1cb64b 100644 --- a/frontend/src/locale/jp.json +++ b/frontend/src/locale/jp.json @@ -11,6 +11,7 @@ "help": "ヘルプ", "emailUs": "メールを送る", "documentation": "ドキュメント", + "manageAgents": "エージェント管理", "demo": [ { "header": "DocsGPTについて学ぶ", @@ -76,7 +77,9 @@ "backToAll": "すべてのドキュメントに戻る", "chunks": "チャンク", "noChunks": "チャンクが見つかりません", - "noChunksAlt": "チャンクが見つかりません" + "noChunksAlt": "チャンクが見つかりません", + "goToDocuments": "ドキュメントへ移動", + "uploadNew": "新規アップロード" }, "apiKeys": { "label": "チャットボット", @@ -101,7 +104,6 @@ }, "messages": "メッセージ", "tokenUsage": "トークン使用量", - "feedback": "フィードバック", "filterPlaceholder": "フィルター", "none": "なし", "positiveFeedback": "肯定的なフィードバック", @@ -146,15 +148,20 @@ "queryParameters": "クエリパラメータ", "body": "ボディ", "deleteActionWarning": "アクション \"{{name}}\" を削除してもよろしいですか?", - "backToTools": "ツールに戻る", + "backToAllTools": "すべてのツールに戻る", "save": "保存", - "name": "名前", - "type": "タイプ", + "fieldName": "フィールド名", + "fieldType": "フィールドタイプ", "filledByLLM": "LLMによる入力", + "fieldDescription": "フィールドの説明", "value": "値", "addProperty": "プロパティを追加", - "propertyName": "プロパティ名", - "noProperties": "プロパティなし" + "propertyName": "新しいプロパティキー", + "add": "追加", + "cancel": "キャンセル", + "addNew": "新規追加", + "name": "名前", + "type": "タイプ" } }, "modals": { @@ -239,6 +246,18 @@ "promptText": "プロンプトテキスト", "save": "保存", "nameExists": "名前が既に存在します" + }, + "chunk": { + "add": "チャンクを追加", + "edit": "チャンクを編集", + "title": "タイトル", + "enterTitle": "タイトルを入力", + "bodyText": "本文", + "promptText": "プロンプトテキスト", + "update": "更新", + "close": "閉じる", + "delete": "削除", + "deleteConfirmation": "このチャンクを削除してもよろしいですか?" } }, "sharedConv": { diff --git a/frontend/src/locale/ru.json b/frontend/src/locale/ru.json index 1a3b8848..8d62a577 100644 --- a/frontend/src/locale/ru.json +++ b/frontend/src/locale/ru.json @@ -11,6 +11,7 @@ "help": "Помощь", "emailUs": "Напишите нам", "documentation": "Документация", + "manageAgents": "Управление агентами", "demo": [ { "header": "Узнайте о DocsGPT", @@ -76,7 +77,9 @@ "backToAll": "Вернуться ко всем документам", "chunks": "Фрагменты", "noChunks": "Фрагменты не найдены", - "noChunksAlt": "Фрагменты не найдены" + "noChunksAlt": "Фрагменты не найдены", + "goToDocuments": "Перейти к документам", + "uploadNew": "Загрузить новый" }, "apiKeys": { "label": "API ключи", @@ -137,23 +140,28 @@ "addAction": "Добавить действие", "noActionsFound": "Действия не найдены", "url": "URL", - "urlPlaceholder": "Введите url", + "urlPlaceholder": "Введите URL", "method": "Метод", "description": "Описание", "descriptionPlaceholder": "Введите описание", "headers": "Заголовки", "queryParameters": "Параметры запроса", - "body": "Тело", + "body": "Тело запроса", "deleteActionWarning": "Вы уверены, что хотите удалить действие \"{{name}}\"?", - "backToTools": "Вернуться к инструментам", + "backToAllTools": "Вернуться ко всем инструментам", "save": "Сохранить", - "name": "Имя", - "type": "Тип", - "filledByLLM": "Заполнено LLM", + "fieldName": "Имя поля", + "fieldType": "Тип поля", + "filledByLLM": "Заполняется LLM", + "fieldDescription": "Описание поля", "value": "Значение", "addProperty": "Добавить свойство", - "propertyName": "Имя свойства", - "noProperties": "Нет свойств" + "propertyName": "Новый ключ свойства", + "add": "Добавить", + "cancel": "Отмена", + "addNew": "Добавить новое", + "name": "Имя", + "type": "Тип" } }, "modals": { @@ -238,6 +246,18 @@ "promptText": "Текст подсказки", "save": "Сохранить", "nameExists": "Название уже существует" + }, + "chunk": { + "add": "Добавить фрагмент", + "edit": "Редактировать фрагмент", + "title": "Заголовок", + "enterTitle": "Введите заголовок", + "bodyText": "Текст", + "promptText": "Текст подсказки", + "update": "Обновить", + "close": "Закрыть", + "delete": "Удалить", + "deleteConfirmation": "Вы уверены, что хотите удалить этот фрагмент?" } }, "sharedConv": { @@ -271,7 +291,7 @@ }, "sources": { "title": "Источники", - "text": "Текст источника", + "text": "Выберите ваши источники", "link": "Ссылка на источник", "view_more": "ещё {{count}} источников" }, diff --git a/frontend/src/locale/zh-TW.json b/frontend/src/locale/zh-TW.json index f20ade6b..366d0f56 100644 --- a/frontend/src/locale/zh-TW.json +++ b/frontend/src/locale/zh-TW.json @@ -11,6 +11,7 @@ "help": "幫助", "emailUs": "給我們發電郵", "documentation": "文件", + "manageAgents": "管理代理", "demo": [ { "header": "了解 DocsGPT", @@ -76,7 +77,9 @@ "backToAll": "返回所有文件", "chunks": "文本塊", "noChunks": "未找到文本塊", - "noChunksAlt": "未找到文本塊" + "noChunksAlt": "未找到文本塊", + "goToDocuments": "前往文件", + "uploadNew": "上傳新文件" }, "apiKeys": { "label": "聊天機器人", @@ -145,15 +148,20 @@ "queryParameters": "查詢參數", "body": "主體", "deleteActionWarning": "您確定要刪除操作 \"{{name}}\" 嗎?", - "backToTools": "返回工具", + "backToAllTools": "返回所有工具", "save": "儲存", - "name": "名稱", - "type": "類型", - "filledByLLM": "由LLM填寫", + "fieldName": "欄位名稱", + "fieldType": "欄位類型", + "filledByLLM": "由LLM填入", + "fieldDescription": "欄位描述", "value": "值", "addProperty": "新增屬性", - "propertyName": "屬性名稱", - "noProperties": "無屬性" + "propertyName": "新屬性鍵", + "add": "新增", + "cancel": "取消", + "addNew": "新增", + "name": "名稱", + "type": "類型" } }, "modals": { @@ -238,6 +246,18 @@ "promptText": "提示文字", "save": "儲存", "nameExists": "名稱已存在" + }, + "chunk": { + "add": "新增區塊", + "edit": "編輯區塊", + "title": "標題", + "enterTitle": "輸入標題", + "bodyText": "內文", + "promptText": "提示文字", + "update": "更新", + "close": "關閉", + "delete": "刪除", + "deleteConfirmation": "您確定要刪除此區塊嗎?" } }, "sharedConv": { diff --git a/frontend/src/locale/zh.json b/frontend/src/locale/zh.json index 22f144dd..6d4e590c 100644 --- a/frontend/src/locale/zh.json +++ b/frontend/src/locale/zh.json @@ -11,6 +11,7 @@ "help": "帮助", "emailUs": "给我们发邮件", "documentation": "文档", + "manageAgents": "管理代理", "demo": [ { "header": "了解 DocsGPT", @@ -72,7 +73,13 @@ }, "actions": "操作", "view": "查看", - "deleteWarning": "您确定要删除 \"{{name}}\" 吗?" + "deleteWarning": "您确定要删除 \"{{name}}\" 吗?", + "backToAll": "返回所有文档", + "chunks": "文本块", + "noChunks": "未找到文本块", + "noChunksAlt": "未找到文本块", + "goToDocuments": "前往文档", + "uploadNew": "上传新文档" }, "apiKeys": { "label": "聊天机器人", @@ -141,15 +148,20 @@ "queryParameters": "查询参数", "body": "请求体", "deleteActionWarning": "您确定要删除操作 \"{{name}}\" 吗?", - "backToTools": "返回工具", + "backToAllTools": "返回所有工具", "save": "保存", - "name": "名称", - "type": "类型", + "fieldName": "字段名称", + "fieldType": "字段类型", "filledByLLM": "由LLM填充", + "fieldDescription": "字段描述", "value": "值", "addProperty": "添加属性", - "propertyName": "属性名称", - "noProperties": "无属性" + "propertyName": "新属性键", + "add": "添加", + "cancel": "取消", + "addNew": "添加新的", + "name": "名称", + "type": "类型" } }, "modals": { @@ -234,6 +246,18 @@ "promptText": "提示文本", "save": "保存", "nameExists": "名称已存在" + }, + "chunk": { + "add": "添加块", + "edit": "编辑块", + "title": "标题", + "enterTitle": "输入标题", + "bodyText": "正文", + "promptText": "提示文本", + "update": "更新", + "close": "关闭", + "delete": "删除", + "deleteConfirmation": "您确定要删除此块吗?" } }, "sharedConv": { diff --git a/frontend/src/modals/ChunkModal.tsx b/frontend/src/modals/ChunkModal.tsx index ab51fdee..4e229980 100644 --- a/frontend/src/modals/ChunkModal.tsx +++ b/frontend/src/modals/ChunkModal.tsx @@ -1,9 +1,10 @@ import React from 'react'; +import { useTranslation } from 'react-i18next'; -import Exit from '../assets/exit.svg'; import Input from '../components/Input'; import { ActiveState } from '../models/misc'; import ConfirmationModal from './ConfirmationModal'; +import WrapperModal from './WrapperModal'; export default function ChunkModal({ type, @@ -22,6 +23,7 @@ export default function ChunkModal({ originalText?: string; handleDelete?: () => void; }) { + const { t } = useTranslation(); const [title, setTitle] = React.useState(''); const [chunkText, setChunkText] = React.useState(''); const [deleteModal, setDeleteModal] = React.useState('INACTIVE'); @@ -30,157 +32,105 @@ export default function ChunkModal({ setTitle(originalTitle || ''); setChunkText(originalText || ''); }, [originalTitle, originalText]); - if (type === 'ADD') { - return ( -
-
-
- -
-

- Add Chunk -

-
- - Title - - setTitle(e.target.value)} - borderVariant="thin" - placeholder={'Enter title'} - labelBgClassName="bg-white dark:bg-charleston-green-2" - > -
-
-
- - Body text - - -
-
-
- - -
-
-
-
+ + if (modalState !== 'ACTIVE') return null; + + const content = ( +
+

+ {t(`modals.chunk.${type === 'ADD' ? 'add' : 'edit'}`)} +

+
+ setTitle(e.target.value)} + borderVariant="thin" + placeholder={t('modals.chunk.title')} + labelBgClassName="bg-white dark:bg-charleston-green-2" + />
- ); - } else { - return ( -
-
-
+
+
+ + {t('modals.chunk.bodyText')} + + +
+
+ + {type === 'ADD' ? ( +
+ + +
+ ) : ( +
+ +
+ -
-

- Edit Chunk -

-
- setTitle(e.target.value)} - borderVariant="thin" - placeholder={'Enter title'} - labelBgClassName="bg-white dark:bg-charleston-green-2" - > -
-
-
- - Body text - - -
-
-
- -
- - -
-
-
-
+
+ )} +
+ ); + + return ( + <> + setModalState('INACTIVE')} + className="sm:w-[620px]" + > + {content} + + + {type === 'EDIT' && ( -
- ); - } + )} + + ); } diff --git a/frontend/src/preferences/PromptsModal.tsx b/frontend/src/preferences/PromptsModal.tsx index b5e028bd..f61ba4ee 100644 --- a/frontend/src/preferences/PromptsModal.tsx +++ b/frontend/src/preferences/PromptsModal.tsx @@ -51,7 +51,7 @@ function AddPrompt({