From 2612ce5ad91ac19f6e06d0211753cec36015c51d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 20:34:44 +0000 Subject: [PATCH 01/21] build(deps): bump duckduckgo-search from 6.3.0 to 7.4.2 in /application Bumps [duckduckgo-search](https://github.com/deedy5/duckduckgo_search) from 6.3.0 to 7.4.2. - [Release notes](https://github.com/deedy5/duckduckgo_search/releases) - [Commits](https://github.com/deedy5/duckduckgo_search/compare/v6.3.0...v7.4.2) --- updated-dependencies: - dependency-name: duckduckgo-search dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- application/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/requirements.txt b/application/requirements.txt index 1707ad80..ffb96ecd 100644 --- a/application/requirements.txt +++ b/application/requirements.txt @@ -4,7 +4,7 @@ beautifulsoup4==4.12.3 celery==5.4.0 dataclasses-json==0.6.7 docx2txt==0.8 -duckduckgo-search==6.3.0 +duckduckgo-search==7.4.2 ebooklib==0.18 elastic-transport==8.17.0 elasticsearch==8.17.0 From 04730ba8c7bbe4027e3f336dbd24a809f86591d6 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Tue, 18 Feb 2025 04:20:20 +0530 Subject: [PATCH 02/21] (feat:theme)exacting the designs --- frontend/src/Hero.tsx | 2 +- frontend/src/modals/WrapperModal.tsx | 2 +- frontend/src/upload/Upload.tsx | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/frontend/src/Hero.tsx b/frontend/src/Hero.tsx index 9fe965a1..a000ab2e 100644 --- a/frontend/src/Hero.tsx +++ b/frontend/src/Hero.tsx @@ -37,7 +37,7 @@ export default function Hero({ @@ -706,7 +706,7 @@ function Upload({ } }} disabled={isUploadDisabled()} - className={`rounded-3xl px-4 py-2 font-medium ${ + className={`rounded-3xl px-4 py-2 font-medium text-[14px] ${ isUploadDisabled() ? 'cursor-not-allowed bg-gray-300 text-gray-500' : 'cursor-pointer bg-purple-30 text-white hover:bg-purple-40' From f35af54e9f5d911a11c8836605e40f55d972b4b5 Mon Sep 17 00:00:00 2001 From: Siddhant Rai Date: Tue, 18 Feb 2025 13:10:35 +0530 Subject: [PATCH 03/21] refactor: clean up code and improve UI elements in various components --- application/llm/openai.py | 1 - frontend/src/components/SkeletonLoader.tsx | 14 +-- .../src/conversation/ConversationBubble.tsx | 79 ++++++++------- frontend/src/modals/AddActionModal.tsx | 49 ++++++---- frontend/src/modals/AddToolModal.tsx | 7 +- frontend/src/modals/ConfigToolModal.tsx | 2 +- frontend/src/settings/Analytics.tsx | 1 - frontend/src/settings/Documents.tsx | 29 +++--- frontend/src/settings/Logs.tsx | 98 +++++++++---------- 9 files changed, 145 insertions(+), 135 deletions(-) diff --git a/application/llm/openai.py b/application/llm/openai.py index 36861584..b8f311b0 100644 --- a/application/llm/openai.py +++ b/application/llm/openai.py @@ -85,7 +85,6 @@ class OpenAILLM(BaseLLM): **kwargs, ): messages = self._clean_messages_openai(messages) - print(messages) if tools: response = self.client.chat.completions.create( model=model, diff --git a/frontend/src/components/SkeletonLoader.tsx b/frontend/src/components/SkeletonLoader.tsx index b73c5835..1f318448 100644 --- a/frontend/src/components/SkeletonLoader.tsx +++ b/frontend/src/components/SkeletonLoader.tsx @@ -91,18 +91,18 @@ const SkeletonLoader: React.FC = ({ ); const renderLogs = () => ( -
+
{[...Array(8)].map((_, idx) => (
-
-
+
+
-
-
-
+
+
+
diff --git a/frontend/src/conversation/ConversationBubble.tsx b/frontend/src/conversation/ConversationBubble.tsx index d60b531a..305c4973 100644 --- a/frontend/src/conversation/ConversationBubble.tsx +++ b/frontend/src/conversation/ConversationBubble.tsx @@ -634,47 +634,46 @@ function ToolCalls({ toolCalls }: { toolCalls: ToolCallsType[] }) { title={`${toolCall.tool_name} - ${toolCall.action_name.substring(0, toolCall.action_name.lastIndexOf('_'))}`} className="w-full rounded-[20px] bg-gray-1000 dark:bg-gun-metal hover:bg-[#F1F1F1] dark:hover:bg-[#2C2E3C]" titleClassName="px-6 py-2 text-sm font-semibold" - children={ -
-
-

- - Arguments - {' '} - -

-

- - {JSON.stringify(toolCall.arguments, null, 2)} - -

-
-
-

- - Response - {' '} - -

-

- - {JSON.stringify(toolCall.result, null, 2)} - -

-
+ > +
+
+

+ + Arguments + {' '} + +

+

+ + {JSON.stringify(toolCall.arguments, null, 2)} + +

- } - /> +
+

+ + Response + {' '} + +

+

+ + {JSON.stringify(toolCall.result, null, 2)} + +

+
+
+ ))}
diff --git a/frontend/src/modals/AddActionModal.tsx b/frontend/src/modals/AddActionModal.tsx index 6ff88ae6..5d7301fb 100644 --- a/frontend/src/modals/AddActionModal.tsx +++ b/frontend/src/modals/AddActionModal.tsx @@ -5,17 +5,17 @@ import Exit from '../assets/exit.svg'; import Input from '../components/Input'; import { ActiveState } from '../models/misc'; +type AddActionModalProps = { + modalState: ActiveState; + setModalState: (state: ActiveState) => void; + handleSubmit: (actionName: string) => void; +}; + const isValidFunctionName = (name: string): boolean => { const pattern = /^[a-zA-Z0-9_-]+$/; return pattern.test(name); }; -interface AddActionModalProps { - modalState: ActiveState; - setModalState: (state: ActiveState) => void; - handleSubmit: (actionName: string) => void; -} - export default function AddActionModal({ modalState, setModalState, @@ -23,18 +23,18 @@ export default function AddActionModal({ }: AddActionModalProps) { const { t } = useTranslation(); const [actionName, setActionName] = React.useState(''); - const [functionNameError, setFunctionNameError] = useState(false); // New error state + const [functionNameError, setFunctionNameError] = useState(false); const handleAddAction = () => { if (!isValidFunctionName(actionName)) { - setFunctionNameError(true); // Set error state if invalid + setFunctionNameError(true); return; } - setFunctionNameError(false); // Clear error state if valid + setFunctionNameError(false); handleSubmit(actionName); + setActionName(''); setModalState('INACTIVE'); }; - return (
{ + setFunctionNameError(false); setModalState('INACTIVE'); + setActionName(''); }} > @@ -62,22 +64,25 @@ export default function AddActionModal({ setActionName(e.target.value)} + onChange={(e) => { + const value = e.target.value; + setActionName(value); + setFunctionNameError(!isValidFunctionName(value)); + }} borderVariant="thin" placeholder={'Enter name'} /> -

- Use only letters, numbers, underscores, and hyphens (e.g., - `get_user_data`, `send-report`). +

+ {functionNameError + ? 'Invalid function name format. Use only letters, numbers, underscores, and hyphens.' + : 'Use only letters, numbers, underscores, and hyphens (e.g., `get_data`, `send_report`, etc.)'}

- {functionNameError && ( -

- Invalid function name format. Use only letters, numbers, - underscores, and hyphens. -

- )}
-
+
-

+

{tool.displayName}

diff --git a/frontend/src/modals/ConfigToolModal.tsx b/frontend/src/modals/ConfigToolModal.tsx index f26029fc..e94a56b0 100644 --- a/frontend/src/modals/ConfigToolModal.tsx +++ b/frontend/src/modals/ConfigToolModal.tsx @@ -61,7 +61,7 @@ export default function ConfigToolModal({ {tool?.name}

- + {t('modals.configTool.apiKeyLabel')}
diff --git a/frontend/src/settings/Documents.tsx b/frontend/src/settings/Documents.tsx index e72a6e16..f4cc3f6e 100644 --- a/frontend/src/settings/Documents.tsx +++ b/frontend/src/settings/Documents.tsx @@ -532,11 +532,12 @@ function DocumentChunks({
) : (
- {paginatedChunks.filter((chunk) => - chunk.metadata?.title + {paginatedChunks.filter((chunk) => { + if (!chunk.metadata?.title) return true; + return chunk.metadata.title .toLowerCase() - .includes(searchTerm.toLowerCase()), - ).length === 0 ? ( + .includes(searchTerm.toLowerCase()); + }).length === 0 ? (
) : ( paginatedChunks - .filter((chunk) => - chunk.metadata?.title + .filter((chunk) => { + if (!chunk.metadata?.title) return true; + return chunk.metadata.title .toLowerCase() - .includes(searchTerm.toLowerCase()), - ) + .includes(searchTerm.toLowerCase()); + }) .map((chunk, index) => (

- {chunk.metadata?.title} + {chunk.metadata?.title ?? 'Untitled'}

{chunk.text} @@ -591,11 +593,12 @@ function DocumentChunks({

)} {!loading && - paginatedChunks.filter((chunk) => - chunk.metadata?.title + paginatedChunks.filter((chunk) => { + if (!chunk.metadata?.title) return true; + return chunk.metadata.title .toLowerCase() - .includes(searchTerm.toLowerCase()), - ).length !== 0 && ( + .includes(searchTerm.toLowerCase()); + }).length !== 0 && (
- {loadingChatbots ? ( - - ) : ( -
- - ({ - label: chatbot.name, - value: chatbot.id, - })), - { label: t('settings.logs.none'), value: '' }, - ]} - placeholder={t('settings.logs.selectChatbot')} - onSelect={(chatbot: { label: string; value: string }) => { - setSelectedChatbot( - chatbots.find((item) => item.id === chatbot.value), - ); - setLogs([]); - setPage(1); - setHasMore(true); - }} - selectedValue={ - (selectedChatbot && { - label: selectedChatbot.name, - value: selectedChatbot.id, - }) || - null - } - rounded="3xl" - border="border" - /> -
- )} +
+ + ({ + label: chatbot.name, + value: chatbot.id, + })), + { label: t('settings.logs.none'), value: '' }, + ]} + placeholder={t('settings.logs.selectChatbot')} + onSelect={(chatbot: { label: string; value: string }) => { + setSelectedChatbot( + chatbots.find((item) => item.id === chatbot.value), + ); + setLogs([]); + setPage(1); + setHasMore(true); + }} + selectedValue={ + (selectedChatbot && { + label: selectedChatbot.name, + value: selectedChatbot.id, + }) || + null + } + rounded="3xl" + border="border" + /> +
@@ -148,7 +144,7 @@ function LogsTable({ logs, setPage, loading }: LogsTableProps) { {logs?.map((log, index) => { if (index === logs.length - 1) { return ( -
+
); @@ -170,22 +166,26 @@ function Log({ log }: { log: LogData }) { const { id, action, timestamp, ...filteredLog } = log; return (
- + Expand log entry

{`${log.timestamp}`}

{`[${log.action}]`}

{`${log.question}`}

+ className={`max-w-72 text-xs ${logLevelColor[log.level]} break-words`} + > + {`${log.question}`.length > 250 + ? `${log.question.substring(0, 250)}...` + : log.question} +
-

+

{JSON.stringify(filteredLog, null, 2)}

From 0d9fc26119f3f20ce8d0c0d9abe972cdd9362b3d Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Wed, 19 Feb 2025 03:39:15 +0530 Subject: [PATCH 04/21] (refactor): purge unused files --- frontend/src/modals/index.tsx | 50 --------------- frontend/src/preferences/APIKeyModal.tsx | 80 ------------------------ 2 files changed, 130 deletions(-) delete mode 100644 frontend/src/modals/index.tsx delete mode 100644 frontend/src/preferences/APIKeyModal.tsx diff --git a/frontend/src/modals/index.tsx b/frontend/src/modals/index.tsx deleted file mode 100644 index 1dcffd6d..00000000 --- a/frontend/src/modals/index.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import * as React from 'react'; -import { useTranslation } from 'react-i18next'; -interface ModalProps { - handleSubmit: () => void; - isCancellable: boolean; - handleCancel?: () => void; - render: () => JSX.Element; - modalState: string; - isError: boolean; - errorMessage?: string; - textDelete?: boolean; -} - -const Modal = (props: ModalProps) => { - const { t } = useTranslation(); - return ( -
- {props.render()} -
-
- - {props.isCancellable && ( - - )} -
- {props.isError && ( -

- {props.errorMessage} -

- )} -
-
- ); -}; - -export default Modal; diff --git a/frontend/src/preferences/APIKeyModal.tsx b/frontend/src/preferences/APIKeyModal.tsx deleted file mode 100644 index 43698fe1..00000000 --- a/frontend/src/preferences/APIKeyModal.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { useRef, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { ActiveState } from '../models/misc'; -import { selectApiKey, setApiKey } from './preferenceSlice'; -import { useMediaQuery, useOutsideAlerter } from './../hooks'; -import Modal from '../modals'; -import Input from '../components/Input'; - -export default function APIKeyModal({ - modalState, - setModalState, - isCancellable = true, -}: { - modalState: ActiveState; - setModalState: (val: ActiveState) => void; - isCancellable?: boolean; -}) { - const dispatch = useDispatch(); - const apiKey = useSelector(selectApiKey); - const [key, setKey] = useState(apiKey); - const [isError, setIsError] = useState(false); - const modalRef = useRef(null); - const { isMobile } = useMediaQuery(); - - useOutsideAlerter(modalRef, () => { - if (isMobile && modalState === 'ACTIVE') { - setModalState('INACTIVE'); - } - }, [modalState]); - - function handleSubmit() { - if (key.length <= 1) { - setIsError(true); - } else { - dispatch(setApiKey(key)); - setModalState('INACTIVE'); - setIsError(false); - } - } - - function handleCancel() { - setKey(apiKey); - setIsError(false); - setModalState('INACTIVE'); - } - - return ( - { - return ( -
-

OpenAI API Key

-

- Before you can start using DocsGPT we need you to provide an API - key for llm. Currently, we support only OpenAI but soon many more. - You can find it here. -

- setKey(e.target.value)} - > -
- ); - }} - /> - ); -} From 85893037536e8466e5a892318aad87c141893880 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Wed, 19 Feb 2025 04:01:14 +0530 Subject: [PATCH 05/21] (feat:consitency)modals, dropdowns --- frontend/src/components/Dropdown.tsx | 2 +- frontend/src/components/SourceDropdown.tsx | 2 +- frontend/src/modals/SaveAPIKeyModal.tsx | 52 +++++++-------- frontend/src/preferences/PromptsModal.tsx | 60 ++++++----------- frontend/src/settings/Analytics.tsx | 70 ++++++++++--------- frontend/src/settings/Prompts.tsx | 2 +- frontend/src/upload/Upload.tsx | 78 +++++++++++----------- 7 files changed, 123 insertions(+), 143 deletions(-) diff --git a/frontend/src/components/Dropdown.tsx b/frontend/src/components/Dropdown.tsx index 15923661..5932933e 100644 --- a/frontend/src/components/Dropdown.tsx +++ b/frontend/src/components/Dropdown.tsx @@ -119,7 +119,7 @@ function Dropdown({ {options.map((option: any, index) => (
{ diff --git a/frontend/src/components/SourceDropdown.tsx b/frontend/src/components/SourceDropdown.tsx index f92173a0..080ad320 100644 --- a/frontend/src/components/SourceDropdown.tsx +++ b/frontend/src/components/SourceDropdown.tsx @@ -83,7 +83,7 @@ function SourceDropdown({ return (
{ dispatch(setSelectedDocs(option)); setIsDocsListOpen(false); diff --git a/frontend/src/modals/SaveAPIKeyModal.tsx b/frontend/src/modals/SaveAPIKeyModal.tsx index d91d0c2d..d28d2d0c 100644 --- a/frontend/src/modals/SaveAPIKeyModal.tsx +++ b/frontend/src/modals/SaveAPIKeyModal.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; -import Exit from '../assets/exit.svg'; import { SaveAPIKeyModalProps } from '../models/misc'; +import WrapperModal from './WrapperModal'; export default function SaveAPIKeyModal({ apiKey, @@ -15,38 +15,34 @@ export default function SaveAPIKeyModal({ navigator.clipboard.writeText(apiKey); setIsCopied(true); }; + return ( -
-
- -

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

-

- {t('modals.saveKey.disclaimer')} -

-
-
-

API Key

- {apiKey} -
- + +

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

+

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

+
+
+

API Key

+ {apiKey}
-
+ + ); } + diff --git a/frontend/src/preferences/PromptsModal.tsx b/frontend/src/preferences/PromptsModal.tsx index 11cb0685..1a143cbd 100644 --- a/frontend/src/preferences/PromptsModal.tsx +++ b/frontend/src/preferences/PromptsModal.tsx @@ -1,8 +1,8 @@ import { ActiveState } from '../models/misc'; -import Exit from '../assets/exit.svg'; import Input from '../components/Input'; import React from 'react'; import { useTranslation } from 'react-i18next'; +import WrapperModal from '../modals/WrapperModal'; function AddPrompt({ setModalState, @@ -24,19 +24,7 @@ function AddPrompt({ const { t } = useTranslation(); return ( -
- -
+

{t('modals.prompts.addPrompt')}

@@ -50,17 +38,13 @@ function AddPrompt({ setNewPromptName(e.target.value)} /> -
- - {t('modals.prompts.promptName')} - -
- + {t('modals.prompts.promptText')}
@@ -87,7 +71,6 @@ function AddPrompt({ {t('modals.prompts.save')}
-
); } @@ -114,16 +97,7 @@ function EditPrompt({ const { t } = useTranslation(); return ( -
- +

{t('modals.prompts.editPrompt')} @@ -271,15 +245,19 @@ export default function PromptsModal({ } else { view = <>; } - return ( -

{ + setModalState('INACTIVE'); + if (type === 'ADD') { + setNewPromptName(''); + setNewPromptContent(''); + } + }} + className="sm:w-[512px] mt-24" > -
- {view} -
-
- ); + {view} + + ) : null; } diff --git a/frontend/src/settings/Analytics.tsx b/frontend/src/settings/Analytics.tsx index 4d390495..53538833 100644 --- a/frontend/src/settings/Analytics.tsx +++ b/frontend/src/settings/Analytics.tsx @@ -92,8 +92,10 @@ export default function Analytics() { const [loadingMessages, setLoadingMessages] = useLoaderState(true); const [loadingTokens, setLoadingTokens] = useLoaderState(true); const [loadingFeedback, setLoadingFeedback] = useLoaderState(true); + const [loadingChatbots, setLoadingChatbots] = useLoaderState(true); const fetchChatbots = async () => { + setLoadingChatbots(true); try { const response = await userService.getAPIKeys(); if (!response.ok) { @@ -103,6 +105,8 @@ export default function Analytics() { setChatbots(chatbots); } catch (error) { console.error(error); + } finally { + setLoadingChatbots(false); } }; @@ -188,37 +192,41 @@ export default function Analytics() { return (
-
-

- {t('settings.analytics.filterByChatbot')} -

- ({ - label: chatbot.name, - value: chatbot.id, - })), - { label: t('settings.analytics.none'), value: '' }, - ]} - placeholder={t('settings.analytics.selectChatbot')} - onSelect={(chatbot: { label: string; value: string }) => { - setSelectedChatbot( - chatbots.find((item) => item.id === chatbot.value), - ); - }} - selectedValue={ - (selectedChatbot && { - label: selectedChatbot.name, - value: selectedChatbot.id, - }) || - null - } - rounded="3xl" - border="border" - borderColor="gray-700" - /> -
+ {loadingChatbots ? ( + + ) : ( +
+

+ {t('settings.analytics.filterByChatbot')} +

+ ({ + label: chatbot.name, + value: chatbot.id, + })), + { label: t('settings.analytics.none'), value: '' }, + ]} + placeholder={t('settings.analytics.selectChatbot')} + onSelect={(chatbot: { label: string; value: string }) => { + setSelectedChatbot( + chatbots.find((item) => item.id === chatbot.value), + ); + }} + selectedValue={ + (selectedChatbot && { + label: selectedChatbot.name, + value: selectedChatbot.id, + }) || + null + } + rounded="3xl" + border="border" + borderColor="gray-700" + /> +
+ )} {/* Messages Analytics */}
diff --git a/frontend/src/settings/Prompts.tsx b/frontend/src/settings/Prompts.tsx index 611b0b90..ed1d82d7 100644 --- a/frontend/src/settings/Prompts.tsx +++ b/frontend/src/settings/Prompts.tsx @@ -168,7 +168,7 @@ export default function Prompts({ />
- -
-
- )} +
+

+ {t('modals.uploadDoc.select')} +

+
+ + +
+
+)} {activeTab === 'file' && ( <> setDocName(e.target.value)} borderVariant="thin" - > -
- - {t('modals.uploadDoc.name')} - -
-
+ placeholder={t('modals.uploadDoc.name')} + label={t('modals.uploadDoc.name')} + required={true} + /> +
{t('modals.uploadDoc.choose')} @@ -649,7 +647,7 @@ function Upload({ {activeTab === 'remote' && ( <> opt.value === ingestor.type) || null @@ -664,7 +662,7 @@ function Upload({ setRemoteName(e.target.value)} borderVariant="thin" From 28489d244c5e4be9562bf35708c98bb83036ecdb Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Wed, 19 Feb 2025 04:10:14 +0530 Subject: [PATCH 06/21] (feat:input) consistent colors --- frontend/src/components/Input.tsx | 2 +- frontend/src/modals/WrapperModal.tsx | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/Input.tsx b/frontend/src/components/Input.tsx index f224e2ba..e703ff14 100644 --- a/frontend/src/components/Input.tsx +++ b/frontend/src/components/Input.tsx @@ -47,7 +47,7 @@ const Input = ({ {label && (
- + {label} {required && ( diff --git a/frontend/src/modals/WrapperModal.tsx b/frontend/src/modals/WrapperModal.tsx index c2b22a90..eee205f0 100644 --- a/frontend/src/modals/WrapperModal.tsx +++ b/frontend/src/modals/WrapperModal.tsx @@ -1,12 +1,21 @@ import React, { useEffect, useRef } from 'react'; import Exit from '../assets/exit.svg'; -import { WrapperModalPropsType } from './types'; + +interface WrapperModalPropsType { + children: React.ReactNode; + close: () => void; + isPerformingTask?: boolean; + className?: string; + contentClassName?: string; +} export default function WrapperModal({ children, close, - isPerformingTask, + isPerformingTask = false, + className = 'sm:w-[512px]', // Default width, but can be overridden + contentClassName = 'p-8', // Default padding, but can be overridden }: WrapperModalPropsType) { const modalRef = useRef(null); @@ -40,17 +49,19 @@ export default function WrapperModal({
{!isPerformingTask && ( )} - {children} +
+ {children} +
); From 4e948d8bff017490b088fac5e50d363832ff4173 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Wed, 19 Feb 2025 04:15:31 +0530 Subject: [PATCH 07/21] (refactor:tools modal) reuse wrapper modal --- frontend/src/modals/AddToolModal.tsx | 31 ++----- frontend/src/modals/ConfigToolModal.tsx | 114 +++++++++++------------- 2 files changed, 60 insertions(+), 85 deletions(-) diff --git a/frontend/src/modals/AddToolModal.tsx b/frontend/src/modals/AddToolModal.tsx index ba555df4..d48882a1 100644 --- a/frontend/src/modals/AddToolModal.tsx +++ b/frontend/src/modals/AddToolModal.tsx @@ -7,6 +7,7 @@ import { useOutsideAlerter } from '../hooks'; import { ActiveState } from '../models/misc'; import ConfigToolModal from './ConfigToolModal'; import { AvailableToolType } from './types'; +import WrapperComponent from './WrapperModal'; export default function AddToolModal({ message, @@ -88,28 +89,12 @@ export default function AddToolModal({ return ( <> -
-
setModalState('INACTIVE')} + className="h-[85vh] w-[90vw] md:w-[75vw]" > -
- +

{t('settings.tools.selectToolSetup')} @@ -153,8 +138,8 @@ export default function AddToolModal({

-
-
+ + )} void; + tool: AvailableToolType | null; + getUserTools: () => void; +} + export default function ConfigToolModal({ modalState, setModalState, tool, getUserTools, -}: { - modalState: ActiveState; - setModalState: (state: ActiveState) => void; - tool: AvailableToolType | null; - getUserTools: () => void; -}) { +}: ConfigToolModalProps) { const { t } = useTranslation(); const [authKey, setAuthKey] = React.useState(''); @@ -36,63 +38,51 @@ export default function ConfigToolModal({ getUserTools(); }); }; + + // Only render when modal is active + if (modalState !== 'ACTIVE') return null; + return ( -
setModalState('INACTIVE')} + className="sm:w-[512px]" + contentClassName="" > -
-
- -
-

- {t('modals.configTool.title')} -

-

- {t('modals.configTool.type')}:{' '} - {tool?.name} -

-
- - {t('modals.configTool.apiKeyLabel')} - - setAuthKey(e.target.value)} - borderVariant="thin" - placeholder={t('modals.configTool.apiKeyPlaceholder')} - > -
-
- - -
-
+
+

+ {t('modals.configTool.title')} +

+

+ {t('modals.configTool.type')}:{' '} + {tool?.name} +

+
+ setAuthKey(e.target.value)} + borderVariant="thin" + placeholder={t('modals.configTool.apiKeyPlaceholder')} + label={t('modals.configTool.apiKeyLabel')} + />
-
-
+
+ + +
+
+ ); } From 3aa85bb51cde9e9d8f60463bf3a15600864dee30 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Wed, 19 Feb 2025 04:35:33 +0530 Subject: [PATCH 08/21] (refactor:modals) reuse wrapper modal --- frontend/src/modals/AddActionModal.tsx | 106 ++++++++++------------ frontend/src/modals/ConfigToolModal.tsx | 4 +- frontend/src/modals/CreateAPIKeyModal.tsx | 2 +- frontend/src/modals/WrapperModal.tsx | 8 +- 4 files changed, 52 insertions(+), 68 deletions(-) diff --git a/frontend/src/modals/AddActionModal.tsx b/frontend/src/modals/AddActionModal.tsx index 6ff88ae6..a2160146 100644 --- a/frontend/src/modals/AddActionModal.tsx +++ b/frontend/src/modals/AddActionModal.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; -import Exit from '../assets/exit.svg'; +import WrapperModal from './WrapperModal'; import Input from '../components/Input'; import { ActiveState } from '../models/misc'; @@ -35,67 +35,53 @@ export default function AddActionModal({ setModalState('INACTIVE'); }; + // Only render when modal is active + if (modalState !== 'ACTIVE') return null; + return ( -
setModalState('INACTIVE')} + className="sm:w-[512px]" > -
-
- -
-

- New Action -

-
- - Action Name - - setActionName(e.target.value)} - borderVariant="thin" - placeholder={'Enter name'} - /> -

- Use only letters, numbers, underscores, and hyphens (e.g., - `get_user_data`, `send-report`). -

- {functionNameError && ( -

- Invalid function name format. Use only letters, numbers, - underscores, and hyphens. -

- )} -
-
- - -
-
+
+

+ New Action +

+
+ setActionName(e.target.value)} + borderVariant="thin" + placeholder="Enter name" + label="Action Name" + /> +

+ Use only letters, numbers, underscores, and hyphens (e.g., + `get_user_data`, `send-report`). +

+ {functionNameError && ( +

+ Invalid function name format. Use only letters, numbers, + underscores, and hyphens. +

+ )}
-
-
+
+ + +
+
+ ); } diff --git a/frontend/src/modals/ConfigToolModal.tsx b/frontend/src/modals/ConfigToolModal.tsx index 4a582a49..d8585899 100644 --- a/frontend/src/modals/ConfigToolModal.tsx +++ b/frontend/src/modals/ConfigToolModal.tsx @@ -45,10 +45,8 @@ export default function ConfigToolModal({ return ( setModalState('INACTIVE')} - className="sm:w-[512px]" - contentClassName="" > -
+

{t('modals.configTool.title')}

diff --git a/frontend/src/modals/CreateAPIKeyModal.tsx b/frontend/src/modals/CreateAPIKeyModal.tsx index 5c8c75b8..36ec59a8 100644 --- a/frontend/src/modals/CreateAPIKeyModal.tsx +++ b/frontend/src/modals/CreateAPIKeyModal.tsx @@ -73,7 +73,7 @@ export default function CreateAPIKeyModal({ handleFetchPrompts(); }, []); return ( - +
{t('modals.createAPIKey.label')} diff --git a/frontend/src/modals/WrapperModal.tsx b/frontend/src/modals/WrapperModal.tsx index eee205f0..b945a60a 100644 --- a/frontend/src/modals/WrapperModal.tsx +++ b/frontend/src/modals/WrapperModal.tsx @@ -14,8 +14,8 @@ export default function WrapperModal({ children, close, isPerformingTask = false, - className = 'sm:w-[512px]', // Default width, but can be overridden - contentClassName = 'p-8', // Default padding, but can be overridden + className = '', // Default width, but can be overridden + contentClassName = '', // Default padding, but can be overridden }: WrapperModalPropsType) { const modalRef = useRef(null); @@ -49,7 +49,7 @@ export default function WrapperModal({
{!isPerformingTask && ( )} -
+
{children}
From cc4acb8766e17c75d811071a1f4c6929101b0085 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Wed, 19 Feb 2025 04:38:49 +0530 Subject: [PATCH 09/21] (feat:createAPIModal): UI inconsistency --- frontend/src/modals/CreateAPIKeyModal.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/src/modals/CreateAPIKeyModal.tsx b/frontend/src/modals/CreateAPIKeyModal.tsx index 36ec59a8..5495f520 100644 --- a/frontend/src/modals/CreateAPIKeyModal.tsx +++ b/frontend/src/modals/CreateAPIKeyModal.tsx @@ -80,14 +80,13 @@ export default function CreateAPIKeyModal({
- - {t('modals.createAPIKey.apiKeyName')} - setAPIKeyName(e.target.value)} + borderVariant='thin' >
From 877b44ec0a6aa5268b95f4ca1f775e76ca640f85 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Wed, 19 Feb 2025 04:49:22 +0530 Subject: [PATCH 10/21] (lint) --- frontend/src/modals/AddToolModal.tsx | 3 +- frontend/src/modals/ConfigToolModal.tsx | 4 +- frontend/src/modals/CreateAPIKeyModal.tsx | 4 +- frontend/src/modals/SaveAPIKeyModal.tsx | 9 ++- frontend/src/modals/WrapperModal.tsx | 4 +- frontend/src/preferences/PromptsModal.tsx | 90 +++++++++++------------ frontend/src/upload/Upload.tsx | 58 +++++++-------- 7 files changed, 85 insertions(+), 87 deletions(-) diff --git a/frontend/src/modals/AddToolModal.tsx b/frontend/src/modals/AddToolModal.tsx index d48882a1..c11a5043 100644 --- a/frontend/src/modals/AddToolModal.tsx +++ b/frontend/src/modals/AddToolModal.tsx @@ -2,7 +2,6 @@ import React, { useRef } from 'react'; import { useTranslation } from 'react-i18next'; import userService from '../api/services/userService'; -import Exit from '../assets/exit.svg'; import { useOutsideAlerter } from '../hooks'; import { ActiveState } from '../models/misc'; import ConfigToolModal from './ConfigToolModal'; @@ -90,7 +89,7 @@ export default function AddToolModal({ return ( <> {modalState === 'ACTIVE' && ( - setModalState('INACTIVE')} className="h-[85vh] w-[90vw] md:w-[75vw]" > diff --git a/frontend/src/modals/ConfigToolModal.tsx b/frontend/src/modals/ConfigToolModal.tsx index d8585899..04553677 100644 --- a/frontend/src/modals/ConfigToolModal.tsx +++ b/frontend/src/modals/ConfigToolModal.tsx @@ -43,9 +43,7 @@ export default function ConfigToolModal({ if (modalState !== 'ACTIVE') return null; return ( - setModalState('INACTIVE')} - > + setModalState('INACTIVE')}>

{t('modals.configTool.title')} diff --git a/frontend/src/modals/CreateAPIKeyModal.tsx b/frontend/src/modals/CreateAPIKeyModal.tsx index 5495f520..128bdff6 100644 --- a/frontend/src/modals/CreateAPIKeyModal.tsx +++ b/frontend/src/modals/CreateAPIKeyModal.tsx @@ -73,7 +73,7 @@ export default function CreateAPIKeyModal({ handleFetchPrompts(); }, []); return ( - +
{t('modals.createAPIKey.label')} @@ -86,7 +86,7 @@ export default function CreateAPIKeyModal({ value={APIKeyName} label={t('modals.createAPIKey.apiKeyName')} onChange={(e) => setAPIKeyName(e.target.value)} - borderVariant='thin' + borderVariant="thin" >
diff --git a/frontend/src/modals/SaveAPIKeyModal.tsx b/frontend/src/modals/SaveAPIKeyModal.tsx index d28d2d0c..abe862cb 100644 --- a/frontend/src/modals/SaveAPIKeyModal.tsx +++ b/frontend/src/modals/SaveAPIKeyModal.tsx @@ -26,8 +26,12 @@ export default function SaveAPIKeyModal({

-

API Key

- {apiKey} +

+ API Key +

+ + {apiKey} +
)} -
- {children} -
+
{children}
); diff --git a/frontend/src/preferences/PromptsModal.tsx b/frontend/src/preferences/PromptsModal.tsx index 1a143cbd..f2512210 100644 --- a/frontend/src/preferences/PromptsModal.tsx +++ b/frontend/src/preferences/PromptsModal.tsx @@ -25,52 +25,52 @@ function AddPrompt({ return (
-

- {t('modals.prompts.addPrompt')} -

-

- {t('modals.prompts.addDescription')} -

-
- - setNewPromptName(e.target.value)} - /> -
- - {t('modals.prompts.promptText')} - -
- - -
-
- +

+ {t('modals.prompts.addPrompt')} +

+

+ {t('modals.prompts.addDescription')} +

+
+ + setNewPromptName(e.target.value)} + /> +
+ + {t('modals.prompts.promptText')} +
+ + +
+
+ +
); } diff --git a/frontend/src/upload/Upload.tsx b/frontend/src/upload/Upload.tsx index c8c9ef6d..f97473d5 100644 --- a/frontend/src/upload/Upload.tsx +++ b/frontend/src/upload/Upload.tsx @@ -571,34 +571,34 @@ function Upload({ {t('modals.uploadDoc.label')}

{!activeTab && ( -
-

- {t('modals.uploadDoc.select')} -

-
- - -
-
-)} +
+

+ {t('modals.uploadDoc.select')} +

+
+ + +
+
+ )} {activeTab === 'file' && ( <> @@ -612,7 +612,7 @@ function Upload({ label={t('modals.uploadDoc.name')} required={true} /> -
+
{t('modals.uploadDoc.choose')} From ac1b1c3cdd1c8ec43835e8205c0faa3d3b343f84 Mon Sep 17 00:00:00 2001 From: Siddhant Rai Date: Wed, 19 Feb 2025 13:58:40 +0530 Subject: [PATCH 11/21] feat: add loading spinner to AddToolModal and improve label spacing in General settings --- frontend/src/modals/AddToolModal.tsx | 83 +++++++------ frontend/src/settings/General.tsx | 2 +- frontend/src/settings/Tools.tsx | 172 +++++++++++++++------------ 3 files changed, 142 insertions(+), 115 deletions(-) diff --git a/frontend/src/modals/AddToolModal.tsx b/frontend/src/modals/AddToolModal.tsx index c8652c5b..8b4e98be 100644 --- a/frontend/src/modals/AddToolModal.tsx +++ b/frontend/src/modals/AddToolModal.tsx @@ -7,6 +7,7 @@ import { useOutsideAlerter } from '../hooks'; import { ActiveState } from '../models/misc'; import ConfigToolModal from './ConfigToolModal'; import { AvailableToolType } from './types'; +import Spinner from '../components/Spinner'; export default function AddToolModal({ message, @@ -21,6 +22,8 @@ export default function AddToolModal({ getUserTools: () => void; onToolAdded: (toolId: string) => void; }) { + const { t } = useTranslation(); + const modalRef = useRef(null); const [availableTools, setAvailableTools] = React.useState< AvailableToolType[] >([]); @@ -28,8 +31,7 @@ export default function AddToolModal({ React.useState(null); const [configModalState, setConfigModalState] = React.useState('INACTIVE'); - const modalRef = useRef(null); - const { t } = useTranslation(); + const [loading, setLoading] = React.useState(false); useOutsideAlerter(modalRef, () => { if (modalState === 'ACTIVE') { @@ -38,6 +40,7 @@ export default function AddToolModal({ }, [modalState]); const getAvailableTools = () => { + setLoading(true); userService .getAvailableTools() .then((res) => { @@ -45,6 +48,7 @@ export default function AddToolModal({ }) .then((data) => { setAvailableTools(data.data); + setLoading(false); }); }; @@ -85,7 +89,6 @@ export default function AddToolModal({ React.useEffect(() => { if (modalState === 'ACTIVE') getAvailableTools(); }, [modalState]); - return ( <>
- {availableTools.map((tool, index) => ( -
{ - setSelectedTool(tool); - handleAddTool(tool); - }} - onKeyDown={(e) => { - if (e.key === 'Enter' || e.key === ' ') { + {loading ? ( +
+ +
+ ) : ( + availableTools.map((tool, index) => ( +
{ setSelectedTool(tool); handleAddTool(tool); - } - }} - > -
-
- -
-
-

- {tool.displayName} -

-

- {tool.description} -

+ }} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + setSelectedTool(tool); + handleAddTool(tool); + } + }} + > +
+
+ +
+
+

+ {tool.displayName} +

+

+ {tool.description} +

+
-
- ))} + )) + )}
diff --git a/frontend/src/settings/General.tsx b/frontend/src/settings/General.tsx index d974eab7..86c4f4ab 100644 --- a/frontend/src/settings/General.tsx +++ b/frontend/src/settings/General.tsx @@ -84,7 +84,7 @@ export default function General() { return (
-