diff --git a/assets/javascripts/discourse/components/custom-wizard-composer-editor.js.es6 b/assets/javascripts/discourse/components/custom-wizard-composer-editor.js.es6 index 95ae56c0..ea26cc67 100644 --- a/assets/javascripts/discourse/components/custom-wizard-composer-editor.js.es6 +++ b/assets/javascripts/discourse/components/custom-wizard-composer-editor.js.es6 @@ -18,6 +18,8 @@ import { inject as service } from "@ember/service"; const IMAGE_MARKDOWN_REGEX = /!\[(.*?)\|(\d{1,4}x\d{1,4})(,\s*\d{1,3}%)?(.*?)\]\((upload:\/\/.*?)\)(?!(.*`))/g; +export const wizardComposerEdtiorEventPrefix = "wizard-editor"; + export default ComposerEditor.extend({ modal: service(), @@ -33,7 +35,7 @@ export default ComposerEditor.extend({ draftStatus: "null", replyPlaceholder: alias("field.translatedPlaceholder"), wizardEventFieldId: null, - composerEventPrefix: "wizard-editor", + composerEventPrefix: wizardComposerEdtiorEventPrefix, @on("didInsertElement") _composerEditorInit() { diff --git a/assets/javascripts/discourse/components/custom-wizard-step.js.es6 b/assets/javascripts/discourse/components/custom-wizard-step.js.es6 index 44bef872..86ae1afa 100644 --- a/assets/javascripts/discourse/components/custom-wizard-step.js.es6 +++ b/assets/javascripts/discourse/components/custom-wizard-step.js.es6 @@ -7,8 +7,19 @@ import { cook } from "discourse/lib/text"; import CustomWizard, { updateCachedWizard, } from "discourse/plugins/discourse-custom-wizard/discourse/models/custom-wizard"; -import { alias, not } from "@ember/object/computed"; +import { alias, not, or } from "@ember/object/computed"; import discourseLater from "discourse-common/lib/later"; +import { wizardComposerEdtiorEventPrefix } from "./custom-wizard-composer-editor"; + +const uploadStartedEventKeys = ["upload-started"]; +const uploadEndedEventKeys = [ + "upload-success", + "upload-error", + "upload-cancelled", + "uploads-cancelled", + "uploads-aborted", + "all-uploads-complete", +]; export default Component.extend({ classNameBindings: [":wizard-step", "step.id"], @@ -28,6 +39,17 @@ export default Component.extend({ cook(this.step.translatedDescription).then((cookedDescription) => { this.set("cookedDescription", cookedDescription); }); + + uploadStartedEventKeys.forEach((key) => { + this.appEvents.on(`${wizardComposerEdtiorEventPrefix}:${key}`, () => { + this.set("uploading", true); + }); + }); + uploadEndedEventKeys.forEach((key) => { + this.appEvents.on(`${wizardComposerEdtiorEventPrefix}:${key}`, () => { + this.set("uploading", false); + }); + }); }, didInsertElement() { @@ -40,6 +62,7 @@ export default Component.extend({ showNextButton: not("step.final"), showDoneButton: alias("step.final"), + btnsDisabled: or("saving", "uploading"), @discourseComputed( "step.index", diff --git a/assets/javascripts/discourse/templates/components/custom-wizard-step.hbs b/assets/javascripts/discourse/templates/components/custom-wizard-step.hbs index b9f0c06e..fd4e038e 100644 --- a/assets/javascripts/discourse/templates/components/custom-wizard-step.hbs +++ b/assets/javascripts/discourse/templates/components/custom-wizard-step.hbs @@ -60,7 +60,7 @@ type="button" class="wizard-btn next primary" {{action "nextStep"}} - disabled={{saving}} + disabled={{btnsDisabled}} tabindex={{primaryButtonIndex}} > {{i18n "wizard.next"}} @@ -73,7 +73,7 @@ type="button" class="wizard-btn done" {{action "done"}} - disabled={{saving}} + disabled={{btnsDisabled}} tabindex={{primaryButtonIndex}} > {{i18n "wizard.done_custom"}} diff --git a/plugin.rb b/plugin.rb index 15723558..c9d647cf 100644 --- a/plugin.rb +++ b/plugin.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # name: discourse-custom-wizard # about: Forms for Discourse. Better onboarding, structured posting, data enrichment, automated actions and much more. -# version: 2.6.8 +# version: 2.6.9 # authors: Angus McLeod, Faizaan Gagan, Robert Barrow, Keegan George, Kaitlin Maddever, Juan Marcos Gutierrez Ramos # url: https://github.com/paviliondev/discourse-custom-wizard # contact_emails: development@pavilion.tech diff --git a/test/javascripts/acceptance/field-test.js b/test/javascripts/acceptance/field-test.js index 455d420d..fdf99da5 100644 --- a/test/javascripts/acceptance/field-test.js +++ b/test/javascripts/acceptance/field-test.js @@ -1,8 +1,16 @@ -import { click, fillIn, triggerKeyEvent, visit } from "@ember/test-helpers"; +import { getOwner } from "@ember/application"; +import { + click, + fillIn, + settled, + triggerKeyEvent, + visit, +} from "@ember/test-helpers"; import { test } from "qunit"; import { acceptance, count, + createFile, exists, query, visible, @@ -11,6 +19,8 @@ import { allFieldsWizard } from "../helpers/wizard"; import tagsJson from "../fixtures/tags"; import usersJson from "../fixtures/users"; +const wizardComposerEdtiorEventPrefix = "wizard-editor"; + acceptance("Field | Fields", function (needs) { needs.pretender((server, helper) => { server.get("/w/wizard.json", () => helper.response(allFieldsWizard)); @@ -18,6 +28,28 @@ acceptance("Field | Fields", function (needs) { helper.response({ results: tagsJson["tags"] }) ); server.get("/u/search/users", () => helper.response(usersJson)); + + server.post( + "/uploads.json", + () => { + return helper.response({ + extension: "jpeg", + filesize: 126177, + height: 800, + human_filesize: "123 KB", + id: 202, + original_filename: "avatar.PNG.jpg", + retain_hours: null, + short_path: "/uploads/short-url/yoj8pf9DdIeHRRULyw7i57GAYdz.jpeg", + short_url: "upload://yoj8pf9DdIeHRRULyw7i57GAYdz.jpeg", + thumbnail_height: 320, + thumbnail_width: 690, + url: "/images/discourse-logo-sketch-small.png", + width: 1920, + }); + }, + 500 // this delay is important to slow down the uploads a bit so we can let elements of the interface update + ); }); test("Text", async function (assert) { @@ -54,6 +86,33 @@ acceptance("Field | Fields", function (needs) { "Input in composer" ); }); + + test("Composer - Upload Disables Next Button", async function (assert) { + await visit("/w/wizard"); + const appEvents = getOwner(this).lookup("service:app-events"); + const done = assert.async(); + + appEvents.on( + `${wizardComposerEdtiorEventPrefix}:all-uploads-complete`, + async () => { + await settled(); + assert.ok(!exists(".wizard-btn.next.primary:disabled")); + done(); + } + ); + + appEvents.on( + `${wizardComposerEdtiorEventPrefix}:upload-started`, + async () => { + await settled(); + assert.ok(exists(".wizard-btn.next.primary:disabled")); + } + ); + + const image = createFile("avatar.png"); + appEvents.trigger(`${wizardComposerEdtiorEventPrefix}:add-files`, image); + }); + test("Composer - Hyperlink", async function (assert) { await visit("/w/wizard"); assert.ok(