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() } }) } }