import type { Body, Meta, State, UIPlugin, UIPluginOptions, Uppy, UppyFile, } from '@uppy/core' import type { I18n, Translator } from '@uppy/utils' import { isDragDropSupported } from '@uppy/utils' import classNames from 'classnames' import type { h } from 'preact' import type { DashboardState, TargetWithRender } from '../Dashboard.js' import AddFiles from './AddFiles.js' import AddFilesPanel from './AddFilesPanel.js' import EditorPanel from './EditorPanel.js' import FileCard from './FileCard/index.js' import FileList from './FileList.js' import Informer from './Informer/Informer.js' import PickerPanelContent from './PickerPanelContent.js' import PanelTopBar from './PickerPanelTopBar.js' import Slide from './Slide.js' import StatusBar from './StatusBar/StatusBar.js' // http://dev.edenspiekermann.com/2016/02/11/introducing-accessible-modal-dialog // https://github.com/ghosh/micromodal const WIDTH_XL = 900 const WIDTH_LG = 700 const WIDTH_MD = 576 const HEIGHT_MD = 330 // We might want to enable this in the future // const HEIGHT_LG = 400 // const HEIGHT_XL = 460 type DashboardUIProps = { state: State isHidden: boolean files: State['files'] newFiles: UppyFile[] uploadStartedFiles: UppyFile[] completeFiles: UppyFile[] erroredFiles: UppyFile[] inProgressFiles: UppyFile[] inProgressNotPausedFiles: UppyFile[] processingFiles: UppyFile[] isUploadStarted: boolean isAllComplete: boolean isAllPaused: boolean totalFileCount: number totalProgress: number allowNewUpload: boolean acquirers: TargetWithRender[] theme: string disabled: boolean disableLocalFiles: boolean direction: UIPluginOptions['direction'] activePickerPanel: DashboardState['activePickerPanel'] showFileEditor: boolean saveFileEditor: () => void closeFileEditor: () => void disableInteractiveElements: (disable: boolean) => void animateOpenClose: boolean isClosing: boolean progressindicators: TargetWithRender[] editors: TargetWithRender[] autoProceed: boolean id: string closeModal: () => void handleClickOutside: () => void handleInputChange: ( event: h.JSX.TargetedEvent, ) => void handlePaste: (event: ClipboardEvent) => void inline: boolean showPanel: (id: string) => void hideAllPanels: () => void i18n: I18n i18nArray: Translator['translateArray'] uppy: Uppy note: string | null recoveredState: State['recoveredState'] metaFields: DashboardState['metaFields'] resumableUploads: boolean individualCancellation: boolean isMobileDevice?: boolean fileCardFor: string | null toggleFileCard: (show: boolean, fileID: string) => void toggleAddFilesPanel: (show: boolean) => void showAddFilesPanel: boolean saveFileCard: (meta: M, fileID: string) => void openFileEditor: (file: UppyFile) => void canEditFile: (file: UppyFile) => boolean width: string | number height: string | number showLinkToFileUploadResult: boolean fileManagerSelectionType: string proudlyDisplayPoweredByUppy: boolean hideCancelButton: boolean hideRetryButton: boolean hidePauseResumeButton: boolean showRemoveButtonAfterComplete: boolean containerWidth: number containerHeight: number areInsidesReadyToBeVisible: boolean parentElement: HTMLElement | null allowedFileTypes: string[] | null maxNumberOfFiles: number | null requiredMetaFields: any showSelectedFiles: boolean showNativePhotoCameraButton: boolean showNativeVideoCameraButton: boolean nativeCameraFacingMode: 'user' | 'environment' | '' singleFileFullScreen: boolean handleRequestThumbnail: (file: UppyFile) => void handleCancelThumbnail: (file: UppyFile) => void isDraggingOver: boolean handleDragOver: (event: DragEvent) => void handleDragLeave: (event: DragEvent) => void handleDrop: (event: DragEvent) => void disableInformer: boolean disableStatusBar: boolean hideProgressDetails: boolean hideUploadButton: boolean hideProgressAfterFinish: boolean doneButtonHandler: (() => void) | null } export default function Dashboard( props: DashboardUIProps, ) { const isNoFiles = props.totalFileCount === 0 const isSingleFile = props.totalFileCount === 1 const isSizeMD = props.containerWidth > WIDTH_MD const isSizeHeightMD = props.containerHeight > HEIGHT_MD const dashboardClassName = classNames({ 'uppy-Dashboard': true, 'uppy-Dashboard--isDisabled': props.disabled, 'uppy-Dashboard--animateOpenClose': props.animateOpenClose, 'uppy-Dashboard--isClosing': props.isClosing, 'uppy-Dashboard--isDraggingOver': props.isDraggingOver, 'uppy-Dashboard--modal': !props.inline, 'uppy-size--md': props.containerWidth > WIDTH_MD, 'uppy-size--lg': props.containerWidth > WIDTH_LG, 'uppy-size--xl': props.containerWidth > WIDTH_XL, 'uppy-size--height-md': props.containerHeight > HEIGHT_MD, // We might want to enable this in the future // 'uppy-size--height-lg': props.containerHeight > HEIGHT_LG, // 'uppy-size--height-xl': props.containerHeight > HEIGHT_XL, 'uppy-Dashboard--isAddFilesPanelVisible': props.showAddFilesPanel, 'uppy-Dashboard--isInnerWrapVisible': props.areInsidesReadyToBeVisible, // Only enable “centered single file” mode when Dashboard is tall enough 'uppy-Dashboard--singleFile': props.singleFileFullScreen && isSingleFile && isSizeHeightMD, }) // Important: keep these in sync with the percent width values in `src/components/FileItem/index.scss`. let itemsPerRow = 1 // mobile if (props.containerWidth > WIDTH_XL) { itemsPerRow = 5 } else if (props.containerWidth > WIDTH_LG) { itemsPerRow = 4 } else if (props.containerWidth > WIDTH_MD) { itemsPerRow = 3 } const showFileList = props.showSelectedFiles && !isNoFiles const numberOfFilesForRecovery = props.recoveredState ? Object.keys(props.recoveredState.files).length : null const numberOfGhosts = props.files ? Object.keys(props.files).filter((fileID) => props.files[fileID].isGhost) .length : 0 const renderRestoredText = () => { if (numberOfGhosts > 0) { return props.i18n('recoveredXFiles', { smart_count: numberOfGhosts, }) } return props.i18n('recoveredAllFiles') } const dashboard = ( // biome-ignore lint/a11y/useAriaPropsSupportedByRole: ...
) return dashboard }