UNPKG

@neo4j-ndl/react

Version:

React implementation of Neo4j Design System

107 lines 6.04 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; /** * * Copyright (c) "Neo4j" * Neo4j Sweden AB [http://neo4j.com] * * This file is part of Neo4j. * * Neo4j is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ import { XMarkIcon } from '@heroicons/react/24/solid'; import { Dropzone, FilledButton, Typography } from '@neo4j-ndl/react'; import { useCallback, useState } from 'react'; // Configuration constants const CONFIG = { MAX_FILES: 3, MAX_FILE_SIZE: 5 * 1024 * 1024, // 5MB PROGRESS_INCREMENT: 5, UPDATE_INTERVAL: 100, ACCEPTED_EXTENSIONS: ['.txt', '.json'], }; var UploadState; (function (UploadState) { UploadState["Idle"] = "idle"; UploadState["Uploading"] = "uploading"; UploadState["Success"] = "success"; UploadState["Error"] = "error"; })(UploadState || (UploadState = {})); const Component = () => { const [uploadData, setUploadData] = useState({ errors: [], files: [], progress: 0, state: UploadState.Idle, }); const resetUpload = useCallback(() => { setUploadData({ errors: [], files: [], progress: 0, state: UploadState.Idle, }); }, []); const simulateUpload = useCallback((files) => { setUploadData((prev) => (Object.assign(Object.assign({}, prev), { state: UploadState.Uploading, files, progress: 0 }))); const interval = setInterval(() => { setUploadData((prev) => { const newProgress = prev.progress + CONFIG.PROGRESS_INCREMENT; if (newProgress >= 100) { clearInterval(interval); setTimeout(() => setUploadData((current) => (Object.assign(Object.assign({}, current), { state: UploadState.Success }))), 500); return Object.assign(Object.assign({}, prev), { progress: 100 }); } return Object.assign(Object.assign({}, prev), { progress: newProgress }); }); }, CONFIG.UPDATE_INTERVAL); }, []); const handleDrop = useCallback((acceptedFiles, rejectedFiles, event) => { console.info('Drop event:', { acceptedFiles, event, rejectedFiles }); if (acceptedFiles.length > 0) { simulateUpload(acceptedFiles); } }, [simulateUpload]); const handleDropRejected = useCallback((rejectedFiles) => { const errors = rejectedFiles.map((file) => `${file.file.name}: ${file.errors.map((e) => e.message).join(', ')}`); setUploadData((prev) => (Object.assign(Object.assign({}, prev), { state: UploadState.Error, errors }))); }, []); const handleError = useCallback((error) => { console.error('Dropzone error:', error); setUploadData((prev) => (Object.assign(Object.assign({}, prev), { state: UploadState.Error, errors: [error.message] }))); }, []); const renderStatusContent = () => { const { state, progress, files, errors } = uploadData; switch (state) { case UploadState.Uploading: return (_jsx(Dropzone.LoadingProgressBar, { progressBarPrecentage: Math.round(progress) })); case UploadState.Success: return (_jsxs("div", { className: "n-flex n-flex-col n-justify-center n-items-center n-gap-y-token-32", children: [_jsx(Typography, { variant: "title-4", className: "n-text-success-text n-font-semibold", children: "Upload Complete!" }), _jsxs(Typography, { variant: "body-small", className: "n-text-neutral-text-weak", children: ["Successfully uploaded: ", files.map((file) => file.name).join(', ')] }), _jsx(FilledButton, { onClick: resetUpload, children: "Upload More Files" })] })); case UploadState.Error: return (_jsxs("div", { className: "n-flex n-flex-col n-justify-center n-items-center n-gap-y-token-32", children: [_jsx(XMarkIcon, { className: "n-w-token-32 n-h-token-32 n-text-danger-text" }), _jsx("div", { className: "n-flex n-flex-col n-gap-y-token-2", children: errors.map((message, index) => (_jsx(Typography, { variant: "label", className: "n-text-danger-text n-font-semibold", htmlAttributes: { role: 'alert' }, children: message }, index))) }), _jsx(FilledButton, { onClick: resetUpload, children: "Try Again" })] })); default: return undefined; } }; return (_jsx(Dropzone, { dropZoneOptions: { disabled: uploadData.state === UploadState.Uploading, maxFiles: CONFIG.MAX_FILES, maxSize: CONFIG.MAX_FILE_SIZE, multiple: true, onDrop: handleDrop, onDropRejected: handleDropRejected, onError: handleError, }, supportedFilesDescription: _jsxs("div", { className: "n-text-center n-flex n-flex-col n-gap-y-token-2", children: [_jsx(Typography, { variant: "body-small", className: "n-text-neutral-text-weak", children: "Supports: Text files (.txt, .json) only" }), _jsxs(Typography, { variant: "body-small", className: "n-text-neutral-text-weak", children: ["Max ", CONFIG.MAX_FILES, " files \u2022", ' ', CONFIG.MAX_FILE_SIZE / (1024 * 1024), "MB per file"] })] }), acceptedFileExtensions: CONFIG.ACCEPTED_EXTENSIONS, loadingElement: renderStatusContent(), rejectedText: "Error: Please make sure to only upload .json or .txt files", heading: "Drag & Drop your files" })); }; export default Component; //# sourceMappingURL=dropzone-full.story.js.map