Download frontend/src/components/Modals/ManageWorkspace/Documents/UploadFile/index.jsx from leowuming/rag: direct link, hf CLI and curl.
- Browser
- Download file 6.06 kB
-
https://huggingface.co/spaces/leowuming/rag/resolve/main/frontend/src/components/Modals/ManageWorkspace/Documents/UploadFile/index.jsx
- Command line
-
hf download hf://spaces/leowuming/rag/frontend/src/components/Modals/ManageWorkspace/Documents/UploadFile/index.jsx
-
curl -L -o index.jsx https://huggingface.co/spaces/leowuming/rag/resolve/main/frontend/src/components/Modals/ManageWorkspace/Documents/UploadFile/index.jsx
6.06 kB
| import { CloudArrowUp } from "@phosphor-icons/react"; | |
| import { useEffect, useState } from "react"; | |
| import { useTranslation } from "react-i18next"; | |
| import showToast from "../../../../../utils/toast"; | |
| import System from "../../../../../models/system"; | |
| import { useDropzone } from "react-dropzone"; | |
| import { v4 } from "uuid"; | |
| import FileUploadProgress from "./FileUploadProgress"; | |
| import Workspace from "../../../../../models/workspace"; | |
| import debounce from "lodash.debounce"; | |
| export default function UploadFile({ | |
| workspace, | |
| fetchKeys, | |
| setLoading, | |
| setLoadingMessage, | |
| }) { | |
| const { t } = useTranslation(); | |
| const [ready, setReady] = useState(false); | |
| const [files, setFiles] = useState([]); | |
| const [fetchingUrl, setFetchingUrl] = useState(false); | |
| const handleSendLink = async (e) => { | |
| e.preventDefault(); | |
| setLoading(true); | |
| setLoadingMessage("Scraping link..."); | |
| setFetchingUrl(true); | |
| const formEl = e.target; | |
| const form = new FormData(formEl); | |
| const { response, data } = await Workspace.uploadLink( | |
| workspace.slug, | |
| form.get("link") | |
| ); | |
| if (!response.ok) { | |
| showToast(`Error uploading link: ${data.error}`, "error"); | |
| } else { | |
| fetchKeys(true); | |
| showToast("Link uploaded successfully", "success"); | |
| formEl.reset(); | |
| } | |
| setLoading(false); | |
| setFetchingUrl(false); | |
| }; | |
| // Queue all fetchKeys calls through the same debouncer to prevent spamming the server. | |
| // either a success or error will trigger a fetchKeys call so the UI is not stuck loading. | |
| const debouncedFetchKeys = debounce(() => fetchKeys(true), 1000); | |
| const handleUploadSuccess = () => debouncedFetchKeys(); | |
| const handleUploadError = () => debouncedFetchKeys(); | |
| const onDrop = async (acceptedFiles, rejections) => { | |
| const newAccepted = acceptedFiles.map((file) => { | |
| return { | |
| uid: v4(), | |
| file, | |
| }; | |
| }); | |
| const newRejected = rejections.map((file) => { | |
| return { | |
| uid: v4(), | |
| file: file.file, | |
| rejected: true, | |
| reason: file.errors[0].code, | |
| }; | |
| }); | |
| setFiles([...newAccepted, ...newRejected]); | |
| }; | |
| useEffect(() => { | |
| async function checkProcessorOnline() { | |
| const online = await System.checkDocumentProcessorOnline(); | |
| setReady(online); | |
| } | |
| checkProcessorOnline(); | |
| }, []); | |
| const { getRootProps, getInputProps } = useDropzone({ | |
| onDrop, | |
| disabled: !ready, | |
| }); | |
| return ( | |
| <div> | |
| <div | |
| className={`w-[560px] border-dashed border-[2px] border-theme-modal-border light:border-[#686C6F] rounded-2xl bg-theme-bg-primary transition-colors duration-300 p-3 ${ | |
| ready | |
| ? " light:bg-[#E0F2FE] cursor-pointer hover:bg-theme-bg-secondary light:hover:bg-transparent" | |
| : "cursor-not-allowed" | |
| }`} | |
| {...getRootProps()} | |
| > | |
| <input {...getInputProps()} /> | |
| {ready === false ? ( | |
| <div className="flex flex-col items-center justify-center h-full"> | |
| <CloudArrowUp className="w-8 h-8 text-white/80 light:invert" /> | |
| <div className="text-white text-opacity-80 text-sm font-semibold py-1"> | |
| {t("connectors.upload.processor-offline")} | |
| </div> | |
| <div className="text-white text-opacity-60 text-xs font-medium py-1 px-20 text-center"> | |
| {t("connectors.upload.processor-offline-desc")} | |
| </div> | |
| </div> | |
| ) : files.length === 0 ? ( | |
| <div className="flex flex-col items-center justify-center"> | |
| <CloudArrowUp className="w-8 h-8 text-white/80 light:invert" /> | |
| <div className="text-white text-opacity-80 text-sm font-semibold py-1"> | |
| {t("connectors.upload.click-upload")} | |
| </div> | |
| <div className="text-white text-opacity-60 text-xs font-medium py-1"> | |
| {t("connectors.upload.file-types")} | |
| </div> | |
| </div> | |
| ) : ( | |
| <div className="grid grid-cols-2 gap-2 overflow-auto max-h-[180px] p-1 overflow-y-scroll no-scroll"> | |
| {files.map((file) => ( | |
| <FileUploadProgress | |
| key={file.uid} | |
| file={file.file} | |
| uuid={file.uid} | |
| setFiles={setFiles} | |
| slug={workspace.slug} | |
| rejected={file?.rejected} | |
| reason={file?.reason} | |
| onUploadSuccess={handleUploadSuccess} | |
| onUploadError={handleUploadError} | |
| setLoading={setLoading} | |
| setLoadingMessage={setLoadingMessage} | |
| /> | |
| ))} | |
| </div> | |
| )} | |
| </div> | |
| <div className="text-center text-white text-opacity-50 text-xs font-medium w-[560px] py-2"> | |
| {t("connectors.upload.or-submit-link")} | |
| </div> | |
| <form onSubmit={handleSendLink} className="flex gap-x-2"> | |
| <input | |
| disabled={fetchingUrl} | |
| name="link" | |
| type="url" | |
| className="border-none disabled:bg-theme-settings-input-bg disabled:text-theme-settings-input-placeholder bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-3/4 p-2.5" | |
| placeholder={t("connectors.upload.placeholder-link")} | |
| autoComplete="off" | |
| /> | |
| <button | |
| disabled={fetchingUrl} | |
| type="submit" | |
| className="disabled:bg-white/20 disabled:text-slate-300 disabled:border-slate-400 disabled:cursor-wait bg bg-transparent hover:bg-slate-200 hover:text-slate-800 w-auto border border-white light:border-theme-modal-border text-sm text-white p-2.5 rounded-lg" | |
| > | |
| {fetchingUrl | |
| ? t("connectors.upload.fetching") | |
| : t("connectors.upload.fetch-website")} | |
| </button> | |
| </form> | |
| <div className="mt-6 text-center text-white text-opacity-80 text-xs font-medium w-[560px]"> | |
| {t("connectors.upload.privacy-notice")} | |
| </div> | |
| </div> | |
| ); | |
| } | |