mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 11:23:25 +08:00
FEATURE: introduces list/compact_list components
This commit is contained in:
parent
072f5ce825
commit
066010db7d
|
@ -1,113 +1,101 @@
|
|||
import { on } from "ember-addons/ember-computed-decorators";
|
||||
import computed from "ember-addons/ember-computed-decorators";
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNameBindings: [":value-list"],
|
||||
|
||||
_enableSorting: function() {
|
||||
const self = this;
|
||||
const placeholder = document.createElement("div");
|
||||
placeholder.className = "placeholder";
|
||||
inputInvalid: Ember.computed.empty("newValue"),
|
||||
|
||||
let dragging = null;
|
||||
let over = null;
|
||||
let nodePlacement;
|
||||
inputDelimiter: null,
|
||||
inputType: null,
|
||||
newValue: "",
|
||||
collection: null,
|
||||
values: null,
|
||||
|
||||
this.$().on("dragstart.discourse", ".values .value", function(e) {
|
||||
dragging = e.currentTarget;
|
||||
e.dataTransfer.effectAllowed = "move";
|
||||
e.dataTransfer.setData("text/html", e.currentTarget);
|
||||
});
|
||||
@computed("addKey", "filteredChoices.length")
|
||||
noneKey(addKey, filteredChoicesLength) {
|
||||
return addKey || filteredChoicesLength === 0
|
||||
? "admin.site_settings.value_list.no_choices_none"
|
||||
: "admin.site_settings.value_list.default_none";
|
||||
},
|
||||
|
||||
this.$().on("dragend.discourse", ".values .value", function() {
|
||||
Ember.run(function() {
|
||||
dragging.parentNode.removeChild(placeholder);
|
||||
dragging.style.display = "block";
|
||||
|
||||
// Update data
|
||||
const from = Number(dragging.dataset.index);
|
||||
let to = Number(over.dataset.index);
|
||||
if (from < to) to--;
|
||||
if (nodePlacement === "after") to++;
|
||||
|
||||
const collection = self.get("collection");
|
||||
const fromObj = collection.objectAt(from);
|
||||
collection.replace(from, 1);
|
||||
collection.replace(to, 0, [fromObj]);
|
||||
self._saveValues();
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
this.$().on("dragover.discourse", ".values", function(e) {
|
||||
e.preventDefault();
|
||||
dragging.style.display = "none";
|
||||
if (e.target.className === "placeholder") {
|
||||
return;
|
||||
}
|
||||
over = e.target;
|
||||
|
||||
const relY = e.originalEvent.clientY - over.offsetTop;
|
||||
const height = over.offsetHeight / 2;
|
||||
const parent = e.target.parentNode;
|
||||
|
||||
if (relY > height) {
|
||||
nodePlacement = "after";
|
||||
parent.insertBefore(placeholder, e.target.nextElementSibling);
|
||||
} else if (relY < height) {
|
||||
nodePlacement = "before";
|
||||
parent.insertBefore(placeholder, e.target);
|
||||
}
|
||||
});
|
||||
}.on("didInsertElement"),
|
||||
|
||||
_removeSorting: function() {
|
||||
this.$()
|
||||
.off("dragover.discourse")
|
||||
.off("dragend.discourse")
|
||||
.off("dragstart.discourse");
|
||||
}.on("willDestroyElement"),
|
||||
|
||||
_setupCollection: function() {
|
||||
@on("didReceiveAttrs")
|
||||
_setupCollection() {
|
||||
const values = this.get("values");
|
||||
if (this.get("inputType") === "array") {
|
||||
this.set("collection", values || []);
|
||||
} else {
|
||||
this.set("collection", values && values.length ? values.split("\n") : []);
|
||||
return;
|
||||
}
|
||||
}
|
||||
.on("init")
|
||||
.observes("values"),
|
||||
|
||||
_saveValues: function() {
|
||||
if (this.get("inputType") === "array") {
|
||||
this.set("values", this.get("collection"));
|
||||
} else {
|
||||
this.set("values", this.get("collection").join("\n"));
|
||||
}
|
||||
this.set(
|
||||
"collection",
|
||||
this._splitValues(values, this.get("inputDelimiter") || "\n")
|
||||
);
|
||||
},
|
||||
|
||||
inputInvalid: Ember.computed.empty("newValue"),
|
||||
@computed("choices.[]", "collection.[]")
|
||||
filteredChoices(choices, collection) {
|
||||
return Ember.makeArray(choices).filter(i => collection.indexOf(i) < 0);
|
||||
},
|
||||
|
||||
keyDown(e) {
|
||||
if (e.keyCode === 13) {
|
||||
this.send("addValue");
|
||||
}
|
||||
keyDown(event) {
|
||||
if (event.keyCode === 13) this.send("addValue", this.get("newValue"));
|
||||
},
|
||||
|
||||
actions: {
|
||||
addValue() {
|
||||
if (this.get("inputInvalid")) {
|
||||
return;
|
||||
}
|
||||
changeValue(index, newValue) {
|
||||
this._replaceValue(index, newValue);
|
||||
},
|
||||
|
||||
addValue(newValue) {
|
||||
if (this.get("inputInvalid")) return;
|
||||
|
||||
this.get("collection").addObject(this.get("newValue"));
|
||||
this.set("newValue", "");
|
||||
|
||||
this._saveValues();
|
||||
this._addValue(newValue);
|
||||
},
|
||||
|
||||
removeValue(value) {
|
||||
const collection = this.get("collection");
|
||||
collection.removeObject(value);
|
||||
this._saveValues();
|
||||
this._removeValue(value);
|
||||
},
|
||||
|
||||
selectChoice(choice) {
|
||||
this._addValue(choice);
|
||||
}
|
||||
},
|
||||
|
||||
_addValue(value) {
|
||||
this.get("collection").addObject(value);
|
||||
this._saveValues();
|
||||
},
|
||||
|
||||
_removeValue(value) {
|
||||
const collection = this.get("collection");
|
||||
collection.removeObject(value);
|
||||
this._saveValues();
|
||||
},
|
||||
|
||||
_replaceValue(index, newValue) {
|
||||
this.get("collection").replace(index, 1, [newValue]);
|
||||
this._saveValues();
|
||||
},
|
||||
|
||||
_saveValues() {
|
||||
if (this.get("inputType") === "array") {
|
||||
this.set("values", this.get("collection"));
|
||||
return;
|
||||
}
|
||||
|
||||
this.set(
|
||||
"values",
|
||||
this.get("collection").join(this.get("inputDelimiter") || "\n")
|
||||
);
|
||||
},
|
||||
|
||||
_splitValues(values, delimiter) {
|
||||
if (values && values.length) {
|
||||
return values.split(delimiter).filter(x => x);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -10,7 +10,8 @@ const CUSTOM_TYPES = [
|
|||
"category_list",
|
||||
"value_list",
|
||||
"category",
|
||||
"uploaded_image_list"
|
||||
"uploaded_image_list",
|
||||
"compact_list"
|
||||
];
|
||||
|
||||
export default Ember.Mixin.create({
|
||||
|
@ -59,11 +60,20 @@ export default Ember.Mixin.create({
|
|||
return setting.replace(/\_/g, " ");
|
||||
},
|
||||
|
||||
@computed("setting.type")
|
||||
@computed("type")
|
||||
componentType(type) {
|
||||
return CUSTOM_TYPES.indexOf(type) !== -1 ? type : "string";
|
||||
},
|
||||
|
||||
@computed("setting")
|
||||
type(setting) {
|
||||
if (setting.type === "list" && setting.list_type) {
|
||||
return `${setting.list_type}_list`;
|
||||
}
|
||||
|
||||
return setting.type;
|
||||
},
|
||||
|
||||
@computed("typeClass")
|
||||
componentName(typeClass) {
|
||||
return "site-settings/" + typeClass;
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{{list-setting settingValue=value choices=setting.choices settingName=setting.setting}}
|
||||
{{setting-validation-message message=validationMessage}}
|
||||
<div class='desc'>{{{unbound setting.description}}}</div>
|
|
@ -1,3 +1,3 @@
|
|||
{{list-setting settingValue=value choices=setting.choices settingName=setting.setting}}
|
||||
{{value-list values=value inputDelimiter="|" choices=setting.choices}}
|
||||
{{setting-validation-message message=validationMessage}}
|
||||
<div class='desc'>{{{unbound setting.description}}}</div>
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
{{#if collection}}
|
||||
<div class='values'>
|
||||
{{#each collection as |value index|}}
|
||||
<div class='value' draggable='true' data-index={{index}}>
|
||||
<div class='value' data-index={{index}}>
|
||||
{{d-button action="removeValue"
|
||||
actionParam=value
|
||||
icon="times"
|
||||
class="btn-small"}}
|
||||
{{value}}
|
||||
class="remove-value-btn btn-small"}}
|
||||
|
||||
{{input value=value class="value-input" focus-out=(action "changeValue" index)}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class='input'>
|
||||
{{text-field value=newValue placeholderKey=addKey}}
|
||||
{{d-button action="addValue" icon="plus" class="btn-primary btn-small" disabled=inputInvalid}}
|
||||
</div>
|
||||
{{combo-box
|
||||
allowAny=true
|
||||
allowContentReplacement=true
|
||||
none=noneKey
|
||||
content=filteredChoices
|
||||
onSelect=(action "selectChoice")}}
|
||||
|
|
|
@ -151,9 +151,14 @@ export default Ember.Component.extend(
|
|||
this
|
||||
);
|
||||
|
||||
const existingCreatedComputedContent = this.get(
|
||||
"computedContent"
|
||||
).filterBy("created", true);
|
||||
let existingCreatedComputedContent = [];
|
||||
if (!this.get("allowContentReplacement")) {
|
||||
existingCreatedComputedContent = this.get("computedContent").filterBy(
|
||||
"created",
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
this.setProperties({
|
||||
computedContent: content
|
||||
.map(c => this.computeContentItem(c))
|
||||
|
|
|
@ -77,8 +77,8 @@ export default Ember.Mixin.create({
|
|||
|
||||
// use to collapse and remove focus
|
||||
close(event) {
|
||||
this.collapse(event);
|
||||
this.setProperties({ isFocused: false });
|
||||
this.collapse(event);
|
||||
},
|
||||
|
||||
focus() {
|
||||
|
@ -118,8 +118,11 @@ export default Ember.Mixin.create({
|
|||
|
||||
collapse() {
|
||||
this.set("isExpanded", false);
|
||||
Ember.run.schedule("afterRender", () => this._removeFixedPosition());
|
||||
this._boundaryActionHandler("onCollapse", this);
|
||||
|
||||
Ember.run.next(() => {
|
||||
Ember.run.schedule("afterRender", () => this._removeFixedPosition());
|
||||
this._boundaryActionHandler("onCollapse", this);
|
||||
});
|
||||
},
|
||||
|
||||
// lose focus of the component in two steps
|
||||
|
|
|
@ -873,25 +873,43 @@ table#user-badges {
|
|||
|
||||
.value-list {
|
||||
.value {
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 3px;
|
||||
margin-right: 10px;
|
||||
padding: 0.125em 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
cursor: move;
|
||||
display: flex;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.value-input {
|
||||
box-sizing: border-box;
|
||||
flex: 1;
|
||||
border-color: $primary-low;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
|
||||
&:focus {
|
||||
border-color: $tertiary;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.remove-value-btn {
|
||||
margin-right: 0.25em;
|
||||
width: 29px;
|
||||
border: 1px solid $primary-low;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
|
||||
&:focus {
|
||||
border-color: $tertiary;
|
||||
}
|
||||
}
|
||||
}
|
||||
.values {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.placeholder {
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 3px;
|
||||
margin-right: 10px;
|
||||
height: 30px;
|
||||
}
|
||||
input[type="text"] {
|
||||
width: 90%;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -444,9 +444,17 @@
|
|||
padding: 0.25em 0;
|
||||
&.input-area {
|
||||
width: 75%;
|
||||
.value-list,
|
||||
.select-kit,
|
||||
input[type="text"] {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.value-list {
|
||||
.select-kit {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.label-area {
|
||||
width: 25%;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
class ThemeSettingsSerializer < ApplicationSerializer
|
||||
attributes :setting, :type, :default, :value, :description, :valid_values
|
||||
attributes :setting, :type, :default, :value, :description, :valid_values,
|
||||
:list_type
|
||||
|
||||
def setting
|
||||
object.name
|
||||
|
@ -32,4 +33,12 @@ class ThemeSettingsSerializer < ApplicationSerializer
|
|||
def include_description?
|
||||
object.description.present?
|
||||
end
|
||||
|
||||
def list_type
|
||||
object.list_type
|
||||
end
|
||||
|
||||
def include_list_type?
|
||||
object.type == ThemeSetting.types[:list]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3828,6 +3828,9 @@ en:
|
|||
clear_filter: "Clear"
|
||||
add_url: "add URL"
|
||||
add_host: "add host"
|
||||
value_list:
|
||||
default_none: "Type to filter or create..."
|
||||
no_choices_none: "Type to create..."
|
||||
uploaded_image_list:
|
||||
label: "Edit list"
|
||||
empty: "There are no pictures yet. Please upload one."
|
||||
|
|
|
@ -116,6 +116,7 @@ basic:
|
|||
client: true
|
||||
refresh: true
|
||||
type: list
|
||||
list_type: compact
|
||||
default: "latest|new|unread|top|categories"
|
||||
regex: "latest"
|
||||
regex_error: "site_settings.errors.must_include_latest"
|
||||
|
@ -176,6 +177,7 @@ basic:
|
|||
category_colors:
|
||||
client: true
|
||||
type: list
|
||||
list_type: compact
|
||||
default: 'BF1E2E|F1592A|F7941D|9EB83B|3AB54A|12A89D|25AAE2|0E76BD|652D90|92278F|ED207B|8C6238|231F20|808281|B3B5B4|283890'
|
||||
category_style:
|
||||
client: true
|
||||
|
|
|
@ -6,7 +6,7 @@ module SiteSettings; end
|
|||
class SiteSettings::TypeSupervisor
|
||||
include SiteSettings::Validations
|
||||
|
||||
CONSUMED_OPTS = %i[enum choices type validator min max regex hidden regex_error allow_any].freeze
|
||||
CONSUMED_OPTS = %i[enum choices type validator min max regex hidden regex_error allow_any list_type].freeze
|
||||
VALIDATOR_OPTS = %i[min max regex hidden regex_error].freeze
|
||||
|
||||
# For plugins, so they can tell if a feature is supported
|
||||
|
@ -63,6 +63,7 @@ class SiteSettings::TypeSupervisor
|
|||
@validators = {}
|
||||
@types = {}
|
||||
@allow_any = {}
|
||||
@list_type = {}
|
||||
end
|
||||
|
||||
def load_setting(name_arg, opts = {})
|
||||
|
@ -88,6 +89,7 @@ class SiteSettings::TypeSupervisor
|
|||
|
||||
if type.to_sym == :list
|
||||
@allow_any[name] = opts[:allow_any] == false ? false : true
|
||||
@list_type[name] = opts[:list_type] if opts[:list_type]
|
||||
end
|
||||
end
|
||||
@types[name] = get_data_type(name, @defaults_provider[name])
|
||||
|
@ -144,6 +146,7 @@ class SiteSettings::TypeSupervisor
|
|||
end
|
||||
|
||||
result[:choices] = @choices[name] if @choices.has_key? name
|
||||
result[:list_type] = @list_type[name] if @list_type.has_key? name
|
||||
result
|
||||
end
|
||||
|
||||
|
|
|
@ -93,8 +93,13 @@ class ThemeSettingsManager
|
|||
(max.is_a?(::Integer) || max.is_a?(::Float)) && max != ::Float::INFINITY
|
||||
end
|
||||
|
||||
class List < self; end
|
||||
class String < self
|
||||
class List < self
|
||||
def list_type
|
||||
@opts[:list_type]
|
||||
end
|
||||
end
|
||||
|
||||
class String < self
|
||||
def is_valid_value?(new_value)
|
||||
(@opts[:min]..@opts[:max]).include? new_value.to_s.length
|
||||
end
|
||||
|
|
|
@ -33,6 +33,11 @@ class ThemeSettingsParser
|
|||
opts[:max] = raw_opts[:max].is_a?(Numeric) ? raw_opts[:max] : Float::INFINITY
|
||||
opts[:min] = raw_opts[:min].is_a?(Numeric) ? raw_opts[:min] : -Float::INFINITY
|
||||
end
|
||||
|
||||
if raw_opts[:list_type]
|
||||
opts[:list_type] = raw_opts[:list_type]
|
||||
end
|
||||
|
||||
opts
|
||||
end
|
||||
|
||||
|
|
|
@ -306,7 +306,7 @@ describe SiteSettings::TypeSupervisor do
|
|||
settings.setting(:type_url_list, 'string', type: 'url_list')
|
||||
settings.setting(:type_enum_choices, '2', type: 'enum', choices: ['1', '2'])
|
||||
settings.setting(:type_enum_class, 'a', enum: 'TestEnumClass2')
|
||||
settings.setting(:type_list, 'a', type: 'list', choices: ['a', 'b'])
|
||||
settings.setting(:type_list, 'a', type: 'list', choices: ['a', 'b'], list_type: 'compact')
|
||||
settings.refresh!
|
||||
end
|
||||
|
||||
|
@ -336,6 +336,10 @@ describe SiteSettings::TypeSupervisor do
|
|||
expect(settings.type_supervisor.type_hash(:type_list)[:choices]).to eq ['a', 'b']
|
||||
end
|
||||
|
||||
it 'returns list list_type' do
|
||||
expect(settings.type_supervisor.type_hash(:type_list)[:list_type]).to eq 'compact'
|
||||
end
|
||||
|
||||
it 'returns enum choices' do
|
||||
hash = settings.type_supervisor.type_hash(:type_enum_choices)
|
||||
expect(hash[:valid_values]).to eq [{ name: '1', value: '1' }, { name: '2', value: '2' }]
|
||||
|
|
|
@ -114,4 +114,11 @@ describe ThemeSettingsManager do
|
|||
expect { string_setting.value = ("a" * 21) }.to raise_error(Discourse::InvalidParameters)
|
||||
end
|
||||
end
|
||||
|
||||
context "List" do
|
||||
it "can have a list type" do
|
||||
list_setting = find_by_name(:compact_list_setting)
|
||||
expect(list_setting.list_type).to eq("compact")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -82,4 +82,11 @@ describe ThemeSettingsParser do
|
|||
expect(choices.length).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
context "list setting" do
|
||||
it "supports list type" do
|
||||
list_type = loader.find_by_name(:compact_list_setting)[:opts][:list_type]
|
||||
expect(list_type).to eq("compact")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -37,6 +37,12 @@ list_setting:
|
|||
description: "help text"
|
||||
default: "name|age|last name"
|
||||
|
||||
compact_list_setting:
|
||||
type: list
|
||||
list_type: compact
|
||||
description: "help text"
|
||||
default: "name|age|last name"
|
||||
|
||||
enum_setting:
|
||||
default: "trust level 4"
|
||||
type: enum
|
||||
|
|
|
@ -1,63 +1,111 @@
|
|||
import componentTest from "helpers/component-test";
|
||||
moduleForComponent("value-list", { integration: true });
|
||||
|
||||
componentTest("functionality", {
|
||||
template: '{{value-list values=values inputType="array"}}',
|
||||
componentTest("adding a value", {
|
||||
template: "{{value-list values=values}}",
|
||||
|
||||
async test(assert) {
|
||||
assert.ok(this.$(".values .value").length === 0, "it has no values");
|
||||
assert.ok(this.$("input").length, "it renders the input");
|
||||
this.set("values", "vinkas\nosama");
|
||||
|
||||
await selectKit().expand();
|
||||
await selectKit().fillInFilter("eviltrout");
|
||||
await selectKit().keyboard("enter");
|
||||
|
||||
assert.ok(
|
||||
this.$(".btn-primary[disabled]").length,
|
||||
"it is disabled with no value"
|
||||
find(".values .value").length === 3,
|
||||
"it adds the value to the list of values"
|
||||
);
|
||||
|
||||
await fillIn("input", "eviltrout");
|
||||
assert.deepEqual(
|
||||
this.get("values"),
|
||||
"vinkas\nosama\neviltrout",
|
||||
"it adds the value to the list of values"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("removing a value", {
|
||||
template: "{{value-list values=values}}",
|
||||
|
||||
async test(assert) {
|
||||
this.set("values", "vinkas\nosama");
|
||||
|
||||
await click(".values .value[data-index='0'] .remove-value-btn");
|
||||
|
||||
assert.ok(
|
||||
!this.$(".btn-primary[disabled]").length,
|
||||
"it isn't disabled anymore"
|
||||
find(".values .value").length === 1,
|
||||
"it removes the value from the list of values"
|
||||
);
|
||||
|
||||
await click(".btn-primary");
|
||||
assert.equal(this.$(".values .value").length, 1, "it adds the value");
|
||||
assert.equal(this.$("input").val(), "", "it clears the input");
|
||||
assert.ok(this.$(".btn-primary[disabled]").length, "it is disabled again");
|
||||
assert.equal(this.get("values"), "eviltrout", "it appends the value");
|
||||
|
||||
await click(".value .btn-small");
|
||||
assert.ok(this.$(".values .value").length === 0, "it removes the value");
|
||||
assert.equal(this.get("values"), "osama", "it removes the expected value");
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with string delimited values", {
|
||||
template: "{{value-list values=valueString}}",
|
||||
beforeEach() {
|
||||
this.set("valueString", "hello\nworld");
|
||||
},
|
||||
componentTest("selecting a value", {
|
||||
template: "{{value-list values=values choices=choices}}",
|
||||
|
||||
async test(assert) {
|
||||
assert.equal(this.$(".values .value").length, 2);
|
||||
this.set("values", "vinkas\nosama");
|
||||
this.set("choices", ["maja", "michael"]);
|
||||
|
||||
await fillIn("input", "eviltrout");
|
||||
await click(".btn-primary");
|
||||
await selectKit().expand();
|
||||
await selectKit().selectRowByValue("maja");
|
||||
|
||||
assert.equal(this.$(".values .value").length, 3);
|
||||
assert.equal(this.get("valueString"), "hello\nworld\neviltrout");
|
||||
assert.ok(
|
||||
find(".values .value").length === 3,
|
||||
"it adds the value to the list of values"
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
this.get("values"),
|
||||
"vinkas\nosama\nmaja",
|
||||
"it adds the value to the list of values"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("with array values", {
|
||||
template: '{{value-list values=valueArray inputType="array"}}',
|
||||
beforeEach() {
|
||||
this.set("valueArray", ["abc", "def"]);
|
||||
},
|
||||
componentTest("array support", {
|
||||
template: "{{value-list values=values inputType='array'}}",
|
||||
|
||||
async test(assert) {
|
||||
assert.equal(this.$(".values .value").length, 2);
|
||||
this.set("values", ["vinkas", "osama"]);
|
||||
|
||||
await fillIn("input", "eviltrout");
|
||||
await click(".btn-primary");
|
||||
await selectKit().expand();
|
||||
await selectKit().fillInFilter("eviltrout");
|
||||
await selectKit().keyboard("enter");
|
||||
|
||||
assert.equal(this.$(".values .value").length, 3);
|
||||
assert.deepEqual(this.get("valueArray"), ["abc", "def", "eviltrout"]);
|
||||
assert.ok(
|
||||
find(".values .value").length === 3,
|
||||
"it adds the value to the list of values"
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
this.get("values"),
|
||||
["vinkas", "osama", "eviltrout"],
|
||||
"it adds the value to the list of values"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
componentTest("delimiter support", {
|
||||
template: "{{value-list values=values inputDelimiter='|'}}",
|
||||
|
||||
async test(assert) {
|
||||
this.set("values", "vinkas|osama");
|
||||
|
||||
await selectKit().expand();
|
||||
await selectKit().fillInFilter("eviltrout");
|
||||
await selectKit().keyboard("enter");
|
||||
|
||||
assert.ok(
|
||||
find(".values .value").length === 3,
|
||||
"it adds the value to the list of values"
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
this.get("values"),
|
||||
"vinkas|osama|eviltrout",
|
||||
"it adds the value to the list of values"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user