From 3e20934e20df96f619063203d53057904022ba31 Mon Sep 17 00:00:00 2001 From: AkashJana18 Date: Fri, 11 Oct 2024 12:15:51 +0530 Subject: [PATCH 1/5] Added search bar and button --- frontend/src/settings/APIKeys.tsx | 15 +++++++++++++-- frontend/src/settings/Documents.tsx | 18 +++++++++++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/frontend/src/settings/APIKeys.tsx b/frontend/src/settings/APIKeys.tsx index 4517e647..aa4b73d4 100644 --- a/frontend/src/settings/APIKeys.tsx +++ b/frontend/src/settings/APIKeys.tsx @@ -6,6 +6,7 @@ import Trash from '../assets/trash.svg'; import CreateAPIKeyModal from '../modals/CreateAPIKeyModal'; import SaveAPIKeyModal from '../modals/SaveAPIKeyModal'; import { APIKeyData } from './types'; +import Input from '../components/Input'; export default function APIKeys() { const { t } = useTranslation(); @@ -78,7 +79,16 @@ export default function APIKeys() { return (
-
+
+
+ +
+
@@ -90,7 +105,8 @@ const Documents: React.FC = ({ Delete { event.stopPropagation(); From f7063d03f1588085411c4b0b6bcb6dddda009d12 Mon Sep 17 00:00:00 2001 From: AkashJana18 Date: Thu, 17 Oct 2024 00:40:44 +0530 Subject: [PATCH 2/5] added search funtionality --- frontend/src/settings/APIKeys.tsx | 45 ++++++++++++++++++++++------- frontend/src/settings/Documents.tsx | 26 +++++++++++++---- 2 files changed, 54 insertions(+), 17 deletions(-) diff --git a/frontend/src/settings/APIKeys.tsx b/frontend/src/settings/APIKeys.tsx index aa4b73d4..28d414bb 100644 --- a/frontend/src/settings/APIKeys.tsx +++ b/frontend/src/settings/APIKeys.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import userService from '../api/services/userService'; @@ -10,10 +10,12 @@ import Input from '../components/Input'; export default function APIKeys() { const { t } = useTranslation(); - const [isCreateModalOpen, setCreateModal] = React.useState(false); - const [isSaveKeyModalOpen, setSaveKeyModal] = React.useState(false); - const [newKey, setNewKey] = React.useState(''); - const [apiKeys, setApiKeys] = React.useState([]); + const [isCreateModalOpen, setCreateModal] = useState(false); + const [isSaveKeyModalOpen, setSaveKeyModal] = useState(false); + const [newKey, setNewKey] = useState(''); + const [apiKeys, setApiKeys] = useState([]); + const [searchTerm, setSearchTerm] = useState(''); // Added state for search term + const [filteredKeys, setFilteredKeys] = useState([]); // State for filtered API keys const handleFetchKeys = async () => { try { @@ -23,6 +25,7 @@ export default function APIKeys() { } const apiKeys = await response.json(); setApiKeys(apiKeys); + setFilteredKeys(apiKeys); // Initialize the filtered keys as the fetched ones } catch (error) { console.log(error); } @@ -38,8 +41,12 @@ export default function APIKeys() { return response.json(); }) .then((data) => { - data.status === 'ok' && + if (data.status === 'ok') { setApiKeys((previous) => previous.filter((elem) => elem.id !== id)); + setFilteredKeys((previous) => + previous.filter((elem) => elem.id !== id), + ); + } }) .catch((error) => { console.error(error); @@ -63,6 +70,7 @@ export default function APIKeys() { }) .then((data) => { setApiKeys([...apiKeys, data]); + setFilteredKeys([...apiKeys, data]); // Update filtered keys too setCreateModal(false); setNewKey(data.key); setSaveKeyModal(true); @@ -73,9 +81,22 @@ export default function APIKeys() { }); }; - React.useEffect(() => { + useEffect(() => { handleFetchKeys(); }, []); + + // Filter API keys when the search term changes + useEffect(() => { + setFilteredKeys( + apiKeys.filter( + (key) => + key.name.toLowerCase().includes(searchTerm.toLowerCase()) || + key.source?.toLowerCase().includes(searchTerm.toLowerCase()) || + key.key.toLowerCase().includes(searchTerm.toLowerCase()), + ), + ); + }, [searchTerm, apiKeys]); + return (
@@ -84,9 +105,11 @@ export default function APIKeys() { setSearchTerm(e.target.value)} // Update search term />
- {!apiKeys?.length && ( + {!filteredKeys.length && ( )} - {apiKeys?.map((element, index) => ( + {filteredKeys.map((element, index) => ( diff --git a/frontend/src/settings/Documents.tsx b/frontend/src/settings/Documents.tsx index 43528297..d89aa0dd 100644 --- a/frontend/src/settings/Documents.tsx +++ b/frontend/src/settings/Documents.tsx @@ -1,3 +1,4 @@ +import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { useTranslation } from 'react-i18next'; import { useDispatch } from 'react-redux'; @@ -34,6 +35,10 @@ const Documents: React.FC = ({ }) => { const { t } = useTranslation(); const dispatch = useDispatch(); + + // State for search input + const [searchTerm, setSearchTerm] = useState(''); + const syncOptions = [ { label: 'Never', value: 'never' }, { label: 'Daily', value: 'daily' }, @@ -52,6 +57,12 @@ const Documents: React.FC = ({ }) .catch((error) => console.error(error)); }; + + // Filter documents based on the search term + const filteredDocuments = documents?.filter((document) => + document.name.toLowerCase().includes(searchTerm.toLowerCase()), + ); + return (
@@ -64,9 +75,11 @@ const Documents: React.FC = ({ name="Document-search-input" type="text" id="document-search-input" + value={searchTerm} + onChange={(e) => setSearchTerm(e.target.value)} // Handle search input change />
-
@@ -81,15 +94,15 @@ const Documents: React.FC = ({
- {!documents?.length && ( + {!filteredDocuments?.length && ( )} - {documents && - documents.map((document, index) => ( + {filteredDocuments && + filteredDocuments.map((document, index) => ( @@ -105,8 +118,7 @@ const Documents: React.FC = ({ Delete { event.stopPropagation(); @@ -138,8 +150,10 @@ const Documents: React.FC = ({ ); }; + Documents.propTypes = { documents: PropTypes.array.isRequired, handleDeleteDocument: PropTypes.func.isRequired, }; + export default Documents; From a2b0204a9586da8ea7db21d3eb13d641be3a6b4b Mon Sep 17 00:00:00 2001 From: AkashJana18 Date: Thu, 17 Oct 2024 01:01:17 +0530 Subject: [PATCH 3/5] Add new button triggers modal --- frontend/src/settings/Documents.tsx | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/frontend/src/settings/Documents.tsx b/frontend/src/settings/Documents.tsx index d89aa0dd..b2ac3f83 100644 --- a/frontend/src/settings/Documents.tsx +++ b/frontend/src/settings/Documents.tsx @@ -7,10 +7,11 @@ import userService from '../api/services/userService'; import SyncIcon from '../assets/sync.svg'; import Trash from '../assets/trash.svg'; import DropdownMenu from '../components/DropdownMenu'; -import { Doc, DocumentsProps } from '../models/misc'; +import { Doc, DocumentsProps, ActiveState } from '../models/misc'; // Ensure ActiveState type is imported import { getDocs } from '../preferences/preferenceApi'; import { setSourceDocs } from '../preferences/preferenceSlice'; import Input from '../components/Input'; +import Upload from '../upload/Upload'; // Import the Upload component // Utility function to format numbers const formatTokens = (tokens: number): string => { @@ -38,6 +39,9 @@ const Documents: React.FC = ({ // State for search input const [searchTerm, setSearchTerm] = useState(''); + // State for modal: active/inactive + const [modalState, setModalState] = useState('INACTIVE'); // Initialize with inactive state + const [isOnboarding, setIsOnboarding] = useState(false); // State for onboarding flag const syncOptions = [ { label: 'Never', value: 'never' }, @@ -79,7 +83,13 @@ const Documents: React.FC = ({ onChange={(e) => setSearchTerm(e.target.value)} // Handle search input change /> - @@ -146,6 +156,14 @@ const Documents: React.FC = ({
{t('settings.apiKeys.noData')}
{element.name} {element.source}
{t('settings.documents.noData')}
{document.name} {document.date}
+ {/* Conditionally render the Upload modal based on modalState */} + {modalState === 'ACTIVE' && ( + + )}
); From 5580d19b75f8d0c255883d608f42a58cda604a9a Mon Sep 17 00:00:00 2001 From: AkashJana18 Date: Tue, 22 Oct 2024 20:41:18 +0530 Subject: [PATCH 4/5] table redesign --- frontend/src/assets/caret-sort.svg | 1 + frontend/src/index.css | 10 ++++---- frontend/src/settings/Documents.tsx | 37 ++++++++++++++++++++++------- 3 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 frontend/src/assets/caret-sort.svg diff --git a/frontend/src/assets/caret-sort.svg b/frontend/src/assets/caret-sort.svg new file mode 100644 index 00000000..9380120d --- /dev/null +++ b/frontend/src/assets/caret-sort.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/index.css b/frontend/src/index.css index 5bcc7683..1eca983c 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -53,22 +53,24 @@ body.dark { } .table-default th { - @apply border-r border-silver dark:border-silver/40 p-4 w-[244px]; + @apply p-4 w-[244px] font-normal text-gray-400; /* Remove border-r */ } .table-default th:last-child { - @apply w-[auto] border-r-0; + @apply w-[auto]; } .table-default td { - @apply border-r border-t border-silver dark:border-silver/40 px-4 py-2; + @apply border-t border-silver dark:border-silver/40 px-4 py-2; /* Remove border-r */ } .table-default td:last-child { - @apply border-r-0; + @apply border-r-0; /* Ensure no right border on the last column */ } + } + /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ /* Document diff --git a/frontend/src/settings/Documents.tsx b/frontend/src/settings/Documents.tsx index b2ac3f83..67cdb6d0 100644 --- a/frontend/src/settings/Documents.tsx +++ b/frontend/src/settings/Documents.tsx @@ -6,6 +6,7 @@ import { useDispatch } from 'react-redux'; import userService from '../api/services/userService'; import SyncIcon from '../assets/sync.svg'; import Trash from '../assets/trash.svg'; +import caretSort from '../assets/caret-sort.svg'; import DropdownMenu from '../components/DropdownMenu'; import { Doc, DocumentsProps, ActiveState } from '../models/misc'; // Ensure ActiveState type is imported import { getDocs } from '../preferences/preferenceApi'; @@ -97,9 +98,24 @@ const Documents: React.FC = ({ {t('settings.documents.name')} - {t('settings.documents.date')} - {t('settings.documents.tokenUsage')} - {t('settings.documents.type')} + +
+ {t('settings.documents.date')}{' '} + {' '} +
+ + +
+ {t('settings.documents.tokenUsage')}{' '} + +
+ + +
+ {t('settings.documents.type')}{' '} + +
+ @@ -158,11 +174,16 @@ const Documents: React.FC = ({ {/* Conditionally render the Upload modal based on modalState */} {modalState === 'ACTIVE' && ( - +
+
+ {/* Your Upload component */} + +
+
)} From d18cb373fc86560f881db6cef8bd47f811b0db11 Mon Sep 17 00:00:00 2001 From: AkashJana18 Date: Wed, 23 Oct 2024 18:56:08 +0530 Subject: [PATCH 5/5] error fixed --- frontend/src/settings/APIKeys.tsx | 79 ++++--------------------------- 1 file changed, 10 insertions(+), 69 deletions(-) diff --git a/frontend/src/settings/APIKeys.tsx b/frontend/src/settings/APIKeys.tsx index b0f65aca..b039477c 100644 --- a/frontend/src/settings/APIKeys.tsx +++ b/frontend/src/settings/APIKeys.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; import userService from '../api/services/userService'; @@ -7,7 +7,6 @@ import CreateAPIKeyModal from '../modals/CreateAPIKeyModal'; import SaveAPIKeyModal from '../modals/SaveAPIKeyModal'; import { APIKeyData } from './types'; import SkeletonLoader from '../components/SkeletonLoader'; -import Input from '../components/Input'; export default function APIKeys() { const { t } = useTranslation(); @@ -16,9 +15,6 @@ export default function APIKeys() { const [newKey, setNewKey] = React.useState(''); const [apiKeys, setApiKeys] = React.useState([]); const [loading, setLoading] = useState(true); - const [searchTerm, setSearchTerm] = useState(''); // Added state for search term - const [filteredKeys, setFilteredKeys] = useState([]); // State for filtered API keys - const handleFetchKeys = async () => { setLoading(true); @@ -29,7 +25,6 @@ export default function APIKeys() { } const apiKeys = await response.json(); setApiKeys(apiKeys); - setFilteredKeys(apiKeys); // Initialize the filtered keys as the fetched ones } catch (error) { console.log(error); } finally { @@ -47,13 +42,8 @@ export default function APIKeys() { return response.json(); }) .then((data) => { - data.success === true && setApiKeys((previous) => previous.filter((elem) => elem.id !== id)); - setFilteredKeys((previous) => - previous.filter((elem) => elem.id !== id), - ); - } }) .catch((error) => { console.error(error); @@ -77,7 +67,6 @@ export default function APIKeys() { }) .then((data) => { setApiKeys([...apiKeys, data]); - setFilteredKeys([...apiKeys, data]); // Update filtered keys too setCreateModal(false); setNewKey(data.key); setSaveKeyModal(true); @@ -88,37 +77,14 @@ export default function APIKeys() { }); }; - useEffect(() => { + React.useEffect(() => { handleFetchKeys(); }, []); - // Filter API keys when the search term changes - useEffect(() => { - setFilteredKeys( - apiKeys.filter( - (key) => - key.name.toLowerCase().includes(searchTerm.toLowerCase()) || - key.source?.toLowerCase().includes(searchTerm.toLowerCase()) || - key.key.toLowerCase().includes(searchTerm.toLowerCase()), - ), - ); - }, [searchTerm, apiKeys]); - return (
-
-
- setSearchTerm(e.target.value)} // Update search term - /> -
+