mirror of
https://gitlab.com/bramw/baserow.git
synced 2024-11-21 23:37:55 +00:00
148 lines
4.3 KiB
JavaScript
148 lines
4.3 KiB
JavaScript
import UserFileService from '@baserow/modules/core/services/userFile'
|
|
|
|
/**
|
|
* This directive can be used to enable drag and drop (or click) user file upload.
|
|
* The selected files will be uploaded as a user file and the response, containing
|
|
* the file name, url, thumbnails etc will be communicated via the `done` function.
|
|
* The dragging and uploading state is communicated by calling the provided functions.
|
|
* It is possible for users to drag and drop a file inside the element. Clicking on the
|
|
* element opens a file picker.
|
|
*
|
|
* Example:
|
|
* <div
|
|
* v-user-file-upload="{
|
|
* check: (file) => {
|
|
* // Check if the file is accepted.
|
|
* return true
|
|
* },
|
|
* enter: () => {
|
|
* // Entered dragging state.
|
|
* },
|
|
* leave: () => {
|
|
* // Leaving dragging state.
|
|
* },
|
|
* progress: (event) => {
|
|
* // Upload progress changes.
|
|
* const percentage = Math.round((event.loaded * 100) / event.total)
|
|
* console.log(percentage)
|
|
* },
|
|
* done: (file) => {
|
|
* // The file has been uploaded.
|
|
* console.log(file)
|
|
* },
|
|
* }"
|
|
* >
|
|
* Drop here
|
|
* </div>
|
|
*/
|
|
export default {
|
|
/**
|
|
* Registers all the needed drop, drag and click events needed.
|
|
*/
|
|
bind(el, binding, vnode) {
|
|
binding.def.update(el, binding)
|
|
|
|
// The input that is needed to open the file chooser.
|
|
el.userFileUploadElement = document.createElement('input')
|
|
el.userFileUploadElement.accept = el.userFileUploadValue.accept()
|
|
el.userFileUploadElement.type = 'file'
|
|
el.userFileUploadElement.style.display = 'none'
|
|
el.userFileUploadElement.addEventListener('change', (event) => {
|
|
binding.def.upload(el, event, vnode.context.$client)
|
|
})
|
|
|
|
// The counter that is used to calculate if the user is dragging a file over the
|
|
// drop zone. It could be that enter and leave event are going are called
|
|
// multiple times without reentering the drop zone.
|
|
el.userFileUploadDragCounter = 0
|
|
|
|
el.userFileUploadDrop = (event) => {
|
|
event.preventDefault()
|
|
binding.def.upload(el, event, vnode.context.$client)
|
|
}
|
|
el.addEventListener('drop', el.userFileUploadDrop)
|
|
|
|
el.userFileUploadDragOver = (event) => {
|
|
event.preventDefault()
|
|
}
|
|
el.addEventListener('dragover', el.userFileUploadDragOver)
|
|
|
|
el.userFileUploadDragEnter = (event) => {
|
|
event.preventDefault()
|
|
if (el.userFileUploadDragCounter === 0) {
|
|
el.userFileUploadValue.enter()
|
|
}
|
|
el.userFileUploadDragCounter++
|
|
}
|
|
el.addEventListener('dragenter', el.userFileUploadDragEnter)
|
|
|
|
el.userFileUploadDragLeave = () => {
|
|
el.userFileUploadDragCounter--
|
|
if (el.userFileUploadDragCounter === 0) {
|
|
el.userFileUploadValue.leave()
|
|
}
|
|
}
|
|
el.addEventListener('dragleave', el.userFileUploadDragLeave)
|
|
|
|
el.userFileUploadClick = (event) => {
|
|
event.preventDefault()
|
|
el.userFileUploadElement.click(event)
|
|
}
|
|
el.addEventListener('click', el.userFileUploadClick)
|
|
},
|
|
/**
|
|
* Removes all the events registered in the bind function.
|
|
*/
|
|
unbind(el) {
|
|
el.removeEventListener('drop', el.userFileUploadDrop)
|
|
el.removeEventListener('dragover', el.userFileUploadDragOver)
|
|
el.removeEventListener('dragenter', el.userFileUploadDragEnter)
|
|
el.removeEventListener('dragleave', el.userFileUploadDragLeave)
|
|
el.removeEventListener('click', el.userFileUploadClick)
|
|
},
|
|
update(el, binding) {
|
|
const defaults = {
|
|
accept() {
|
|
return '*'
|
|
},
|
|
check() {
|
|
return true
|
|
},
|
|
enter() {},
|
|
leave() {},
|
|
progress() {},
|
|
done() {},
|
|
error() {},
|
|
}
|
|
el.userFileUploadValue = Object.assign(defaults, binding.value)
|
|
},
|
|
/**
|
|
* Called when a file must be uploaded. The progress will be shared by calling the
|
|
* provided functions.
|
|
*/
|
|
async upload(el, event, client) {
|
|
const files = event.target.files
|
|
? event.target.files
|
|
: event.dataTransfer.files
|
|
|
|
if (
|
|
files === null ||
|
|
files.length === 0 ||
|
|
!el.userFileUploadValue.check(files[0])
|
|
) {
|
|
return
|
|
}
|
|
|
|
try {
|
|
const { data } = await UserFileService(client).uploadFile(
|
|
files[0],
|
|
el.userFileUploadValue.progress
|
|
)
|
|
|
|
el.userFileUploadValue.done(data)
|
|
} catch (e) {
|
|
el.userFileUploadValue.error(e)
|
|
}
|
|
},
|
|
}
|