FEATURE: predefined simple list for admin setting (#23953)

Some admin settings are multiple list with predefined values. In that case, we should not allow to input any value which later will fail validation.
This commit is contained in:
Krzysztof Kotlarek 2023-10-18 11:25:32 +11:00 committed by GitHub
parent bf97899029
commit 4773f5d720
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 66 additions and 19 deletions

View File

@ -33,20 +33,33 @@
{{/if}}
<div class="simple-list-input">
<Input
@type="text"
@value={{this.newValue}}
placeholder={{i18n "admin.site_settings.simple_list.add_item"}}
class="add-value-input"
autocomplete="off"
autocorrect="off"
autocapitalize="off"
/>
<DButton
@action={{fn this.addValue this.newValue}}
@disabled={{this.inputEmpty}}
@icon="plus"
class="add-value-btn btn-small"
/>
{{#if this.isPredefinedList}}
{{#if (gt this.validValues.length 0)}}
<ComboBox
@content={{this.validValues}}
@value={{this.newValue}}
@onChange={{action this.addValue}}
@valueProperty={{this.setting.computedValueProperty}}
@nameProperty={{this.setting.computedNameProperty}}
@options={{hash castInteger=true allowAny=false}}
class="add-value-input"
/>
{{/if}}
{{else}}
<Input
@type="text"
@value={{this.newValue}}
placeholder={{i18n "admin.site_settings.simple_list.add_item"}}
class="add-value-input"
autocomplete="off"
autocorrect="off"
autocapitalize="off"
/>
<DButton
@action={{fn this.addValue this.newValue}}
@disabled={{this.inputEmpty}}
@icon="plus"
class="add-value-btn btn-small"
/>
{{/if}}
</div>

View File

@ -1,6 +1,7 @@
import Component from "@ember/component";
import { action } from "@ember/object";
import { empty } from "@ember/object/computed";
import { isEmpty } from "@ember/utils";
import { classNameBindings } from "@ember-decorators/component";
import { on } from "@ember-decorators/object";
import discourseComputed from "discourse-common/utils/decorators";
@ -13,10 +14,13 @@ export default class SimpleList extends Component {
newValue = "";
collection = null;
values = null;
choices = null;
allowAny = false;
@on("didReceiveAttrs")
_setupCollection() {
this.set("collection", this._splitValues(this.values, this.inputDelimiter));
this.set("isPredefinedList", !this.allowAny && !isEmpty(this.choices));
}
keyDown(event) {
@ -35,7 +39,7 @@ export default class SimpleList extends Component {
@action
addValue(newValue) {
if (this.inputEmpty) {
if (!newValue) {
return;
}
@ -71,6 +75,11 @@ export default class SimpleList extends Component {
this.onChange?.(this.collection);
}
@discourseComputed("choices", "values")
validValues(choices, values) {
return choices.filter((name) => !values.includes(name));
}
@discourseComputed("collection")
showUpDownButtons(collection) {
return collection.length - 1 ? true : false;

View File

@ -2,6 +2,8 @@
@values={{this.value}}
@inputDelimiter={{this.inputDelimiter}}
@onChange={{action "onChange"}}
@choices={{this.setting.choices}}
@allowAny={{this.setting.allow_any}}
/>
<SettingValidationMessage @message={{this.validationMessage}} />
<div class="desc">{{html-safe this.setting.description}}</div>

View File

@ -48,6 +48,25 @@ module("Integration | Component | simple-list", function (hooks) {
);
});
test("adding a value when list is predefined", async function (assert) {
this.set("values", "vinkas\nosama");
this.set("choices", ["vinkas", "osama", "kris"]);
await render(
hbs`<SimpleList @values={{this.values}} @allowAny={{false}} @choices={{this.choices}}/>`
);
await click(".add-value-input summary");
assert.strictEqual(count(".select-kit-row"), 1);
await click(".select-kit-row");
assert.strictEqual(
count(".values .value"),
3,
"it adds the value to the list of values"
);
});
test("changing a value", async function (assert) {
const done = assert.async();

View File

@ -1691,8 +1691,8 @@ en:
invalidate_inactive_admin_email_after_days: "Admin accounts that have not visited the site in this number of days will need to re-validate their email address before logging in. Set to 0 to disable."
include_secure_categories_in_tag_counts: "When enabled, count of topics for a tag will include topics that are in read restricted categories for all users. When disabled, normal users are only shown a count of topics for a tag where all the topics are in public categories."
display_personal_messages_tag_counts: "When enabled, count of personal messages tagged with a given tag will be displayed."
top_menu: "Determine which items appear in the homepage navigation, and in what order. Example latest|new|unread|categories|top|read|posted|bookmarks"
post_menu: "Determine which items appear on the post menu, and in what order. Example like|edit|flag|delete|share|bookmark|reply"
top_menu: "Determine which items appear in the homepage navigation, and in what order."
post_menu: "Determine which items appear on the post menu, and in what order."
post_menu_hidden_items: "The menu items to hide by default in the post menu unless an expansion ellipsis is clicked on."
share_links: "Determine which items appear on the share dialog, and in what order."
allow_username_in_share_links: "Allow usernames to be included in share links. This is useful to reward badges based on unique visitors."

View File

@ -192,6 +192,7 @@ basic:
post_menu:
client: true
type: list
list_type: simple
default: "read|like|share|flag|edit|bookmark|delete|admin|reply"
allow_any: false
choices:
@ -207,6 +208,7 @@ basic:
post_menu_hidden_items:
client: true
type: list
list_type: simple
default: "flag|bookmark|edit|delete|admin"
allow_any: false
choices:
@ -221,6 +223,7 @@ basic:
share_links:
client: true
type: list
list_type: simple
default: "twitter|facebook|email"
allow_any: false
choices:
@ -241,6 +244,7 @@ basic:
share_quote_buttons:
client: true
type: list
list_type: simple
default: "twitter|email"
allow_any: false
choices: