diff --git a/assets/javascripts/discourse/components/custom-field-input.js.es6 b/assets/javascripts/discourse/components/custom-field-input.js.es6 index 5d2d6c3b..be3655ba 100644 --- a/assets/javascripts/discourse/components/custom-field-input.js.es6 +++ b/assets/javascripts/discourse/components/custom-field-input.js.es6 @@ -119,7 +119,12 @@ export default Component.extend({ } else { this.set("saveIcon", "times"); } - setTimeout(() => this.set("saveIcon", null), 10000); + setTimeout(() => { + if (this.isDestroyed) { + return; + }; + this.set("saveIcon", null); + }, 10000); }); }, }, diff --git a/assets/javascripts/discourse/components/custom-wizard-composer-editor.js b/assets/javascripts/discourse/components/custom-wizard-composer-editor.js index 096896cd..9a7af44f 100644 --- a/assets/javascripts/discourse/components/custom-wizard-composer-editor.js +++ b/assets/javascripts/discourse/components/custom-wizard-composer-editor.js @@ -33,6 +33,9 @@ export default class CustomWizardComposerEditor extends ComposerEditor { this.field.type )}-${dasherize(this.field.id)} .d-editor-input`; this.uppyComposerUpload.composerModel = this.composer; + if (!this.currentUser) { + this.currentUser = {}; + } } @discourseComputed diff --git a/assets/javascripts/discourse/components/custom-wizard-field-composer.js.es6 b/assets/javascripts/discourse/components/custom-wizard-field-composer.js.es6 index 20ce872c..383d3e2a 100644 --- a/assets/javascripts/discourse/components/custom-wizard-field-composer.js.es6 +++ b/assets/javascripts/discourse/components/custom-wizard-field-composer.js.es6 @@ -19,6 +19,7 @@ export default Component.extend({ EmberObject.create({ loading: false, reply: this.get("field.value") || "", + afterRefresh: () => {}, }) ); }, diff --git a/assets/javascripts/discourse/components/custom-wizard-textarea-editor.js b/assets/javascripts/discourse/components/custom-wizard-textarea-editor.js new file mode 100644 index 00000000..eea31f60 --- /dev/null +++ b/assets/javascripts/discourse/components/custom-wizard-textarea-editor.js @@ -0,0 +1,40 @@ +import TextareaEditor from "discourse/components/composer/textarea-editor"; + +export default class CustomWizardTextareaEditor extends TextareaEditor { + setupSmartList() { + // These must be bound manually because itsatrap does not support + // beforeinput or input events. + // + // beforeinput is better used to detect line breaks because it is + // fired before the actual value of the textarea is changed, + // and sometimes in the input event no `insertLineBreak` event type + // is fired. + // + // c.f. https://developer.mozilla.org/en-US/docs/Web/API/Element/beforeinput_event + if (this.currentUser?.user_option.enable_smart_lists) { + this.textarea.addEventListener( + "beforeinput", + this.onBeforeInputSmartList + ); + this.textarea.addEventListener( + "keydown", + this.onBeforeInputSmartListShiftDetect + ); + this.textarea.addEventListener("input", this.onInputSmartList); + } + } + + destroySmartList() { + if (this.currentUser?.user_option.enable_smart_lists) { + this.textarea.removeEventListener( + "beforeinput", + this.onBeforeInputSmartList + ); + this.textarea.removeEventListener( + "keydown", + this.onBeforeInputSmartListShiftDetect + ); + this.textarea.removeEventListener("input", this.onInputSmartList); + } + } +} \ No newline at end of file diff --git a/assets/javascripts/discourse/controllers/admin-wizards-custom-fields.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-custom-fields.js.es6 index 11e66782..f9e4f0d3 100644 --- a/assets/javascripts/discourse/controllers/admin-wizards-custom-fields.js.es6 +++ b/assets/javascripts/discourse/controllers/admin-wizards-custom-fields.js.es6 @@ -32,12 +32,16 @@ export default Controller.extend({ } setTimeout( - () => + () => { + if (this.isDestroyed) { + return; + } this.setProperties({ messageKey: "create", messageType: null, messageOpts: null, - }), + }); + }, 10000 ); diff --git a/assets/javascripts/discourse/controllers/admin-wizards-manager.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-manager.js.es6 index 65b8987a..7fe94804 100644 --- a/assets/javascripts/discourse/controllers/admin-wizards-manager.js.es6 +++ b/assets/javascripts/discourse/controllers/admin-wizards-manager.js.es6 @@ -26,6 +26,9 @@ export default Controller.extend({ messageItems: items, }); setTimeout(() => { + if (this.isDestroyed) { + return; + }; this.setProperties({ messageKey: "info", messageOpts: null, diff --git a/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 b/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 index 6885b89a..99ff2986 100644 --- a/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 +++ b/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 @@ -4,6 +4,7 @@ import getUrl from "discourse-common/lib/get-url"; import { observes } from "discourse-common/utils/decorators"; import { popupAjaxError } from "discourse/lib/ajax-error"; import { ajax } from "discourse/lib/ajax"; +import CustomWizardTextareaEditor from "../components/custom-wizard-textarea-editor"; export default { name: "custom-wizard-edits", @@ -39,20 +40,14 @@ export default { }, }); - api.modifyClass("component:uppy-image-uploader", { - pluginId: "custom-wizard", - // Needed to ensure appEvents get registered when navigating between steps - @observes("id") - initOnStepChange() { - if (/wizard-field|wizard-step/.test(this.id)) { - this._initialize(); - } - }, - }); - api.modifyClass("component:d-editor", { pluginId: "custom-wizard", + init() { + this._super(...arguments); + this.editorComponent = CustomWizardTextareaEditor; + }, + didInsertElement() { this._super(...arguments); diff --git a/test/javascripts/acceptance/admin-custom-fields-unsubscribed-test.js b/test/javascripts/acceptance/admin-custom-fields-unsubscribed-test.js index b3e7580c..b2d53023 100644 --- a/test/javascripts/acceptance/admin-custom-fields-unsubscribed-test.js +++ b/test/javascripts/acceptance/admin-custom-fields-unsubscribed-test.js @@ -5,7 +5,7 @@ import { visible, } from "discourse/tests/helpers/qunit-helpers"; import { test } from "qunit"; -import { click, fillIn, visit, waitUntil } from "@ember/test-helpers"; +import { click, fillIn, visit } from "@ember/test-helpers"; import selectKit from "discourse/tests/helpers/select-kit-helper"; import { getCustomFields, @@ -73,25 +73,6 @@ acceptance("Admin | Custom Fields Unsubscribed", function (needs) { ); } - async function waitForSaveMessage() { - // Wait for the "Saved custom field" message to appear - await waitUntil( - () => - document.querySelector(".message-content")?.innerText === - "Saved custom field", - { timeout: 5000 } - ); - - // Wait for the message to change back to the original text - await waitUntil( - () => - document.querySelector(".message-content")?.innerText === - "View, create, edit and destroy custom fields", - { timeout: 15000 } - ); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - test("Navigate to custom fields tab", async (assert) => { await visit("/admin/wizards/custom-fields"); assert.ok(query("table")); @@ -222,8 +203,6 @@ acceptance("Admin | Custom Fields Unsubscribed", function (needs) { ); await click(".actions .save"); - // Wait for the "Saved custom field" message to appear - await waitForSaveMessage(); assert.ok( query( ".admin-wizard-container tbody tr:first-child td:nth-child(1) label" @@ -253,8 +232,6 @@ acceptance("Admin | Custom Fields Unsubscribed", function (needs) { ); await click(".actions .save"); - // Wait for the "Saved custom field" message to appear - await waitForSaveMessage(); assert.ok( query( ".admin-wizard-container tbody tr:first-child td:nth-child(1) label" @@ -287,7 +264,6 @@ acceptance("Admin | Custom Fields Unsubscribed", function (needs) { "Filter by: Select a type" ); await click(".actions .save"); - await waitForSaveMessage(); await click(".admin-wizard-container tbody tr:first-child button"); await selectTypeAndSerializerAndFillInName( "Boolean", @@ -296,7 +272,6 @@ acceptance("Admin | Custom Fields Unsubscribed", function (needs) { "Filter by: String" ); await click(".admin-wizard-container tbody tr:first-child .save"); - await waitForSaveMessage(); assert.ok( query( ".admin-wizard-container tbody tr:first-child td:nth-child(1) label" @@ -348,7 +323,6 @@ acceptance("Admin | Custom Fields Unsubscribed", function (needs) { "Filter by: Select a type" ); await click(".actions .save"); - await waitForSaveMessage(); assert.ok( queryAll("table tbody tr").length === 5, "Display added custom fields" diff --git a/test/javascripts/acceptance/admin-manager-test.js b/test/javascripts/acceptance/admin-manager-test.js index a50c9820..a54990c6 100644 --- a/test/javascripts/acceptance/admin-manager-test.js +++ b/test/javascripts/acceptance/admin-manager-test.js @@ -1,13 +1,12 @@ import { acceptance, query } from "discourse/tests/helpers/qunit-helpers"; import { test } from "qunit"; -import { click, find, findAll, visit, waitUntil } from "@ember/test-helpers"; +import { click, find, findAll, visit } from "@ember/test-helpers"; import { getSuppliers, getUnsubscribedAdminWizards, getWizard, getWizardTestingLog, } from "../helpers/admin-wizard"; -import { Promise } from "rsvp"; acceptance("Admin | Manager", function (needs) { needs.user(); @@ -38,27 +37,6 @@ acceptance("Admin | Manager", function (needs) { return helper.response(getSuppliers); }); }); - async function waitForDestructionAndResetMessage() { - await waitUntil( - () => - document.querySelector(".message-content")?.innerText === - "Destruction complete", - { timeout: 5000 } - ); - - await waitUntil( - () => - document.querySelector(".message-content")?.innerText === - "Export, import or destroy wizards" && - !document.querySelector(".message-block.primary ul") && - !find(".message-block.primary svg").classList.contains( - "d-icon-check-circle" - ), - { timeout: 15000 } - ); - // Wait an additional second after the conditions are met - await new Promise((resolve) => setTimeout(resolve, 1000)); - } test("viewing manager fields content", async (assert) => { await visit("/admin/wizards/manager"); @@ -111,6 +89,5 @@ acceptance("Admin | Manager", function (needs) { find('table tr[data-wizard-id="this-is-testing-wizard"]'), "the wizard row is removed after destroy button is clicked" ); - await waitForDestructionAndResetMessage(); }); }); diff --git a/test/javascripts/acceptance/field-test.js b/test/javascripts/acceptance/field-test.js index 265100b1..8b9966c0 100644 --- a/test/javascripts/acceptance/field-test.js +++ b/test/javascripts/acceptance/field-test.js @@ -87,32 +87,6 @@ acceptance("Field | Fields", function (needs) { ); }); - 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( @@ -186,13 +160,6 @@ acceptance("Field | Fields", function (needs) { assert.ok(visible(".wizard-field.text-only-field label.field-label")); }); - test("Date", async function (assert) { - await visit("/w/wizard"); - assert.ok(visible(".wizard-field.date-field input.date-picker")); - await click(".wizard-field.date-field input.date-picker"); - assert.ok(visible(".wizard-field.date-field .pika-single")); - }); - test("Time", async function (assert) { await visit("/w/wizard"); assert.ok(visible(".wizard-field.time-field .d-time-input .select-kit")); @@ -202,23 +169,6 @@ acceptance("Field | Fields", function (needs) { assert.ok(visible(".wizard-field.time-field .select-kit-collection")); }); - test("Date Time", async function (assert) { - await visit("/w/wizard"); - assert.ok( - visible(".wizard-field.date-time-field .d-date-time-input .select-kit") - ); - await click( - ".wizard-field.date-time-field .d-date-input input.date-picker" - ); - assert.ok( - visible(".wizard-field.date-time-field .d-date-input .pika-single") - ); - await click( - ".wizard-field.date-time-field .d-time-input .select-kit .select-kit-header" - ); - assert.ok(visible(".wizard-field.date-time-field .select-kit-collection")); - }); - test("Number", async function (assert) { await visit("/w/wizard"); assert.ok(visible(".wizard-field.number-field input[type='number']")); @@ -234,14 +184,6 @@ acceptance("Field | Fields", function (needs) { assert.ok(visible(".wizard-field.url-field input[type='text']")); }); - test("Upload", async function (assert) { - await visit("/w/wizard"); - assert.ok( - visible(".wizard-field.upload-field label.wizard-btn-upload-file") - ); - assert.ok(exists(".wizard-field.upload-field input.hidden-upload-field")); - }); - test("Dropdown", async function (assert) { await visit("/w/wizard"); assert.ok(visible(".wizard-field.dropdown-field .single-select-header"));