uploader.tsx
Overview
uploader.tsx is a React functional component module designed to provide a user-friendly interface for uploading files directly within a web application. It leverages a custom file upload UI library (@/components/file-upload) alongside custom hooks (useUploadCanvasFile) to handle file selection, drag-and-drop interaction, upload processing, progress display, and error handling.
The core component, FileUploadDirectUpload, supports uploading a single file at a time, visually displays upload progress and file metadata, and integrates with an external upload API through the useUploadCanvasFile hook. It also provides instant user feedback for rejected files using toast notifications.
Detailed Explanation
Component: FileUploadDirectUpload
A React component that enables users to upload files via drag-and-drop or file browsing, with support for direct upload to a backend or service.
Props
Prop Name | Type | Description |
|---|---|---|
| Callback invoked after a successful upload. Receives the response data object from the upload API. |
State
State Variable | Type | Description |
|---|---|---|
|
| Tracks the currently selected file(s) to upload. |
Internal Hooks Used
useUploadCanvasFile: Custom hook that exposes the uploadCanvasFile method to upload files to a specific backend or API.
Key Methods and Callbacks
onUpload
Type:
NonNullable<FileUploadProps['onUpload']>Purpose: Handles the actual uploading process when files are selected.
Parameters:
files:File[]- Array of files to upload.callbacks: { onSuccess: (file: File) => void; onError: (file: File, error: Error) => void; } - Callbacks to indicate success or failure of each file upload.
Returns:
Promise<void>Description: Iterates over each file, calls uploadCanvasFile to perform the upload, and manages success and error callbacks. Uses
Promise.allto await completion of all upload attempts. Handles unexpected errors gracefully.Usage Example:
onUpload(files, { onSuccess: (file) => console.log(`${file.name} uploaded successfully.`), onError: (file, error) => console.error(`${file.name} failed:`, error), });
onFileReject
Type:
(file: File, message: string) => voidPurpose: Displays a toast notification when a file is rejected (e.g., due to validation failures).
Parameters:
file: The rejectedFileobject.message: A string message explaining the rejection.
Returns:
voidDescription: Uses the
toastfunction fromsonnerto notify the user, truncating the file name if too long.Usage Example:
onFileReject(file, "File type not supported.");
Rendered UI Structure
The component renders a FileUpload container with these main parts:
FileUploadDropzone: Area supporting drag & drop and click-to-browse file selection.
Displays an upload icon with instructions.
Has a button to trigger file browsing.
FileUploadList: Displays a list of selected files with:
A preview of the file (
FileUploadItemPreview).File metadata such as name and size (
FileUploadItemMetadata).A delete button to remove the file from the selection (
FileUploadItemDelete).Upload progress bar (
FileUploadItemProgress).
Important Implementation Details and Algorithms
Upload Handling with Concurrency:
UsesPromise.allto concurrently upload multiple files if needed (although the UI limits max files to 1). This pattern allows efficient asynchronous uploads and collective error handling.Error Handling:
Each file upload is wrapped in a try-catch. If upload fails or returns a non-zerocode,onErrorcallback is invoked with an appropriate error object. Unexpected errors are logged to the console.File Rejection Feedback:
When a file is rejected (e.g., due to exceeding max files or unsupported type), a toast notification is shown, enhancing user experience.Controlled Files State:
The component manages the selected files in local state (files), syncing with the underlyingFileUploadcomponent's value.Single File Limit:
Although the dropzone UI mentions max 2 files, the actualmaxFilesprop is set to 1, enforcing single file upload.
Interaction with Other Parts of the System
UI Components:
Imports multiple reusable UI components from@/components/file-uploadthat encapsulate file upload related UI elements (dropzone, list, items, progress, delete button, etc.).Custom Hook:
UtilizesuseUploadCanvasFilehook (from@/hooks/use-agent-request) which abstracts the API call to upload files to the backend or cloud service.Third-party Libraries:
lucide-reactfor SVG icons (Upload,X).sonnerfor toast notifications.
Parent Application:
TheonChangeprop callback allows the parent component or system to react to upload results, e.g., updating state or triggering further processing based on the uploaded file data.
Usage Example
import { FileUploadDirectUpload } from './uploader';
function MyUploaderParentComponent() {
const [uploadedData, setUploadedData] = React.useState(null);
return (
<FileUploadDirectUpload
onChange={(data) => {
console.log('Upload succeeded with data:', data);
setUploadedData(data);
}}
/>
);
}
Visual Diagram
componentDiagram
component FileUploadDirectUpload {
+files: File[]
+onUpload(files, callbacks): Promise<void>
+onFileReject(file, message): void
+render()
}
component FileUpload {
+value
+onValueChange
+onUpload
+onFileReject
+maxFiles
+multiple
}
component FileUploadDropzone
component FileUploadTrigger
component FileUploadList
component FileUploadItem
component FileUploadItemPreview
component FileUploadItemMetadata
component FileUploadItemDelete
component FileUploadItemProgress
component Button
component useUploadCanvasFile
FileUploadDirectUpload --> FileUpload
FileUpload --> FileUploadDropzone
FileUploadDropzone --> FileUploadTrigger
FileUpload --> FileUploadList
FileUploadList --> FileUploadItem
FileUploadItem --> FileUploadItemPreview
FileUploadItem --> FileUploadItemMetadata
FileUploadItem --> FileUploadItemDelete
FileUploadItem --> FileUploadItemProgress
FileUploadItemDelete --> Button
FileUploadDropzone --> Button
FileUploadDirectUpload --> useUploadCanvasFile
Summary
Purpose: Provides a robust UI and upload mechanism for direct file uploads with drag-and-drop and file browsing.
Functionality: Handles file selection, upload processing with progress and error handling, and user feedback.
Integration: Connects UI components with a backend upload API via custom hooks.
User Experience: Includes visual progress, metadata display, deletion, and toast notifications for errors.
This file is a key part of the file upload workflow in the application, abstracting complexity and providing a seamless user experience for uploading files.