diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index b858a0f7..cf68ff9c 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -24,7 +24,7 @@ jobs: python -m pytest --cov=application --cov-report=xml - name: Upload coverage reports to Codecov if: github.event_name == 'pull_request' && matrix.python-version == '3.11' - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/application/requirements.txt b/application/requirements.txt index 2f28c2ea..36a008a7 100644 --- a/application/requirements.txt +++ b/application/requirements.txt @@ -85,5 +85,5 @@ tzdata==2024.2 urllib3==2.2.3 vine==5.1.0 wcwidth==0.2.13 -werkzeug==3.0.4 +werkzeug==3.1.3 yarl==1.11.1 \ No newline at end of file diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 0a97c542..0714098f 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -17,8 +17,8 @@ "react-chartjs-2": "^5.2.0", "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.3.1", - "react-dropzone": "^14.2.3", "react-helmet": "^6.1.0", + "react-dropzone": "^14.3.5", "react-i18next": "^15.0.2", "react-markdown": "^9.0.1", "react-redux": "^8.0.5", @@ -2383,9 +2383,9 @@ } }, "node_modules/attr-accept": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", - "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.4.tgz", + "integrity": "sha512-2pA6xFIbdTUDCAwjN8nQwI+842VwzbDUXO2IYlpPXQIORgKnavorcr4Ce3rwh+zsNg9zK7QPsdvDj3Lum4WX4w==", "engines": { "node": ">=4" } @@ -4167,20 +4167,20 @@ } }, "node_modules/file-selector": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz", - "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-2.1.0.tgz", + "integrity": "sha512-ZuXAqGePcSPz4JuerOY06Dzzq0hrmQ6VGoXVzGyFI1npeOfBgqGIKKpznfYWRkSLJlXutkqVC5WvGZtkFVhu9Q==", "dependencies": { - "tslib": "^2.4.0" + "tslib": "^2.7.0" }, "engines": { "node": ">= 12" } }, "node_modules/file-selector/node_modules/tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, "node_modules/fill-range": { "version": "7.1.1", @@ -7842,12 +7842,12 @@ } }, "node_modules/react-dropzone": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.3.tgz", - "integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==", + "version": "14.3.5", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.3.5.tgz", + "integrity": "sha512-9nDUaEEpqZLOz5v5SUcFA0CjM4vq8YbqO0WRls+EYT7+DvxUdzDPKNCPLqGfj3YL9MsniCLCD4RFA6M95V6KMQ==", "dependencies": { - "attr-accept": "^2.2.2", - "file-selector": "^0.6.0", + "attr-accept": "^2.2.4", + "file-selector": "^2.1.0", "prop-types": "^15.8.1" }, "engines": { diff --git a/frontend/package.json b/frontend/package.json index 6fffd384..be08de0c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -28,8 +28,8 @@ "react-chartjs-2": "^5.2.0", "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.3.1", - "react-dropzone": "^14.2.3", "react-helmet": "^6.1.0", + "react-dropzone": "^14.3.5", "react-i18next": "^15.0.2", "react-markdown": "^9.0.1", "react-redux": "^8.0.5", diff --git a/frontend/src/Navigation.tsx b/frontend/src/Navigation.tsx index f6d65675..c29aaf20 100644 --- a/frontend/src/Navigation.tsx +++ b/frontend/src/Navigation.tsx @@ -476,8 +476,10 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) { /> {uploadModalState === 'ACTIVE' && ( setUploadModalState('INACTIVE')} > )} diff --git a/frontend/src/api/endpoints.ts b/frontend/src/api/endpoints.ts index 05c8f786..4e7112d0 100644 --- a/frontend/src/api/endpoints.ts +++ b/frontend/src/api/endpoints.ts @@ -17,7 +17,7 @@ const endpoints = { TOKEN_ANALYTICS: '/api/get_token_analytics', FEEDBACK_ANALYTICS: '/api/get_feedback_analytics', LOGS: `/api/get_user_logs`, - MANAGE_SYNC: '/api/manage_sync' + MANAGE_SYNC: '/api/manage_sync', }, CONVERSATION: { ANSWER: '/api/answer', diff --git a/frontend/src/assets/DragFileUpload.svg b/frontend/src/assets/DragFileUpload.svg new file mode 100644 index 00000000..1b41d193 --- /dev/null +++ b/frontend/src/assets/DragFileUpload.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/src/conversation/Conversation.tsx b/frontend/src/conversation/Conversation.tsx index 7f06d6b1..2614104e 100644 --- a/frontend/src/conversation/Conversation.tsx +++ b/frontend/src/conversation/Conversation.tsx @@ -1,8 +1,10 @@ -import { Fragment, useEffect, useRef, useState } from 'react'; +import { Fragment, useCallback, useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; import { useNavigate } from 'react-router-dom'; import Hero from '../Hero'; +import { useDropzone } from 'react-dropzone'; +import DragFileUpload from '../assets/DragFileUpload.svg'; import ArrowDown from '../assets/arrow-down.svg'; import newChatIcon from '../assets/openNewChat.svg'; import Send from '../assets/send.svg'; @@ -28,6 +30,8 @@ import { updateConversationId, updateQuery, } from './conversationSlice'; +import Upload from '../upload/Upload'; +import { ActiveState } from '../models/misc'; export default function Conversation() { const queries = useSelector(selectQueries); @@ -45,6 +49,47 @@ export default function Conversation() { const [isShareModalOpen, setShareModalState] = useState(false); const { t } = useTranslation(); const { isMobile } = useMediaQuery(); + const [uploadModalState, setUploadModalState] = + useState('INACTIVE'); + const [files, setFiles] = useState([]); + const [handleDragActive, setHandleDragActive] = useState(false); + + const onDrop = useCallback((acceptedFiles: File[]) => { + setUploadModalState('ACTIVE'); + setFiles(acceptedFiles); + setHandleDragActive(false); + }, []); + + const { getRootProps, getInputProps } = useDropzone({ + onDrop, + noClick: true, + multiple: true, + onDragEnter: () => { + setHandleDragActive(true); + }, + onDragLeave: () => { + setHandleDragActive(false); + }, + maxSize: 25000000, + accept: { + 'application/pdf': ['.pdf'], + 'text/plain': ['.txt'], + 'text/x-rst': ['.rst'], + 'text/x-markdown': ['.md'], + 'application/zip': ['.zip'], + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': + ['.docx'], + 'application/json': ['.json'], + 'text/csv': ['.csv'], + 'text/html': ['.html'], + 'application/epub+zip': ['.epub'], + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': [ + '.xlsx', + ], + 'application/vnd.openxmlformats-officedocument.presentationml.presentation': + ['.pptx'], + }, + }); const handleUserInterruption = () => { if (!eventInterrupt && status === 'loading') setEventInterrupt(true); @@ -323,7 +368,11 @@ export default function Conversation() {
-
+
+