DEV: Change create-invite-uploader to use uppy (#15088)

Part of overall strategy to remove jQuery file uploader
from the codebase. Also added some helper functionality to
the uppy mixin to allow for non-autostart uploads (all
previous upload changes have been for auto start components.)
This commit is contained in:
Martin Brennan 2021-12-01 09:45:05 +10:00 committed by GitHub
parent dce6c6fb50
commit d64323b4e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 105 deletions

View File

@ -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();
},
});

View File

@ -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 = "";
},

View File

@ -1,5 +1,6 @@
{{yield (hash data=data
uploading=uploading
progress=progress
uploadProgress=uploadProgress
uploaded=uploaded
submitDisabled=submitDisabled)}}
submitDisabled=submitDisabled
startUpload=(action "startUpload"))}}

View File

@ -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}}