mirror of
https://github.com/discourse/discourse.git
synced 2025-01-18 10:42:45 +08:00
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:
parent
bf97899029
commit
4773f5d720
|
@ -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>
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue
Block a user