diff --git a/common/common.scss b/common/common.scss index 01eca78..be9df25 100644 --- a/common/common.scss +++ b/common/common.scss @@ -22,7 +22,7 @@ div.d-wrap[data-wrap="placeholder"] { p, .discourse-placeholder-name { - font-size: $font-down-1; + font-size: var(--font-down-1); color: var(--primary-or-secondary); } @@ -41,7 +41,7 @@ div.d-wrap[data-wrap="placeholder"] { .discourse-placeholder-value { width: 350px; padding: 0.5em; - line-height: $line-height-small; + line-height: var(--line-height-small); color: var(--primary); background-color: var(--secondary); border: 1px solid var(--primary-medium); @@ -50,19 +50,17 @@ div.d-wrap[data-wrap="placeholder"] { .discourse-placeholder-select { width: 350px; margin: 0.5em 0; - line-height: $line-height-small; + line-height: var(--line-height-small); color: var(--primary); background-color: var(--secondary); border: 1px solid var(--primary-medium); } } -.discourse-placeholder-builder-modal { - .input { - input { - margin: 0; - width: 100%; - } +.placeholder-builder { + .input input { + margin: 0; + width: 100%; } .multi-select { diff --git a/javascripts/discourse/components/modal/discourse-placeholder-builder.hbs b/javascripts/discourse/components/modal/discourse-placeholder-builder.hbs new file mode 100644 index 0000000..eb7e30f --- /dev/null +++ b/javascripts/discourse/components/modal/discourse-placeholder-builder.hbs @@ -0,0 +1,64 @@ + + <:body> +
+ + {{theme-i18n "builder.key.label"}} + +
+ +
+

{{theme-i18n "builder.key.description"}}

+
+ +
+ + {{theme-i18n "builder.description.label"}} + +
+ +
+

+ {{theme-i18n "builder.description.description"}} +

+
+ +
+ + {{theme-i18n "builder.values.label"}} + +
+ +
+

{{theme-i18n "builder.values.description"}}

+
+ + + <:footer> + + +
\ No newline at end of file diff --git a/javascripts/discourse/components/modal/discourse-placeholder-builder.js b/javascripts/discourse/components/modal/discourse-placeholder-builder.js new file mode 100644 index 0000000..8b163d5 --- /dev/null +++ b/javascripts/discourse/components/modal/discourse-placeholder-builder.js @@ -0,0 +1,52 @@ +import Component from "@ember/component"; +import EmberObject, { action } from "@ember/object"; +import { isBlank } from "@ember/utils"; +import I18n from "I18n"; +import { inject as service } from "@ember/service"; + +export default class DiscoursePlaceholderBuilder extends Component { + @service dialog; + + form = EmberObject.create({ + key: null, + description: null, + values: [], + }); + + @action + updateKey(event) { + this.form.set("key", event.target.value); + } + + @action + updateDescription(event) { + this.form.set("description", event.target.value); + } + + @action + insertPlaceholder() { + if (isBlank(this.form.key)) { + this.dialog.alert(I18n.t(themePrefix("builder.errors.no_key"))); + return; + } + + let output = `[wrap=placeholder key="${this.form.key}"`; + + if (this.form.description) { + output += ` description="${this.form.description}"`; + } + + if (this.form.values.length) { + if (this.form.values.length === 1) { + output += ` default="${this.form.values.firstObject}"`; + } else { + output += ` defaults="${this.form.values.join(",")}"`; + } + } + + output += "][/wrap]"; + this.model.toolbarEvent.addText(output); + + this.closeModal(); + } +} diff --git a/javascripts/discourse/controllers/discourse-placeholder-builder.js b/javascripts/discourse/controllers/discourse-placeholder-builder.js deleted file mode 100644 index 9a76d6c..0000000 --- a/javascripts/discourse/controllers/discourse-placeholder-builder.js +++ /dev/null @@ -1,50 +0,0 @@ -import Controller from "@ember/controller"; -import ModalFunctionality from "discourse/mixins/modal-functionality"; -import EmberObject, { action } from "@ember/object"; -import { isBlank } from "@ember/utils"; -import I18n from "I18n"; -import { inject as service } from "@ember/service"; - -export default Controller.extend(ModalFunctionality, { - dialog: service(), - form: null, - - onShow() { - this.set( - "form", - EmberObject.create({ - key: null, - description: null, - values: [], - }) - ); - }, - - onClose() {}, - - @action - insertPlaceholder() { - if (isBlank(this.form.key)) { - this.dialog.alert(I18n.t(themePrefix("builder.errors.no_key"))); - return; - } - - let output = `[wrap=placeholder key="${this.form.key}"`; - - if (this.form.description) { - output = `${output} description="${this.form.description}"`; - } - - if (this.form.values.length) { - if (this.form.values.length === 1) { - output = `${output} default="${this.form.values.firstObject}"`; - } else { - output = `${output} defaults="${this.form.values.join(",")}"`; - } - } - - this.model.toolbarEvent.addText(`${output}][/wrap]`); - - this.send("closeModal"); - }, -}); diff --git a/javascripts/discourse/initializers/setup.js b/javascripts/discourse/initializers/setup.js index e8a2d80..69ed1ab 100644 --- a/javascripts/discourse/initializers/setup.js +++ b/javascripts/discourse/initializers/setup.js @@ -1,6 +1,6 @@ -import showModal from "discourse/lib/show-modal"; import { withPluginApi } from "discourse/lib/plugin-api"; import { debounce, later } from "@ember/runloop"; +import DiscoursePlaceholderBuilder from "../components/modal/discourse-placeholder-builder"; const VALID_TAGS = "h1, h2, h3, h4, h5, h6, p, code, blockquote, .md-table, li p"; @@ -296,7 +296,8 @@ export default { label: themePrefix("toolbar.builder"), icon: "file", action: (toolbarEvent) => { - showModal("discourse-placeholder-builder", { + const modal = container.lookup("service:modal"); + modal.show(DiscoursePlaceholderBuilder, { model: { toolbarEvent, }, diff --git a/javascripts/discourse/templates/modal/discourse-placeholder-builder.hbs b/javascripts/discourse/templates/modal/discourse-placeholder-builder.hbs deleted file mode 100644 index 453d483..0000000 --- a/javascripts/discourse/templates/modal/discourse-placeholder-builder.hbs +++ /dev/null @@ -1,60 +0,0 @@ -{{#d-modal-body - title=(theme-prefix "builder.title") - class="discourse-placeholder-builder" - style="overflow: auto" -}} -
-
- - {{theme-i18n "builder.key.label"}} - -
- {{input - value=(readonly form.key) - input=(action (mut form.key) value="target.value") - }} -
-

{{theme-i18n "builder.key.description"}}

-
- -
- - {{theme-i18n "builder.description.label"}} - -
- {{input - value=(readonly form.description) - input=(action (mut form.description) value="target.value") - }} -
-

- {{theme-i18n "builder.description.description"}} -

-
- -
- - {{theme-i18n "builder.values.label"}} - -
- {{multi-select - valueProperty=null - nameProperty=null - value=form.values - content=form.values - options=(hash allowAny=true placementStrategy="absolute") - onChange=(action (mut form.values)) - }} -
-

{{theme-i18n "builder.values.description"}}

-
-
-{{/d-modal-body}} - - \ No newline at end of file diff --git a/test/javascripts/acceptance/add-placeholder-test.js b/test/javascripts/acceptance/add-placeholder-test.js new file mode 100644 index 0000000..0c33cd7 --- /dev/null +++ b/test/javascripts/acceptance/add-placeholder-test.js @@ -0,0 +1,52 @@ +import { click, fillIn, visit } from "@ember/test-helpers"; +import { test } from "qunit"; +import { acceptance } from "discourse/tests/helpers/qunit-helpers"; +import selectKit from "discourse/tests/helpers/select-kit-helper"; +import I18n from "I18n"; + +acceptance("Discourse Placeholder | Add a placeholder", function (needs) { + needs.user(); + + test("add a placeholder through the modal", async function (assert) { + await visit("/"); + await click("#create-topic"); + const categoryChooser = selectKit(".category-chooser"); + await categoryChooser.expand(); + await categoryChooser.selectRowByValue(2); + + await click(".d-editor-button-bar .options"); + await selectKit(".toolbar-popup-menu-options").expand(); + const buttonSelector = `.select-kit-row[data-name='${I18n.t( + themePrefix("toolbar.builder") + )}']`; + assert.dom(buttonSelector).exists("it shows the composer button"); + await click(buttonSelector); + + assert.dom(".d-modal.placeholder-builder").exists(); + + await click(".d-modal .btn-primary"); + assert + .dom(".dialog-body") + .hasText(I18n.t(themePrefix("builder.errors.no_key"))); + await click(".dialog-footer .btn-primary"); + + await fillIn(".placeholder-builder__key", "password"); + await fillIn(".placeholder-builder__description", "A secret password"); + + const dropdown = selectKit(".placeholder-builder__default-values"); + await dropdown.expand(); + await dropdown.fillInFilter("one"); + await dropdown.keyboard("Enter"); + await dropdown.fillInFilter("two"); + await dropdown.keyboard("Enter"); + + await click(".d-modal .btn-primary"); + assert.dom(".d-modal.placeholder-builder").doesNotExist(); + + assert + .dom("textarea.d-editor-input") + .hasValue( + `[wrap=placeholder key="password" description="A secret password" defaults="one,two"][/wrap]` + ); + }); +});