WIP: Implement uploads
This commit is contained in:
@@ -24,8 +24,13 @@ export default class extends Controller {
|
||||
})
|
||||
|
||||
this.buttonTargets.forEach((element, index) => {
|
||||
if (this.hasButtonActiveClass) {
|
||||
element.classList.toggle(this.buttonActiveClass, activeTab === index)
|
||||
if (false === this.hasButtonActiveClass) {
|
||||
return
|
||||
}
|
||||
if (activeTab === index) {
|
||||
element.classList.add(...this.buttonActiveClasses)
|
||||
} else {
|
||||
element.classList.remove(...this.buttonActiveClasses)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import { Controller } from '@hotwired/stimulus'
|
||||
import { useFetch } from '../mixins/use_fetch'
|
||||
import Dropzone from 'dropzone'
|
||||
import 'dropzone/dist/dropzone.css'
|
||||
Dropzone.autoDiscover = false
|
||||
|
||||
/* stimulusFetch: 'lazy' */
|
||||
export default class extends Controller {
|
||||
|
||||
static targets = [
|
||||
'dropzone',
|
||||
]
|
||||
|
||||
static values = {
|
||||
endpointUpload: String,
|
||||
endpointDelete: String,
|
||||
maxFiles: Number,
|
||||
maxFilesize: Number,
|
||||
acceptedFiles: String,
|
||||
chunking: Boolean,
|
||||
params: Object,
|
||||
}
|
||||
|
||||
connect () {
|
||||
useFetch(this)
|
||||
|
||||
const dropzone = new Dropzone(this.dropzoneTarget, {
|
||||
url: this.endpointUploadValue,
|
||||
withCredentials: true,
|
||||
maxFiles: this.maxFilesValue,
|
||||
maxFilesize: this.maxFilesizeValue,
|
||||
acceptedFiles: this.acceptedFilesValue,
|
||||
chunking: this.chunkingValue,
|
||||
chunkSize: 10000000,
|
||||
parallelUploads: 3,
|
||||
retryChunks: true,
|
||||
disablePreviews: false,
|
||||
createImageThumbnails: true,
|
||||
autoProcessQueue: true,
|
||||
addRemoveLinks: true,
|
||||
})
|
||||
|
||||
dropzone.on('sending', (file, xhr, formData) => {
|
||||
if (this.hasParamsValue) {
|
||||
let keys = Object.keys(this.paramsValue)
|
||||
keys.forEach(key => {
|
||||
formData.append(key, this.paramsValue[key])
|
||||
})
|
||||
}
|
||||
formData.append('uuid', file.upload.uuid)
|
||||
formData.append('originalFilename', file.name)
|
||||
window.dispatchEvent(new CustomEvent('dropzone:uploading'))
|
||||
})
|
||||
|
||||
dropzone.on('queuecomplete', () => {
|
||||
window.dispatchEvent(new CustomEvent('dropzone:complete'))
|
||||
})
|
||||
|
||||
dropzone.on('removedfile', (file) => {
|
||||
fetch(`${this.endpointDeleteValue}?uuid=${file.upload.uuid}`, { method: 'delete', credentials: 'include' })
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
import { Controller } from '@hotwired/stimulus'
|
||||
import Dropzone from 'dropzone'
|
||||
Dropzone.autoDiscover = false
|
||||
|
||||
/* stimulusFetch: 'lazy' */
|
||||
export default class extends Controller {
|
||||
|
||||
static targets = [
|
||||
'dropzone',
|
||||
'queue',
|
||||
'previewTemplate',
|
||||
'fieldsTemplate',
|
||||
'fields',
|
||||
'error',
|
||||
'errorMessage',
|
||||
'upload',
|
||||
]
|
||||
|
||||
static values = {
|
||||
endpoint: String,
|
||||
maxFiles: Number,
|
||||
maxFilesize: Number,
|
||||
acceptedFiles: String,
|
||||
chunking: Boolean,
|
||||
language: Object,
|
||||
params: Object,
|
||||
uploads: Array,
|
||||
error: String,
|
||||
formName: String,
|
||||
}
|
||||
|
||||
initialize() {
|
||||
this.fieldsTemplate = this.fieldsTemplateTarget.innerHTML
|
||||
}
|
||||
|
||||
connect () {
|
||||
const dropzone = new Dropzone(this.dropzoneTarget, {
|
||||
url: this.endpointValue,
|
||||
withCredentials: true,
|
||||
maxFiles: this.maxFilesValue,
|
||||
maxFilesize: this.maxFilesizeValue,
|
||||
acceptedFiles: this.acceptedFilesValue,
|
||||
chunking: this.chunkingValue,
|
||||
chunkSize: 10000000,
|
||||
parallelUploads: 3,
|
||||
retryChunks: true,
|
||||
previewsContainer: this.queueTarget,
|
||||
previewTemplate: this.previewTemplateTarget.innerHTML,
|
||||
createImageThumbnails: true,
|
||||
dictFileTooBig: this.languageValue.fileTooBig,
|
||||
dictInvalidFileType: this.languageValue.invalidFileType,
|
||||
dictMaxFilesExceeded: this.languageValue.maxFilesExceeded,
|
||||
})
|
||||
|
||||
dropzone.on('addedfile', file => {
|
||||
if (this.maxFilesValue > this.uploadsValue.length) {
|
||||
this._removeFile(file.id)
|
||||
return
|
||||
}
|
||||
this.errorValue = ''
|
||||
const uploads = this.uploadsValue;
|
||||
uploads.pop()
|
||||
this.uploadsValue = uploads
|
||||
})
|
||||
|
||||
dropzone.on('removedfile', file => {
|
||||
this._removeFile(file.upload.uuid)
|
||||
})
|
||||
|
||||
dropzone.on('maxfilesexceeded', file => {
|
||||
this.errorValue = dropzone.options.dictMaxFilesExceeded
|
||||
dropzone.removeFile(file);
|
||||
})
|
||||
|
||||
dropzone.on('error', (file, errorMessage) => {
|
||||
this.errorValue = errorMessage;
|
||||
dropzone.removeFile(file)
|
||||
})
|
||||
|
||||
dropzone.on('dragenter', () => {
|
||||
this.errorValue = ''
|
||||
})
|
||||
|
||||
dropzone.on('success', file => {
|
||||
const response = JSON.parse(file.xhr.response)
|
||||
const uploads = this.uploadsValue
|
||||
uploads.push({
|
||||
filename: response.filename,
|
||||
originalFilename: response.originalFilename,
|
||||
uploaderType: response.uploaderType,
|
||||
size: response.size,
|
||||
mimeType: response.mimeType,
|
||||
fileId: file.upload.uuid
|
||||
})
|
||||
this.uploadsValue = uploads
|
||||
window.dispatchEvent(new CustomEvent('dropzone', {
|
||||
detail: 'success'
|
||||
}))
|
||||
})
|
||||
|
||||
dropzone.on('sending', () => {
|
||||
window.dispatchEvent(new CustomEvent('dropzone', {
|
||||
detail: 'uploading'
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
errorValueChanged () {
|
||||
if ('' === this.errorValue) {
|
||||
this.errorTarget.classList.add('hidden')
|
||||
} else {
|
||||
this.errorMessageTarget.innerText = this.errorValue
|
||||
this.errorTarget.classList.remove('hidden')
|
||||
}
|
||||
}
|
||||
|
||||
uploadsValueChanged (uploads) {
|
||||
this.fieldsTarget.innerHTML = ''
|
||||
uploads.forEach((upload, index) => {
|
||||
const field = this.fieldsTemplate
|
||||
.replace(/__formName__/g, this.formNameValue)
|
||||
.replace(/__index__/g, index)
|
||||
.replace(/__fileId__/g, upload.fileId)
|
||||
.replace(/__originalFilename__/g, upload.originalFilename)
|
||||
.replace(/__filename__/g, upload.filename)
|
||||
.replace(/__mimeType__/g, upload.mimeType)
|
||||
.replace(/__size__/g, upload.size)
|
||||
this.fieldsTarget.insertAdjacentHTML('beforeend', field)
|
||||
})
|
||||
}
|
||||
|
||||
removeFile ({ params }) {
|
||||
const fileId = params.fileid
|
||||
this._removeFile(fileId)
|
||||
}
|
||||
|
||||
_removeFile(fileId) {
|
||||
this.uploadsValue = this.uploadsValue.filter(upload => {
|
||||
return upload.fileId !== fileId
|
||||
})
|
||||
}
|
||||
|
||||
removeUpload (event) {
|
||||
event.preventDefault()
|
||||
this.uploadTargets.forEach(element => {
|
||||
if (element.contains(event.target)) {
|
||||
element.remove()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
.btn {
|
||||
@apply inline-flex justify-center rounded-lg text-sm uppercase font-semibold py-2.5 px-4 bg-primary text-white hover:bg-primary/80 w-full;
|
||||
@apply inline-flex justify-center rounded-lg text-sm uppercase font-semibold py-2.5 px-4 bg-primary text-white hover:bg-primary/80 w-full shadow-md;
|
||||
}
|
||||
|
||||
.btn--secondary {
|
||||
@apply bg-secondary text-gray-800 hover:bg-secondary/80;
|
||||
}
|
||||
|
||||
.btn--active {
|
||||
@apply shadow-none;
|
||||
}
|
||||
Reference in New Issue
Block a user