diff --git a/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/models.gjs b/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/models.gjs index 485ce0f0378..2fe0bb61737 100644 --- a/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/models.gjs +++ b/app/assets/javascripts/admin/addon/components/schema-theme-setting/types/models.gjs @@ -29,9 +29,15 @@ export default class SchemaThemeSettingTypeModels extends Component { return; } + const isValueBlank = isBlank(this.value); + + if (!this.required && isValueBlank) { + return; + } + if ( (this.min && this.value.length < this.min) || - (this.required && isBlank(this.value)) + (this.required && isValueBlank) ) { return I18n.t( `admin.customize.theme.schema.fields.${this.type}.at_least`, diff --git a/app/assets/javascripts/discourse/tests/helpers/select-kit-helper.js b/app/assets/javascripts/discourse/tests/helpers/select-kit-helper.js index 5e08b918de9..43d97f88fe4 100644 --- a/app/assets/javascripts/discourse/tests/helpers/select-kit-helper.js +++ b/app/assets/javascripts/discourse/tests/helpers/select-kit-helper.js @@ -308,6 +308,12 @@ export default function selectKit(selector) { await click(`${selector} .selected-content [data-name="${name}"]`); }, + async deselectItemByIndex(index) { + await click( + queryAll(`${selector} .selected-content .selected-choice`)[index] + ); + }, + exists() { return exists(selector); }, 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 a33f2f824c6..163a87c9975 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 @@ -667,6 +667,81 @@ module( assert.strictEqual(enumSelector.header().value(), "nice"); }); + test("input fields of type categories that is not required with min and max validations", async function (assert) { + const setting = ThemeSettings.create({ + setting: "objects_setting", + objects_schema: { + name: "something", + properties: { + not_required_category: { + type: "categories", + validations: { + min: 2, + max: 3, + }, + }, + }, + }, + metadata: { + categories: { + 6: { + id: 6, + name: "some category", + }, + }, + }, + value: [{}], + }); + + await render(); + + const inputFields = new InputFieldsFromDOM(); + + assert + .dom(inputFields.fields.not_required_category.labelElement) + .hasText("not_required_category"); + + const categorySelector = selectKit( + `${inputFields.fields.not_required_category.selector} .select-kit` + ); + + assert.strictEqual(categorySelector.header().value(), null); + + await categorySelector.expand(); + await categorySelector.selectRowByIndex(1); + await categorySelector.collapse(); + + inputFields.refresh(); + + assert.dom(inputFields.fields.not_required_category.errorElement).hasText( + I18n.t("admin.customize.theme.schema.fields.categories.at_least", { + count: 2, + }) + ); + + await categorySelector.expand(); + await categorySelector.selectRowByIndex(2); + await categorySelector.selectRowByIndex(3); + await categorySelector.selectRowByIndex(4); + + assert + .dom(categorySelector.error()) + .hasText("You can only select 3 items."); + + await categorySelector.deselectItemByIndex(0); + await categorySelector.deselectItemByIndex(0); + await categorySelector.deselectItemByIndex(0); + await categorySelector.collapse(); + + inputFields.refresh(); + + assert + .dom(inputFields.fields.not_required_category.errorElement) + .doesNotExist(); + }); + test("input fields of type categories", async function (assert) { const setting = ThemeSettings.create({ setting: "objects_setting", @@ -678,13 +753,6 @@ module( type: "categories", required: true, }, - not_required_category: { - type: "categories", - validations: { - min: 2, - max: 3, - }, - }, }, }, metadata: { @@ -729,37 +797,6 @@ module( count: 1, }) ); - - assert - .dom(inputFields.fields.not_required_category.labelElement) - .hasText("not_required_category"); - - categorySelector = selectKit( - `${inputFields.fields.not_required_category.selector} .select-kit` - ); - - assert.strictEqual(categorySelector.header().value(), null); - - await categorySelector.expand(); - await categorySelector.selectRowByIndex(1); - await categorySelector.collapse(); - - inputFields.refresh(); - - assert.dom(inputFields.fields.not_required_category.errorElement).hasText( - I18n.t("admin.customize.theme.schema.fields.categories.at_least", { - count: 2, - }) - ); - - await categorySelector.expand(); - await categorySelector.selectRowByIndex(2); - await categorySelector.selectRowByIndex(3); - await categorySelector.selectRowByIndex(4); - - assert - .dom(categorySelector.error()) - .hasText("You can only select 3 items."); }); test("input fields of type tags which is required", async function (assert) {