diff --git a/app/assets/javascripts/discourse/app/components/create-invite-uploader.js b/app/assets/javascripts/discourse/app/components/create-invite-uploader.js index c98064d6be..17d29e01d4 100644 --- a/app/assets/javascripts/discourse/app/components/create-invite-uploader.js +++ b/app/assets/javascripts/discourse/app/components/create-invite-uploader.js @@ -1,111 +1,32 @@ import Component from "@ember/component"; -import getUrl from "discourse-common/lib/get-url"; +import { action } from "@ember/object"; +import UppyUploadMixin from "discourse/mixins/uppy-upload"; import discourseComputed from "discourse-common/utils/decorators"; -import { - displayErrorForUpload, - validateUploadedFiles, -} from "discourse/lib/uploads"; -export default Component.extend({ - tagName: "", +export default Component.extend(UppyUploadMixin, { + id: "create-invite-uploader", + tagName: "div", + type: "csv", + autoStartUploads: false, + uploadUrl: "/invites/upload_csv", + preventDirectS3Uploads: true, + fileInputSelector: "#csv-file", - data: null, - uploading: false, - progress: 0, - uploaded: null, - - @discourseComputed("messageBus.clientId") - clientId() { - return this.messageBus && this.messageBus.clientId; + validateUploadedFilesOptions() { + return { bypassNewUserRestriction: true, csvOnly: true }; }, - @discourseComputed("data", "uploading") - submitDisabled(data, uploading) { - return !data || uploading; + @discourseComputed("filesAwaitingUpload", "uploading") + submitDisabled(filesAwaitingUpload, uploading) { + return !filesAwaitingUpload || uploading; }, - didInsertElement() { - this._super(...arguments); - - this.setProperties({ - data: null, - uploading: false, - progress: 0, - uploaded: null, - }); - - const $upload = $("#csv-file"); - - $upload.fileupload({ - url: getUrl("/invites/upload_csv.json") + "?client_id=" + this.clientId, - dataType: "json", - dropZone: null, - replaceFileInput: false, - autoUpload: false, - }); - - $upload.on("fileuploadadd", (e, data) => { - this.set("data", data); - }); - - $upload.on("fileuploadsubmit", (e, data) => { - const isValid = validateUploadedFiles(data.files, { - user: this.currentUser, - siteSettings: this.siteSettings, - bypassNewUserRestriction: true, - csvOnly: true, - }); - - data.formData = { type: "csv" }; - this.setProperties({ progress: 0, uploading: isValid }); - - return isValid; - }); - - $upload.on("fileuploadprogress", (e, data) => { - const progress = parseInt((data.loaded / data.total) * 100, 10); - this.set("progress", progress); - }); - - $upload.on("fileuploaddone", (e, data) => { - const upload = data.result; - this.set("uploaded", upload); - this.reset(); - }); - - $upload.on("fileuploadfail", (e, data) => { - if (data.errorThrown !== "abort") { - displayErrorForUpload(data, this.siteSettings, data.files[0].name); - } - this.reset(); - }); + uploadDone() { + this.set("uploaded", true); }, - willDestroyElement() { - this._super(...arguments); - - if (this.messageBus) { - this.messageBus.unsubscribe("/uploads/csv"); - } - - const $upload = $(this.element); - - try { - $upload.fileupload("destroy"); - } catch (e) { - /* wasn't initialized yet */ - } finally { - $upload.off(); - } - }, - - reset() { - this.setProperties({ - data: null, - uploading: false, - progress: 0, - }); - - document.getElementById("csv-file").value = ""; + @action + startUpload() { + this._startUpload(); }, }); diff --git a/app/assets/javascripts/discourse/app/mixins/uppy-upload.js b/app/assets/javascripts/discourse/app/mixins/uppy-upload.js index 05c145d645..84ca638dfb 100644 --- a/app/assets/javascripts/discourse/app/mixins/uppy-upload.js +++ b/app/assets/javascripts/discourse/app/mixins/uppy-upload.js @@ -30,6 +30,7 @@ export default Mixin.create(UppyS3Multipart, { inProgressUploads: null, id: null, uploadRootPath: "/uploads", + fileInputSelector: ".hidden-upload-field", uploadDone() { warn("You should implement `uploadDone`", { @@ -57,7 +58,7 @@ export default Mixin.create(UppyS3Multipart, { @on("didInsertElement") _initialize() { this.setProperties({ - fileInputEl: this.element.querySelector(".hidden-upload-field"), + fileInputEl: this.element.querySelector(this.fileInputSelector), }); this.set("allowMultipleFiles", this.fileInputEl.multiple); this.set("inProgressUploads", []); @@ -96,7 +97,11 @@ export default Mixin.create(UppyS3Multipart, { this.validateUploadedFilesOptions() ); const isValid = validateUploadedFile(currentFile, validationOpts); - this.setProperties({ uploadProgress: 0, uploading: isValid }); + this.setProperties({ + uploadProgress: 0, + uploading: isValid && this.autoStartUploads, + filesAwaitingUpload: !this.autoStartUploads, + }); return isValid; }, @@ -221,6 +226,16 @@ export default Mixin.create(UppyS3Multipart, { } }, + _startUpload() { + if (!this.filesAwaitingUpload) { + return; + } + if (!this._uppyInstance?.getFiles().length) { + return; + } + return this._uppyInstance?.upload(); + }, + _useXHRUploads() { this._uppyInstance.use(XHRUpload, { endpoint: this._xhrUploadUrl(), @@ -327,6 +342,7 @@ export default Mixin.create(UppyS3Multipart, { uploading: false, processing: false, uploadProgress: 0, + filesAwaitingUpload: false, }); this.fileInputEl.value = ""; }, diff --git a/app/assets/javascripts/discourse/app/templates/components/create-invite-uploader.hbs b/app/assets/javascripts/discourse/app/templates/components/create-invite-uploader.hbs index acc33b06b8..b6119e5869 100644 --- a/app/assets/javascripts/discourse/app/templates/components/create-invite-uploader.hbs +++ b/app/assets/javascripts/discourse/app/templates/components/create-invite-uploader.hbs @@ -1,5 +1,6 @@ {{yield (hash data=data uploading=uploading - progress=progress + uploadProgress=uploadProgress uploaded=uploaded - submitDisabled=submitDisabled)}} + submitDisabled=submitDisabled + startUpload=(action "startUpload"))}} diff --git a/app/assets/javascripts/discourse/app/templates/modal/create-invite-bulk.hbs b/app/assets/javascripts/discourse/app/templates/modal/create-invite-bulk.hbs index 3973a3912e..de9fae0437 100644 --- a/app/assets/javascripts/discourse/app/templates/modal/create-invite-bulk.hbs +++ b/app/assets/javascripts/discourse/app/templates/modal/create-invite-bulk.hbs @@ -13,10 +13,10 @@ {{#unless status.uploaded}} {{d-button icon=(if isEmail "envelope" "link") - translatedLabel=(if status.uploading (i18n "user.invited.bulk_invite.progress" progress=status.progress) + translatedLabel=(if status.uploading (i18n "user.invited.bulk_invite.progress" progress=status.uploadProgress) (i18n "user.invited.bulk_invite.text")) class="btn-primary" - action=(action "submit" status.data) + action=status.startUpload disabled=status.submitDisabled }} {{/unless}}