2017-11-21 18:53:09 +08:00
|
|
|
import SelectKitComponent from "select-kit/components/select-kit";
|
2018-01-24 18:48:20 +08:00
|
|
|
import { default as computed, on } from 'ember-addons/ember-computed-decorators';
|
2017-11-22 17:34:12 +08:00
|
|
|
const { get, isNone, isEmpty, isPresent, run } = Ember;
|
2017-11-21 18:53:09 +08:00
|
|
|
|
|
|
|
export default SelectKitComponent.extend({
|
|
|
|
pluginApiIdentifiers: ["single-select"],
|
2018-02-26 18:42:57 +08:00
|
|
|
layoutName: "select-kit/templates/components/single-select",
|
2017-11-21 18:53:09 +08:00
|
|
|
classNames: "single-select",
|
|
|
|
computedValue: null,
|
|
|
|
value: null,
|
2017-11-24 20:15:02 +08:00
|
|
|
allowInitialValueMutation: false,
|
2017-11-21 18:53:09 +08:00
|
|
|
|
|
|
|
@on("didReceiveAttrs")
|
|
|
|
_compute() {
|
2017-11-28 02:50:04 +08:00
|
|
|
run.scheduleOnce("afterRender", () => {
|
2017-11-21 18:53:09 +08:00
|
|
|
this.willComputeAttributes();
|
2018-02-26 18:42:57 +08:00
|
|
|
let content = this.get("content") || [];
|
|
|
|
let asyncContent = this.get("asyncContent") || [];
|
|
|
|
content = this.willComputeContent(content);
|
|
|
|
asyncContent = this.willComputeAsyncContent(asyncContent);
|
2017-11-21 18:53:09 +08:00
|
|
|
let value = this._beforeWillComputeValue(this.get("value"));
|
|
|
|
content = this.computeContent(content);
|
2018-02-26 18:42:57 +08:00
|
|
|
asyncContent = this.computeAsyncContent(asyncContent);
|
2017-11-21 18:53:09 +08:00
|
|
|
content = this._beforeDidComputeContent(content);
|
2018-02-26 18:42:57 +08:00
|
|
|
asyncContent = this._beforeDidComputeAsyncContent(asyncContent);
|
2017-11-21 18:53:09 +08:00
|
|
|
value = this.willComputeValue(value);
|
|
|
|
value = this.computeValue(value);
|
|
|
|
value = this._beforeDidComputeValue(value);
|
|
|
|
this.didComputeContent(content);
|
2018-02-26 18:42:57 +08:00
|
|
|
this.didComputeAsyncContent(asyncContent);
|
2017-11-21 18:53:09 +08:00
|
|
|
this.didComputeValue(value);
|
|
|
|
this.didComputeAttributes();
|
2017-11-23 21:39:26 +08:00
|
|
|
|
|
|
|
if (this.get("allowInitialValueMutation")) this.mutateAttributes();
|
2018-01-11 16:39:51 +08:00
|
|
|
|
2018-01-26 21:42:24 +08:00
|
|
|
this._setCollectionHeaderComputedContent();
|
2018-01-11 16:39:51 +08:00
|
|
|
this._setHeaderComputedContent();
|
2017-11-21 18:53:09 +08:00
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2017-11-22 17:34:12 +08:00
|
|
|
mutateAttributes() {
|
2017-11-28 02:50:04 +08:00
|
|
|
if (this.get("isDestroyed") || this.get("isDestroying")) return;
|
|
|
|
|
2017-11-22 17:34:12 +08:00
|
|
|
run.next(() => {
|
|
|
|
this.mutateContent(this.get("computedContent"));
|
|
|
|
this.mutateValue(this.get("computedValue"));
|
2018-01-26 21:42:24 +08:00
|
|
|
this._setCollectionHeaderComputedContent();
|
2018-01-09 17:52:32 +08:00
|
|
|
this._setHeaderComputedContent();
|
2017-11-22 17:34:12 +08:00
|
|
|
});
|
|
|
|
},
|
|
|
|
mutateContent() {},
|
|
|
|
mutateValue(computedValue) {
|
|
|
|
this.set("value", computedValue);
|
|
|
|
},
|
|
|
|
|
2017-11-21 18:53:09 +08:00
|
|
|
_beforeWillComputeValue(value) {
|
2018-01-24 18:48:20 +08:00
|
|
|
if (!isEmpty(this.get("content")) &&
|
|
|
|
isEmpty(value) &&
|
|
|
|
isNone(this.get("none")) &&
|
|
|
|
this.get("allowAutoSelectFirst")) {
|
|
|
|
value = this.valueForContentItem(get(this.get("content"), "firstObject"));
|
2017-11-24 20:15:02 +08:00
|
|
|
}
|
|
|
|
|
2017-11-21 18:53:09 +08:00
|
|
|
switch (typeof value) {
|
|
|
|
case "string":
|
|
|
|
case "number":
|
|
|
|
return this._castInteger(value === "" ? null : value);
|
|
|
|
default:
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
willComputeValue(value) { return value; },
|
|
|
|
computeValue(value) { return value; },
|
|
|
|
_beforeDidComputeValue(value) {
|
|
|
|
this.setProperties({ computedValue: value });
|
|
|
|
return value;
|
|
|
|
},
|
|
|
|
didComputeValue(value) { return value; },
|
|
|
|
|
|
|
|
filterComputedContent(computedContent, computedValue, filter) {
|
|
|
|
const lowerFilter = filter.toLowerCase();
|
|
|
|
return computedContent.filter(c => {
|
|
|
|
return get(c, "name").toLowerCase().indexOf(lowerFilter) > -1;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
baseHeaderComputedContent() {
|
|
|
|
return {
|
2017-12-22 20:08:12 +08:00
|
|
|
title: this.get("title"),
|
2017-11-21 18:53:09 +08:00
|
|
|
icons: Ember.makeArray(this.getWithDefault("headerIcon", [])),
|
2017-12-22 20:08:12 +08:00
|
|
|
value: this.get("selectedComputedContent.value"),
|
2017-11-21 18:53:09 +08:00
|
|
|
name: this.get("selectedComputedContent.name") || this.get("noneRowComputedContent.name")
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
2018-02-26 18:42:57 +08:00
|
|
|
@computed("computedAsyncContent.[]", "computedValue")
|
|
|
|
filteredAsyncComputedContent(computedAsyncContent, computedValue) {
|
|
|
|
computedAsyncContent = computedAsyncContent.filter(c => {
|
|
|
|
return computedValue !== get(c, "value");
|
|
|
|
});
|
|
|
|
|
|
|
|
if (this.get("limitMatches")) {
|
|
|
|
return computedAsyncContent.slice(0, this.get("limitMatches"));
|
|
|
|
}
|
|
|
|
|
|
|
|
return computedAsyncContent;
|
|
|
|
},
|
|
|
|
|
2017-11-21 18:53:09 +08:00
|
|
|
@computed("computedContent.[]", "computedValue", "filter", "shouldFilter")
|
|
|
|
filteredComputedContent(computedContent, computedValue, filter, shouldFilter) {
|
2018-01-24 18:48:20 +08:00
|
|
|
if (shouldFilter) {
|
2017-11-21 18:53:09 +08:00
|
|
|
computedContent = this.filterComputedContent(computedContent, computedValue, filter);
|
|
|
|
}
|
|
|
|
|
2018-01-11 16:54:39 +08:00
|
|
|
if (this.get("limitMatches")) {
|
|
|
|
return computedContent.slice(0, this.get("limitMatches"));
|
|
|
|
}
|
|
|
|
|
|
|
|
return computedContent;
|
2017-11-21 18:53:09 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
@computed("computedValue", "computedContent.[]")
|
|
|
|
selectedComputedContent(computedValue, computedContent) {
|
|
|
|
return computedContent.findBy("value", computedValue);
|
|
|
|
},
|
|
|
|
|
|
|
|
@computed("selectedComputedContent")
|
|
|
|
hasSelection(selectedComputedContent) {
|
|
|
|
return selectedComputedContent !== this.get("noneRowComputedContent") &&
|
|
|
|
!Ember.isNone(selectedComputedContent);
|
|
|
|
},
|
|
|
|
|
2018-03-03 18:42:44 +08:00
|
|
|
@computed("computedValue", "filter", "collectionComputedContent.[]", "limitReached")
|
|
|
|
shouldDisplayCreateRow(computedValue, filter) {
|
2017-11-21 18:53:09 +08:00
|
|
|
return this._super() && computedValue !== filter;
|
|
|
|
},
|
|
|
|
|
|
|
|
autoHighlight() {
|
2017-11-28 02:50:04 +08:00
|
|
|
run.schedule("afterRender", () => {
|
2018-01-24 18:48:20 +08:00
|
|
|
if (!isNone(this.get("highlightedValue"))) return;
|
2017-11-21 18:53:09 +08:00
|
|
|
|
|
|
|
const filteredComputedContent = this.get("filteredComputedContent");
|
|
|
|
const displayCreateRow = this.get("shouldDisplayCreateRow");
|
|
|
|
const none = this.get("noneRowComputedContent");
|
|
|
|
|
|
|
|
if (this.get("hasSelection") && isEmpty(this.get("filter"))) {
|
2018-01-11 16:39:51 +08:00
|
|
|
this.send("highlight", this.get("selectedComputedContent"));
|
2017-11-21 18:53:09 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isNone(this.get("highlightedValue")) && !isEmpty(filteredComputedContent)) {
|
2018-01-11 16:39:51 +08:00
|
|
|
this.send("highlight", get(filteredComputedContent, "firstObject"));
|
2017-11-21 18:53:09 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-01-24 18:48:20 +08:00
|
|
|
if (displayCreateRow && isEmpty(filteredComputedContent)) {
|
2018-01-11 16:39:51 +08:00
|
|
|
this.send("highlight", this.get("createRowComputedContent"));
|
2017-11-21 18:53:09 +08:00
|
|
|
}
|
|
|
|
else if (!isEmpty(filteredComputedContent)) {
|
2018-01-11 16:39:51 +08:00
|
|
|
this.send("highlight", get(filteredComputedContent, "firstObject"));
|
2017-11-21 18:53:09 +08:00
|
|
|
}
|
2018-01-24 18:48:20 +08:00
|
|
|
else if (isEmpty(filteredComputedContent) && isPresent(none) && !displayCreateRow) {
|
2018-01-11 16:39:51 +08:00
|
|
|
this.send("highlight", none);
|
2017-11-21 18:53:09 +08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
actions: {
|
2018-01-11 16:39:51 +08:00
|
|
|
clearSelection() {
|
|
|
|
this.send("deselect", this.get("selectedComputedContent"));
|
|
|
|
this._boundaryActionHandler("onClearSelection");
|
2017-11-21 18:53:09 +08:00
|
|
|
},
|
|
|
|
|
2018-01-11 16:39:51 +08:00
|
|
|
create(computedContentItem) {
|
2018-02-14 00:23:12 +08:00
|
|
|
if (this.get("computedValue") !== computedContentItem.value &&
|
|
|
|
this.validateCreate(computedContentItem.value)) {
|
2017-11-21 18:53:09 +08:00
|
|
|
this.get("computedContent").pushObject(computedContentItem);
|
2018-01-11 16:39:51 +08:00
|
|
|
this._boundaryActionHandler("onCreate");
|
|
|
|
this.send("select", computedContentItem);
|
|
|
|
} else {
|
|
|
|
this._boundaryActionHandler("onCreateFailure");
|
2017-11-21 18:53:09 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-01-11 16:39:51 +08:00
|
|
|
select(rowComputedContentItem) {
|
2018-02-14 00:23:12 +08:00
|
|
|
if (this.validateSelect(rowComputedContentItem)) {
|
|
|
|
this.willSelect(rowComputedContentItem);
|
|
|
|
this.set("computedValue", rowComputedContentItem.value);
|
|
|
|
this.mutateAttributes();
|
|
|
|
run.schedule("afterRender", () => this.didSelect(rowComputedContentItem));
|
|
|
|
} else {
|
|
|
|
this._boundaryActionHandler("onSelectFailure");
|
|
|
|
}
|
2017-11-21 18:53:09 +08:00
|
|
|
},
|
|
|
|
|
2018-01-11 16:39:51 +08:00
|
|
|
deselect(rowComputedContentItem) {
|
2017-11-21 18:53:09 +08:00
|
|
|
this.willDeselect(rowComputedContentItem);
|
|
|
|
this.set("computedValue", null);
|
|
|
|
this.mutateAttributes();
|
2017-11-28 02:50:04 +08:00
|
|
|
run.schedule("afterRender", () => this.didDeselect(rowComputedContentItem));
|
2017-11-21 18:53:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|