diff --git a/app/assets/javascripts/admin/addon/components/schema-theme-setting/editor.gjs b/app/assets/javascripts/admin/addon/components/schema-theme-setting/editor.gjs
index 38d98d1e08f..f1b9b9bfcc7 100644
--- a/app/assets/javascripts/admin/addon/components/schema-theme-setting/editor.gjs
+++ b/app/assets/javascripts/admin/addon/components/schema-theme-setting/editor.gjs
@@ -96,7 +96,7 @@ export default class SchemaThemeSettingEditor extends Component {
}
list.push({
name,
- type: spec.type,
+ spec,
value: node.object[name],
});
}
@@ -194,8 +194,8 @@ export default class SchemaThemeSettingEditor extends Component {
{{#each this.fields as |field|}}
{{/each}}
diff --git a/app/assets/javascripts/admin/addon/components/schema-theme-setting/field.gjs b/app/assets/javascripts/admin/addon/components/schema-theme-setting/field.gjs
index e033f99cadf..e7702ae00bc 100644
--- a/app/assets/javascripts/admin/addon/components/schema-theme-setting/field.gjs
+++ b/app/assets/javascripts/admin/addon/components/schema-theme-setting/field.gjs
@@ -1,29 +1,34 @@
import Component from "@glimmer/component";
-import { Input } from "@ember/component";
+import BooleanField from "./types/boolean";
+import EnumField from "./types/enum";
+import IntegerField from "./types/integer";
+import StringField from "./types/string";
export default class SchemaThemeSettingField extends Component {
- #bufferVal;
-
get component() {
- if (this.args.type === "string") {
- return Input;
+ switch (this.args.spec.type) {
+ case "string":
+ return StringField;
+ case "integer":
+ return IntegerField;
+ case "boolean":
+ return BooleanField;
+ case "enum":
+ return EnumField;
+ default:
+ throw new Error("unknown type");
}
}
- get value() {
- return this.#bufferVal || this.args.value;
- }
-
- set value(v) {
- this.#bufferVal = v;
- this.args.onValueChange(v);
- }
-
diff --git a/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/boolean.gjs b/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/boolean.gjs
new file mode 100644
index 00000000000..21d10b58557
--- /dev/null
+++ b/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/boolean.gjs
@@ -0,0 +1,15 @@
+import Component from "@glimmer/component";
+import { Input } from "@ember/component";
+import { on } from "@ember/modifier";
+import { action } from "@ember/object";
+
+export default class SchemaThemeSettingTypeBoolean extends Component {
+ @action
+ onInput(event) {
+ this.args.onChange(event.currentTarget.checked);
+ }
+
+
+
+
+}
diff --git a/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/enum.gjs b/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/enum.gjs
new file mode 100644
index 00000000000..077064ca4fe
--- /dev/null
+++ b/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/enum.gjs
@@ -0,0 +1,36 @@
+import Component from "@glimmer/component";
+import { tracked } from "@glimmer/tracking";
+import { action } from "@ember/object";
+import ComboBox from "select-kit/components/combo-box";
+
+export default class SchemaThemeSettingTypeEnum extends Component {
+ @tracked value;
+
+ constructor() {
+ super(...arguments);
+ this.value = this.args.value;
+ }
+
+ get content() {
+ return this.args.spec.choices.map((choice) => {
+ return {
+ name: choice,
+ id: choice,
+ };
+ });
+ }
+
+ @action
+ onInput(newVal) {
+ this.value = newVal;
+ this.args.onChange(newVal);
+ }
+
+
+
+
+}
diff --git a/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/integer.gjs b/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/integer.gjs
new file mode 100644
index 00000000000..761bb10114d
--- /dev/null
+++ b/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/integer.gjs
@@ -0,0 +1,15 @@
+import Component from "@glimmer/component";
+import { Input } from "@ember/component";
+import { on } from "@ember/modifier";
+import { action } from "@ember/object";
+
+export default class SchemaThemeSettingTypeInteger extends Component {
+ @action
+ onInput(event) {
+ this.args.onChange(event.currentTarget.value);
+ }
+
+
+
+
+}
diff --git a/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/string.gjs b/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/string.gjs
new file mode 100644
index 00000000000..0b427c6b063
--- /dev/null
+++ b/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/string.gjs
@@ -0,0 +1,15 @@
+import Component from "@glimmer/component";
+import { Input } from "@ember/component";
+import { on } from "@ember/modifier";
+import { action } from "@ember/object";
+
+export default class SchemaThemeSettingTypeString extends Component {
+ @action
+ onInput(event) {
+ this.args.onChange(event.currentTarget.value);
+ }
+
+
+
+
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-schema.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-schema.js
index 1c6098693a5..878a8b69360 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-schema.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-schema.js
@@ -4,6 +4,9 @@ export default class AdminCustomizeThemesSchemaController extends Controller {
data = [
{
name: "item 1",
+ width: 143,
+ is_valid: true,
+ enum_prop: 11,
children: [
{
name: "child 1-1",
@@ -25,6 +28,9 @@ export default class AdminCustomizeThemesSchemaController extends Controller {
},
{
name: "item 2",
+ width: 803,
+ is_valid: false,
+ enum_prop: 22,
children: [
{
name: "child 2-1",
@@ -53,6 +59,16 @@ export default class AdminCustomizeThemesSchemaController extends Controller {
name: {
type: "string",
},
+ width: {
+ type: "integer",
+ },
+ is_valid: {
+ type: "boolean",
+ },
+ enum_prop: {
+ type: "enum",
+ choices: [11, 22],
+ },
children: {
type: "objects",
schema: {
diff --git a/app/assets/javascripts/discourse/tests/fixtures/theme-setting-schema-data.js b/app/assets/javascripts/discourse/tests/fixtures/theme-setting-schema-data.js
index 7add942a8ef..a445c838c19 100644
--- a/app/assets/javascripts/discourse/tests/fixtures/theme-setting-schema-data.js
+++ b/app/assets/javascripts/discourse/tests/fixtures/theme-setting-schema-data.js
@@ -159,6 +159,40 @@ export default function schemaAndData(version = 1) {
],
},
];
+ } else if (version === 3) {
+ schema = {
+ name: "something",
+ identifier: "name",
+ properties: {
+ name: {
+ type: "string",
+ },
+ integer_field: {
+ type: "integer",
+ },
+ boolean_field: {
+ type: "boolean",
+ },
+ enum_field: {
+ type: "enum",
+ choices: ["nice", "awesome", "cool"]
+ }
+ },
+ };
+ data = [
+ {
+ name: "lamb",
+ integer_field: 92,
+ boolean_field: true,
+ enum_field: "awesome"
+ },
+ {
+ name: "cow",
+ integer_field: 820,
+ boolean_field: false,
+ enum_field: "cool"
+ },
+ ];
} else {
throw new Error("unknown fixture version");
}
diff --git a/app/assets/javascripts/discourse/tests/integration/components/admin-schema-theme-setting/editor-test.gjs b/app/assets/javascripts/discourse/tests/integration/components/admin-schema-theme-setting/editor-test.gjs
index fbe35dacbd4..d11243cb73f 100644
--- a/app/assets/javascripts/discourse/tests/integration/components/admin-schema-theme-setting/editor-test.gjs
+++ b/app/assets/javascripts/discourse/tests/integration/components/admin-schema-theme-setting/editor-test.gjs
@@ -3,6 +3,7 @@ import { module, test } from "qunit";
import schemaAndData from "discourse/tests/fixtures/theme-setting-schema-data";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { queryAll } from "discourse/tests/helpers/qunit-helpers";
+import selectKit from "discourse/tests/helpers/select-kit-helper";
import I18n from "discourse-i18n";
import AdminSchemaThemeSettingEditor from "admin/components/schema-theme-setting/editor";
@@ -47,6 +48,7 @@ class InputFieldsFromDOM {
this.fields[field.dataset.name] = {
labelElement: field.querySelector("label"),
inputElement: field.querySelector(".input").children[0],
+ selector: `.schema-field[data-name="${field.dataset.name}"]`,
};
});
}
@@ -329,6 +331,93 @@ module(
assert.dom(inputFields.fields.icon.inputElement).hasValue("asterisk");
});
+ test("input fields of type integer", async function (assert) {
+ const [schema, data] = schemaAndData(3);
+ await render(
+
+ );
+
+ const inputFields = new InputFieldsFromDOM();
+ assert
+ .dom(inputFields.fields.integer_field.labelElement)
+ .hasText("integer_field");
+ assert.dom(inputFields.fields.integer_field.inputElement).hasValue("92");
+ assert
+ .dom(inputFields.fields.integer_field.inputElement)
+ .hasAttribute("type", "number");
+ await fillIn(inputFields.fields.integer_field.inputElement, "922229");
+
+ const tree = new TreeFromDOM();
+ await click(tree.nodes[1].element);
+
+ inputFields.refresh();
+
+ assert.dom(inputFields.fields.integer_field.inputElement).hasValue("820");
+
+ tree.refresh();
+ await click(tree.nodes[0].element);
+ inputFields.refresh();
+
+ assert
+ .dom(inputFields.fields.integer_field.inputElement)
+ .hasValue("922229");
+ });
+
+ test("input fields of type boolean", async function (assert) {
+ const [schema, data] = schemaAndData(3);
+ await render(
+
+ );
+
+ const inputFields = new InputFieldsFromDOM();
+ assert
+ .dom(inputFields.fields.boolean_field.labelElement)
+ .hasText("boolean_field");
+ assert.dom(inputFields.fields.boolean_field.inputElement).isChecked();
+ await click(inputFields.fields.boolean_field.inputElement);
+
+ const tree = new TreeFromDOM();
+ await click(tree.nodes[1].element);
+
+ inputFields.refresh();
+ assert
+ .dom(inputFields.fields.boolean_field.labelElement)
+ .hasText("boolean_field");
+ assert.dom(inputFields.fields.boolean_field.inputElement).isNotChecked();
+
+ tree.refresh();
+ await click(tree.nodes[0].element);
+ inputFields.refresh();
+
+ assert.dom(inputFields.fields.boolean_field.inputElement).isNotChecked();
+ });
+
+ test("input fields of type enum", async function (assert) {
+ const [schema, data] = schemaAndData(3);
+ await render(
+
+ );
+
+ const inputFields = new InputFieldsFromDOM();
+ const enumSelector = selectKit(
+ `${inputFields.fields.enum_field.selector} .select-kit`
+ );
+ assert.strictEqual(enumSelector.header().value(), "awesome");
+
+ await enumSelector.expand();
+ await enumSelector.selectRowByValue("nice");
+ assert.strictEqual(enumSelector.header().value(), "nice");
+
+ const tree = new TreeFromDOM();
+ await click(tree.nodes[1].element);
+ assert.strictEqual(enumSelector.header().value(), "cool");
+
+ tree.refresh();
+
+ await click(tree.nodes[0].element);
+ assert.strictEqual(enumSelector.header().value(), "nice");
+ });
+
test("identifier field instantly updates in the navigation tree when the input field is changed", async function (assert) {
const [schema, data] = schemaAndData(2);
await render(