From 58af393968a8bd5f6c74832838927fafc69fbfe1 Mon Sep 17 00:00:00 2001 From: rohittcodes Date: Wed, 13 Nov 2024 02:15:05 +0530 Subject: [PATCH 1/2] feat: wrapper modal --- frontend/src/Navigation.tsx | 17 +- frontend/src/modals/ConfirmationModal.tsx | 76 ++++----- frontend/src/modals/CreateAPIKeyModal.tsx | 161 +++++++++--------- .../src/modals/ShareConversationModal.tsx | 145 ++++++++-------- frontend/src/modals/WrapperModal.tsx | 48 ++++++ frontend/src/modals/types/index.ts | 4 + frontend/src/settings/Documents.tsx | 2 +- frontend/src/upload/Upload.tsx | 37 ++-- 8 files changed, 253 insertions(+), 237 deletions(-) create mode 100644 frontend/src/modals/WrapperModal.tsx create mode 100644 frontend/src/modals/types/index.ts diff --git a/frontend/src/Navigation.tsx b/frontend/src/Navigation.tsx index 324d5aa05..f5eee00e7 100644 --- a/frontend/src/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -32,7 +32,6 @@ import { selectConversations, selectModalStateDeleteConv, selectSelectedDocs, - selectSelectedDocsStatus, selectSourceDocs, selectPaginatedDocuments, setConversations, @@ -85,10 +84,6 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { const [apiKeyModalState, setApiKeyModalState] = useState('INACTIVE'); - const isSelectedDocsSet = useSelector(selectSelectedDocsStatus); - const [selectedDocsModalState, setSelectedDocsModalState] = - useState(isSelectedDocsSet ? 'INACTIVE' : 'ACTIVE'); - const [uploadModalState, setUploadModalState] = useState('INACTIVE'); @@ -491,11 +486,13 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { setModalState={setModalStateDeleteConv} handleDeleteAllConv={handleDeleteAllConversations} /> - + {uploadModalState === 'ACTIVE' && ( + setUploadModalState('INACTIVE')} + > + )} ); } diff --git a/frontend/src/modals/ConfirmationModal.tsx b/frontend/src/modals/ConfirmationModal.tsx index 0b39440bd..c69dcedd7 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'; +import WrapperModal from './WrapperModal'; function ConfirmationModal({ message, modalState, @@ -20,49 +20,43 @@ function ConfirmationModal({ }) { const { t } = useTranslation(); return ( -
-
-
- -
-

- {message} -

-
-
- - + <> + {modalState === 'ACTIVE' && ( + { + setModalState('INACTIVE'); + handleCancel && handleCancel(); + }} + > +
+
+

+ {message} +

+
+
+ + +
-
-
-
+ + )} + ); } diff --git a/frontend/src/modals/CreateAPIKeyModal.tsx b/frontend/src/modals/CreateAPIKeyModal.tsx index eb085a28c..5c8c75b85 100644 --- a/frontend/src/modals/CreateAPIKeyModal.tsx +++ b/frontend/src/modals/CreateAPIKeyModal.tsx @@ -3,11 +3,11 @@ import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; import userService from '../api/services/userService'; -import Exit from '../assets/exit.svg'; import Dropdown from '../components/Dropdown'; import Input from '../components/Input'; import { CreateAPIKeyModalProps, Doc } from '../models/misc'; import { selectSourceDocs } from '../preferences/preferenceSlice'; +import WrapperModal from './WrapperModal'; const embeddingsName = import.meta.env.VITE_EMBEDDINGS_NAME || @@ -73,91 +73,82 @@ export default function CreateAPIKeyModal({ handleFetchPrompts(); }, []); return ( -
-
- -
- - {t('modals.createAPIKey.label')} - -
-
- - {t('modals.createAPIKey.apiKeyName')} - - setAPIKeyName(e.target.value)} - > -
-
- { - setSourcePath(selection); - }} - options={extractDocPaths()} - size="w-full" - rounded="xl" - border="border" - /> -
-
- - setPrompt(value) - } - size="w-full" - border="border" - /> -
-
-

- {t('modals.createAPIKey.chunks')} -

- setChunk(value)} - size="w-full" - border="border" - /> -
- + options={extractDocPaths()} + size="w-full" + rounded="xl" + border="border" + />
-
+
+ + setPrompt(value) + } + size="w-full" + border="border" + /> +
+
+

+ {t('modals.createAPIKey.chunks')} +

+ setChunk(value)} + size="w-full" + border="border" + /> +
+ + ); } diff --git a/frontend/src/modals/ShareConversationModal.tsx b/frontend/src/modals/ShareConversationModal.tsx index fbb494683..3f87839e6 100644 --- a/frontend/src/modals/ShareConversationModal.tsx +++ b/frontend/src/modals/ShareConversationModal.tsx @@ -10,7 +10,6 @@ import { import Dropdown from '../components/Dropdown'; import { Doc } from '../models/misc'; import Spinner from '../assets/spinner.svg'; -import Exit from '../assets/exit.svg'; const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com'; const embeddingsName = import.meta.env.VITE_EMBEDDINGS_NAME || @@ -19,6 +18,7 @@ const embeddingsName = type StatusType = 'loading' | 'idle' | 'fetched' | 'failed'; import conversationService from '../api/services/conversationService'; +import WrapperModal from './WrapperModal'; export const ShareConversationModal = ({ close, @@ -99,85 +99,78 @@ export const ShareConversationModal = ({ }; return ( -
-
- -
-

{t('modals.shareConv.label')}

-

{t('modals.shareConv.note')}

-
- {t('modals.shareConv.option')} - -
- {allowPrompt && ( -
- - setSourcePath(selection) - } - options={extractDocPaths(sourceDocs ?? [])} - size="w-full" - rounded="xl" + +
+

{t('modals.shareConv.label')}

+

{t('modals.shareConv.note')}

+
+ {t('modals.shareConv.option')} +
-
+
); }; diff --git a/frontend/src/modals/WrapperModal.tsx b/frontend/src/modals/WrapperModal.tsx new file mode 100644 index 000000000..1a0128713 --- /dev/null +++ b/frontend/src/modals/WrapperModal.tsx @@ -0,0 +1,48 @@ +import React, { useEffect, useRef } from 'react'; +import { WrapperModalProps } from './types'; +import Exit from '../assets/exit.svg'; + +const WrapperModal: React.FC = ({ children, close }) => { + const modalRef = useRef(null); + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if ( + modalRef.current && + !modalRef.current.contains(event.target as Node) + ) { + close(); + } + }; + + const handleEscapePress = (event: KeyboardEvent) => { + if (event.key === 'Escape') { + close(); + } + }; + + document.addEventListener('mousedown', handleClickOutside); + document.addEventListener('keydown', handleEscapePress); + + return () => { + document.removeEventListener('mousedown', handleClickOutside); + document.removeEventListener('keydown', handleEscapePress); + }; + }, [close]); + + return ( +
+
+ + {children} +
+
+ ); +}; + +export default WrapperModal; diff --git a/frontend/src/modals/types/index.ts b/frontend/src/modals/types/index.ts new file mode 100644 index 000000000..2010bbb92 --- /dev/null +++ b/frontend/src/modals/types/index.ts @@ -0,0 +1,4 @@ +export type WrapperModalProps = { + children?: React.ReactNode; + close: () => void; +}; diff --git a/frontend/src/settings/Documents.tsx b/frontend/src/settings/Documents.tsx index f91a33559..db2e58555 100644 --- a/frontend/src/settings/Documents.tsx +++ b/frontend/src/settings/Documents.tsx @@ -255,9 +255,9 @@ const Documents: React.FC = ({
{/* Your Upload component */} setModalState('INACTIVE')} />
diff --git a/frontend/src/upload/Upload.tsx b/frontend/src/upload/Upload.tsx index 4fee88f6d..612456d52 100644 --- a/frontend/src/upload/Upload.tsx +++ b/frontend/src/upload/Upload.tsx @@ -4,7 +4,6 @@ import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; import userService from '../api/services/userService'; -import Exit from '../assets/exit.svg'; import ArrowLeft from '../assets/arrow-left.svg'; import FileUpload from '../assets/file_upload.svg'; import WebsiteCollect from '../assets/website_collect.svg'; @@ -17,15 +16,16 @@ import { setSourceDocs, selectSourceDocs, } from '../preferences/preferenceSlice'; +import WrapperModal from '../modals/WrapperModal'; function Upload({ - modalState, setModalState, isOnboarding, + close, }: { - modalState: ActiveState; setModalState: (state: ActiveState) => void; isOnboarding: boolean; + close: () => void; }) { const [docName, setDocName] = useState(''); const [urlName, setUrlName] = useState(''); @@ -626,28 +626,17 @@ function Upload({ } return ( -
{ + close(); + setDocName(''); + setfiles([]); + setModalState('INACTIVE'); + setActiveTab(null); + }} > -
- {!isOnboarding && !progress && ( - - )} - {view} -
-
+ {view} + ); } From 04959df194c1d63232108e6331aa96a848dfcfc0 Mon Sep 17 00:00:00 2001 From: rohittcodes Date: Sat, 16 Nov 2024 19:45:22 +0530 Subject: [PATCH 2/2] refactor: upload --- frontend/src/modals/WrapperModal.tsx | 15 +++++++++++---- frontend/src/modals/types/index.ts | 1 + frontend/src/upload/Upload.tsx | 26 +++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/frontend/src/modals/WrapperModal.tsx b/frontend/src/modals/WrapperModal.tsx index 1a0128713..f17e0a8ad 100644 --- a/frontend/src/modals/WrapperModal.tsx +++ b/frontend/src/modals/WrapperModal.tsx @@ -2,10 +2,15 @@ import React, { useEffect, useRef } from 'react'; import { WrapperModalProps } from './types'; import Exit from '../assets/exit.svg'; -const WrapperModal: React.FC = ({ children, close }) => { +const WrapperModal: React.FC = ({ + children, + close, + isPerformingTask, +}) => { const modalRef = useRef(null); useEffect(() => { + if (isPerformingTask) return; const handleClickOutside = (event: MouseEvent) => { if ( modalRef.current && @@ -36,9 +41,11 @@ const WrapperModal: React.FC = ({ children, close }) => { ref={modalRef} className="relative w-11/12 rounded-2xl bg-white p-10 dark:bg-outer-space sm:w-[512px]" > - + {!isPerformingTask && ( + + )} {children}
diff --git a/frontend/src/modals/types/index.ts b/frontend/src/modals/types/index.ts index 2010bbb92..976bf0e9f 100644 --- a/frontend/src/modals/types/index.ts +++ b/frontend/src/modals/types/index.ts @@ -1,4 +1,5 @@ export type WrapperModalProps = { children?: React.ReactNode; + isPerformingTask?: boolean; close: () => void; }; diff --git a/frontend/src/upload/Upload.tsx b/frontend/src/upload/Upload.tsx index 612456d52..b956afd1d 100644 --- a/frontend/src/upload/Upload.tsx +++ b/frontend/src/upload/Upload.tsx @@ -600,7 +600,30 @@ function Upload({ ) : ( @@ -627,6 +650,7 @@ function Upload({ return ( { close(); setDocName('');