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"
-}}
-
-{{/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]`
+ );
+ });
+});