diff --git a/packages/@uppy/dashboard/src/index.js b/packages/@uppy/dashboard/src/index.js index 3828678d0..5a5e420d2 100644 --- a/packages/@uppy/dashboard/src/index.js +++ b/packages/@uppy/dashboard/src/index.js @@ -117,6 +117,7 @@ module.exports = class Dashboard extends Plugin { hideProgressAfterFinish: false, note: null, closeModalOnClickOutside: false, + closeAfterFinish: false, disableStatusBar: false, disableInformer: false, disableThumbnailGenerator: false, @@ -154,7 +155,9 @@ module.exports = class Dashboard extends Plugin { this.maintainFocus = this.maintainFocus.bind(this) this.initEvents = this.initEvents.bind(this) - this.onKeydown = this.onKeydown.bind(this) + this.handleKeyDown = this.handleKeyDown.bind(this) + this.handleFileAdded = this.handleFileAdded.bind(this) + this.handleComplete = this.handleComplete.bind(this) this.handleClickOutside = this.handleClickOutside.bind(this) this.toggleFileCard = this.toggleFileCard.bind(this) this.toggleAddFilesPanel = this.toggleAddFilesPanel.bind(this) @@ -316,7 +319,7 @@ module.exports = class Dashboard extends Plugin { } // handle ESC and TAB keys in modal dialog - document.addEventListener('keydown', this.onKeydown) + document.addEventListener('keydown', this.handleKeyDown) // this.rerender(this.uppy.getState()) this.setFocusToBrowse() @@ -350,7 +353,7 @@ module.exports = class Dashboard extends Plugin { } // handle ESC and TAB keys in modal dialog - document.removeEventListener('keydown', this.onKeydown) + document.removeEventListener('keydown', this.handleKeyDown) this.savedActiveElement.focus() @@ -369,7 +372,7 @@ module.exports = class Dashboard extends Plugin { return !this.getPluginState().isHidden || false } - onKeydown (event) { + handleKeyDown (event) { // close modal on esc key press if (event.keyCode === ESC_KEY) this.requestCloseModal(event) // maintainFocus on tab key press @@ -456,10 +459,19 @@ module.exports = class Dashboard extends Plugin { this.ro.observe(this.el.querySelector('.uppy-Dashboard-inner')) this.uppy.on('plugin-remove', this.removeTarget) - this.uppy.on('file-added', (ev) => { - this.toggleAddFilesPanel(false) - this.hideAllPanels() - }) + this.uppy.on('file-added', this.handleFileAdded) + this.uppy.on('complete', this.handleComplete) + } + + handleFileAdded () { + this.toggleAddFilesPanel(false) + } + + handleComplete ({ failed, uploadID }) { + if (this.opts.closeAfterFinish && failed.length === 0) { + // All uploads are done + this.requestCloseModal() + } } removeEvents () { @@ -474,7 +486,8 @@ module.exports = class Dashboard extends Plugin { // window.removeEventListener('resize', this.throttledUpdateDashboardElWidth) window.removeEventListener('popstate', this.handlePopState, false) this.uppy.off('plugin-remove', this.removeTarget) - this.uppy.off('file-added', (ev) => this.toggleAddFilesPanel(false)) + this.uppy.off('file-added', this.handleFileAdded) + this.uppy.off('complete', this.handleComplete) } toggleFileCard (fileId) { @@ -653,7 +666,17 @@ module.exports = class Dashboard extends Plugin { targets: [] }) - const target = this.opts.target + const { inline, closeAfterFinish } = this.opts + if (inline && closeAfterFinish) { + throw new Error('[Dashboard] `closeAfterFinish: true` cannot be used on an inline Dashboard, because an inline Dashboard cannot be closed at all. Either set `inline: false`, or disable the `closeAfterFinish` option.') + } + + const { allowMultipleUploads } = this.uppy.opts + if (allowMultipleUploads && closeAfterFinish) { + this.uppy.log('[Dashboard] When using `closeAfterFinish`, we recommended setting the `allowMultipleUploads` option to `false` in the Uppy constructor. See https://uppy.io/docs/uppy/#allowMultipleUploads-true', 'warning') + } + + const { target } = this.opts if (target) { this.mount(target, this) } diff --git a/packages/@uppy/status-bar/src/StatusBar.js b/packages/@uppy/status-bar/src/StatusBar.js index c9d3bd5a2..7ad909f28 100644 --- a/packages/@uppy/status-bar/src/StatusBar.js +++ b/packages/@uppy/status-bar/src/StatusBar.js @@ -76,8 +76,13 @@ module.exports = (props) => { const width = typeof progressValue === 'number' ? progressValue : 100 const isHidden = (uploadState === statusBarStates.STATE_WAITING && props.hideUploadButton) || (uploadState === statusBarStates.STATE_WAITING && !props.newFiles > 0) || - (uploadState === statusBarStates.STATE_COMPLETE && props.hideAfterFinish) || - !props.allowNewUpload + (uploadState === statusBarStates.STATE_COMPLETE && props.hideAfterFinish) + + const showUploadButton = props.newFiles && !props.hideUploadButton && props.allowNewUpload + const showRetryButton = props.error && !props.hideRetryButton + const showCancelButton = !props.hidePauseResumeCancelButtons && + uploadState !== statusBarStates.STATE_WAITING && + uploadState !== statusBarStates.STATE_COMPLETE const progressClassNames = `uppy-StatusBar-progress ${progressMode ? 'is-' + progressMode : ''}` @@ -99,12 +104,9 @@ module.exports = (props) => { aria-valuenow={progressValue} /> {progressBarContent}
- { props.newFiles && !props.hideUploadButton ? : null } - { props.error && !props.hideRetryButton ? : null } - { !props.hidePauseResumeCancelButtons && uploadState !== statusBarStates.STATE_WAITING && uploadState !== statusBarStates.STATE_COMPLETE - ? - : null - } + { showUploadButton ? : null } + { showRetryButton ? : null } + { showCancelButton ? : null }
) diff --git a/website/src/docs/dashboard.md b/website/src/docs/dashboard.md index 77a6bb596..f6ff2a858 100644 --- a/website/src/docs/dashboard.md +++ b/website/src/docs/dashboard.md @@ -71,6 +71,7 @@ uppy.use(Dashboard, { hideProgressAfterFinish: false, note: null, closeModalOnClickOutside: false, + closeAfterFinish: false, disableStatusBar: false, disableInformer: false, disableThumbnailGenerator: false, @@ -184,6 +185,14 @@ Note that this metadata will only be set on a file object if it is entered by th Set to true to automatically close the modal when the user clicks outside of it. +### `closeAfterFinish: false` + +Set to true to automatically close the modal when all current uploads are complete. You can use this together with the [`allowMultipleUploads: false`](/docs/uppy#allowMultipleUploads-true) option in Uppy Core to create a smooth experience when uploading a single (batch of) file(s). + +With this option, the modal is only automatically closed when uploads are complete _and successful_. If some uploads failed, the modal stays open so the user can retry failed uploads or cancel the current batch and upload an entirely different set of files instead. + +> Setting [`allowMultipleUploads: false`](/docs/uppy#allowMultipleUploads-true) is **strongly** recommended when using this option. With multiple upload batches, the auto-closing behavior can be very confusing for users. + ### `disablePageScrollWhenModalOpen: true` Page scrolling is disabled by default when the Dashboard modal is open, so when you scroll a list of files in Uppy, the website in the background stays still. Set to false to override this behaviour and leave page scrolling intact.