diff --git a/app/assets/javascripts/discourse/app/components/form-template-field/upload.gjs b/app/assets/javascripts/discourse/app/components/form-template-field/upload.gjs index 9e6505a4e00..140f0ae976a 100644 --- a/app/assets/javascripts/discourse/app/components/form-template-field/upload.gjs +++ b/app/assets/javascripts/discourse/app/components/form-template-field/upload.gjs @@ -12,38 +12,51 @@ export default class FormTemplateFieldUpload extends Component.extend( UppyUploadMixin ) { @tracked uploadValue; - @tracked uploadComplete = false; @tracked uploadedFiles = []; - @tracked disabled = this.uploading; + @tracked disabled = this.uploadingOrProcessing; @tracked fileUploadElementId = `${dasherize(this.id)}-uploader`; @tracked fileInputSelector = `#${this.fileUploadElementId}`; type = "composer"; - @computed("uploading", "uploadValue") + @computed("uploadingOrProcessing") get uploadStatusLabel() { - if (!this.uploading && !this.uploadValue) { - return "form_templates.upload_field.upload"; - } + return this.uploadingOrProcessing + ? "form_templates.upload_field.uploading" + : "form_templates.upload_field.upload"; + } - if (!this.uploading && this.uploadValue) { - this.uploadComplete = true; - return "form_templates.upload_field.upload"; - } + /** + * The validation from PickFilesButton._filesPicked, where acceptedFormatsOverride + * is validated and displays a message, happens after the upload is complete. + * + * Overriding this method allows us to validate the file before the upload + * + * @param file + * @returns {boolean} + */ + isUploadedFileAllowed(file) { + // same logic from PickFilesButton._hasAcceptedExtensionOrType + const fileTypes = this.attributes.file_types; + const extension = file.name.split(".").pop(); - return "form_templates.upload_field.uploading"; + return ( + !fileTypes || + fileTypes.includes(`.${extension}`) || + fileTypes.includes(file.type) + ); } uploadDone(upload) { // If re-uploading, clear the existing file if multiple aren't allowed - if (!this.attributes.allow_multiple && this.uploadComplete) { + if (!this.attributes.allow_multiple && this.uploadValue) { this.uploadedFiles = []; this.uploadValue = ""; } - const uploadMarkdown = this.buildMarkdown(upload); this.uploadedFiles.pushObject(upload); + const uploadMarkdown = this.buildMarkdown(upload); if (this.uploadValue && this.allowMultipleFiles) { // multiple file upload this.uploadValue = `${this.uploadValue}\n${uploadMarkdown}`; diff --git a/app/assets/javascripts/discourse/app/mixins/uppy-upload.js b/app/assets/javascripts/discourse/app/mixins/uppy-upload.js index a53399a7375..c782851c510 100644 --- a/app/assets/javascripts/discourse/app/mixins/uppy-upload.js +++ b/app/assets/javascripts/discourse/app/mixins/uppy-upload.js @@ -47,6 +47,17 @@ export default Mixin.create(UppyS3Multipart, ExtendableUploader, { return {}; }, + /** + * Overridable for custom file validations, executed before uploading. + * + * @param {object} file + * + * @returns {boolean} + */ + isUploadedFileAllowed() { + return true; + }, + uploadingOrProcessing: or("uploading", "processing"), @on("willDestroyElement") @@ -112,7 +123,9 @@ export default Mixin.create(UppyS3Multipart, ExtendableUploader, { }, this.validateUploadedFilesOptions() ); - const isValid = validateUploadedFile(currentFile, validationOpts); + const isValid = + validateUploadedFile(currentFile, validationOpts) && + this.isUploadedFileAllowed(currentFile); this.setProperties({ uploadProgress: 0, uploading: isValid && this.autoStartUploads, diff --git a/spec/system/composer/category_templates_spec.rb b/spec/system/composer/category_templates_spec.rb index af045552520..032909b6b05 100644 --- a/spec/system/composer/category_templates_spec.rb +++ b/spec/system/composer/category_templates_spec.rb @@ -370,6 +370,7 @@ describe "Composer Form Templates", type: :system do expect(find("#dialog-holder .dialog-body p", visible: :all)).to have_content( I18n.t("js.pick_files_button.unsupported_file_picked", { types: ".jpg, .png" }), ) + expect(page).to have_no_css(".form-template-field__uploaded-files") end it "creates a post with multiple uploads" do @@ -401,6 +402,22 @@ describe "Composer Form Templates", type: :system do ) end + it "overrides uploaded file if allow_multiple false" do + topic_title = "Peter Parker's Medication" + + category_page.visit(category_with_upload_template) + category_page.new_topic_button.click + attach_file "prescription-uploader", + "#{Rails.root}/spec/fixtures/images/logo.png", + make_visible: true + composer.fill_title(topic_title) + attach_file "prescription-uploader", + "#{Rails.root}/spec/fixtures/images/fake.jpg", + make_visible: true + + expect(find(".form-template-field__uploaded-files")).to have_css("li", count: 1) + end + it "shows labels and descriptions when a form template is assigned to the category" do category_page.visit(category_with_template_6) category_page.new_topic_button.click