mirror of
https://github.com/discourse/discourse.git
synced 2024-11-23 03:40:00 +08:00
FIX: improves category/tag drops header shortcuts (#6610)
- wont appear when filtering - can now be selected with keyboard - fix bugs on click with safari/firefox
This commit is contained in:
parent
fc95f772bc
commit
9911a41f4c
|
@ -10,7 +10,7 @@ export default ComboBoxComponent.extend({
|
||||||
classNameBindings: ["categoryStyle"],
|
classNameBindings: ["categoryStyle"],
|
||||||
classNames: "category-drop",
|
classNames: "category-drop",
|
||||||
verticalOffset: 3,
|
verticalOffset: 3,
|
||||||
content: Ember.computed.alias("categories"),
|
content: Ember.computed.alias("categoriesWithShortcuts"),
|
||||||
rowComponent: "category-row",
|
rowComponent: "category-row",
|
||||||
headerComponent: "category-drop/category-drop-header",
|
headerComponent: "category-drop/category-drop-header",
|
||||||
allowAutoSelectFirst: false,
|
allowAutoSelectFirst: false,
|
||||||
|
@ -24,6 +24,34 @@ export default ComboBoxComponent.extend({
|
||||||
subCategory: false,
|
subCategory: false,
|
||||||
isAsync: Ember.computed.not("subCategory"),
|
isAsync: Ember.computed.not("subCategory"),
|
||||||
|
|
||||||
|
@computed("categories", "hasSelection", "subCategory", "noSubcategories")
|
||||||
|
categoriesWithShortcuts(
|
||||||
|
categories,
|
||||||
|
hasSelection,
|
||||||
|
subCategory,
|
||||||
|
noSubcategories
|
||||||
|
) {
|
||||||
|
const shortcuts = [];
|
||||||
|
|
||||||
|
if (hasSelection || (noSubcategories && subCategory)) {
|
||||||
|
shortcuts.push({
|
||||||
|
name: this.get("allCategoriesLabel"),
|
||||||
|
__sk_row_type: "noopRow",
|
||||||
|
id: "all-categories"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subCategory && (hasSelection || !noSubcategories)) {
|
||||||
|
shortcuts.push({
|
||||||
|
name: this.get("noCategoriesLabel"),
|
||||||
|
__sk_row_type: "noopRow",
|
||||||
|
id: "no-categories"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return shortcuts.concat(categories);
|
||||||
|
},
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this._super();
|
this._super();
|
||||||
|
|
||||||
|
@ -54,45 +82,6 @@ export default ComboBoxComponent.extend({
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed(
|
|
||||||
"allCategoriesUrl",
|
|
||||||
"allCategoriesLabel",
|
|
||||||
"noCategoriesUrl",
|
|
||||||
"noCategoriesLabel"
|
|
||||||
)
|
|
||||||
collectionHeader(
|
|
||||||
allCategoriesUrl,
|
|
||||||
allCategoriesLabel,
|
|
||||||
noCategoriesUrl,
|
|
||||||
noCategoriesLabel
|
|
||||||
) {
|
|
||||||
let shortcuts = "";
|
|
||||||
|
|
||||||
if (
|
|
||||||
this.get("hasSelection") ||
|
|
||||||
(this.get("noSubcategories") && this.get("subCategory"))
|
|
||||||
) {
|
|
||||||
shortcuts += `
|
|
||||||
<a href="${allCategoriesUrl}" class="category-filter">
|
|
||||||
${allCategoriesLabel}
|
|
||||||
</a>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
this.get("subCategory") &&
|
|
||||||
(this.get("hasSelection") || !this.get("noSubcategories"))
|
|
||||||
) {
|
|
||||||
shortcuts += `
|
|
||||||
<a href="${noCategoriesUrl}" class="category-filter">
|
|
||||||
${noCategoriesLabel}
|
|
||||||
</a>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return shortcuts.htmlSafe();
|
|
||||||
},
|
|
||||||
|
|
||||||
computeHeaderContent() {
|
computeHeaderContent() {
|
||||||
let content = this._super();
|
let content = this._super();
|
||||||
|
|
||||||
|
@ -131,19 +120,28 @@ export default ComboBoxComponent.extend({
|
||||||
|
|
||||||
@computed("parentCategory.url", "subCategory")
|
@computed("parentCategory.url", "subCategory")
|
||||||
allCategoriesUrl(parentCategoryUrl, subCategory) {
|
allCategoriesUrl(parentCategoryUrl, subCategory) {
|
||||||
return subCategory ? parentCategoryUrl || "/" : "/";
|
return Discourse.getURL(subCategory ? parentCategoryUrl || "/" : "/");
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed("parentCategory.url")
|
@computed("parentCategory.url")
|
||||||
noCategoriesUrl(parentCategoryUrl) {
|
noCategoriesUrl(parentCategoryUrl) {
|
||||||
return `${parentCategoryUrl}/none`;
|
return Discourse.getURL(`${parentCategoryUrl}/none`);
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
onSelect(categoryId) {
|
onSelect(categoryId) {
|
||||||
const category = Category.findById(parseInt(categoryId, 10));
|
let categoryURL;
|
||||||
const categoryURL =
|
|
||||||
Discourse.getURL("/c/") + Discourse.Category.slugFor(category);
|
if (categoryId === "all-categories") {
|
||||||
|
categoryURL = Discourse.getURL(this.get("allCategoriesUrl"));
|
||||||
|
} else if (categoryId === "no-categories") {
|
||||||
|
categoryURL = Discourse.getURL(this.get("noCategoriesUrl"));
|
||||||
|
} else {
|
||||||
|
const category = Category.findById(parseInt(categoryId, 10));
|
||||||
|
const slug = Discourse.Category.slugFor(category);
|
||||||
|
categoryURL = Discourse.getURL("/c/") + slug;
|
||||||
|
}
|
||||||
|
|
||||||
DiscourseURL.routeTo(categoryURL);
|
DiscourseURL.routeTo(categoryURL);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -264,6 +264,11 @@ export default SelectKitComponent.extend({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (computedContentItem.__sk_row_type === "noopRow") {
|
||||||
|
this._boundaryActionHandler("onSelect", computedContentItem.value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (computedContentItem.__sk_row_type === "createRow") {
|
if (computedContentItem.__sk_row_type === "createRow") {
|
||||||
if (
|
if (
|
||||||
!this.get("computedValues").includes(computedContentItem.value) &&
|
!this.get("computedValues").includes(computedContentItem.value) &&
|
||||||
|
|
|
@ -213,7 +213,9 @@ export default Ember.Component.extend(
|
||||||
name: name || this._nameForContent(contentItem),
|
name: name || this._nameForContent(contentItem),
|
||||||
locked: false,
|
locked: false,
|
||||||
created: options.created || false,
|
created: options.created || false,
|
||||||
__sk_row_type: options.created ? "createRow" : null,
|
__sk_row_type: options.created
|
||||||
|
? "createRow"
|
||||||
|
: contentItem.__sk_row_type,
|
||||||
originalContent
|
originalContent
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,11 @@ export default SelectKitComponent.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
select(computedContentItem) {
|
select(computedContentItem) {
|
||||||
|
if (computedContentItem.__sk_row_type === "noopRow") {
|
||||||
|
this._boundaryActionHandler("onSelect", computedContentItem.value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.get("hasSelection")) {
|
if (this.get("hasSelection")) {
|
||||||
this.deselect(this.get("selection.value"));
|
this.deselect(this.get("selection.value"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,9 +67,9 @@ export default ComboBoxComponent.extend(TagsMixin, {
|
||||||
@computed("firstCategory", "secondCategory")
|
@computed("firstCategory", "secondCategory")
|
||||||
allTagsUrl() {
|
allTagsUrl() {
|
||||||
if (this.get("currentCategory")) {
|
if (this.get("currentCategory")) {
|
||||||
return this.get("currentCategory.url") + "?allTags=1";
|
return Discourse.getURL(this.get("currentCategory.url") + "?allTags=1");
|
||||||
} else {
|
} else {
|
||||||
return "/";
|
return Discourse.getURL("/");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -79,30 +79,7 @@ export default ComboBoxComponent.extend(TagsMixin, {
|
||||||
if (this.get("currentCategory")) {
|
if (this.get("currentCategory")) {
|
||||||
url += this.get("currentCategory.url");
|
url += this.get("currentCategory.url");
|
||||||
}
|
}
|
||||||
return `${url}/none`;
|
return Discourse.getURL(`${url}/none`);
|
||||||
},
|
|
||||||
|
|
||||||
@computed("allTagsUrl", "allTagsLabel", "noTagsUrl", "noTagsLabel")
|
|
||||||
collectionHeader(allTagsUrl, allTagsLabel, noTagsUrl, noTagsLabel) {
|
|
||||||
let content = "";
|
|
||||||
|
|
||||||
if (this.get("tagId") !== "none") {
|
|
||||||
content += `
|
|
||||||
<a href="${noTagsUrl}" class="tag-filter">
|
|
||||||
${noTagsLabel}
|
|
||||||
</a>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.get("tagId")) {
|
|
||||||
content += `
|
|
||||||
<a href="${allTagsUrl}" class="tag-filter">
|
|
||||||
${allTagsLabel}
|
|
||||||
</a>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return content;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed("tag")
|
@computed("tag")
|
||||||
|
@ -115,12 +92,35 @@ export default ComboBoxComponent.extend(TagsMixin, {
|
||||||
return I18n.t("tagging.selector_no_tags");
|
return I18n.t("tagging.selector_no_tags");
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed("site.top_tags")
|
@computed("tagId", "allTagsLabel", "noTagsLabel")
|
||||||
content(topTags) {
|
shortcuts(tagId, allTagsLabel, noTagsLabel) {
|
||||||
|
const shortcuts = [];
|
||||||
|
|
||||||
|
if (tagId !== "none") {
|
||||||
|
shortcuts.push({
|
||||||
|
name: noTagsLabel,
|
||||||
|
__sk_row_type: "noopRow",
|
||||||
|
id: "no-tags"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tagId) {
|
||||||
|
shortcuts.push({
|
||||||
|
name: allTagsLabel,
|
||||||
|
__sk_row_type: "noopRow",
|
||||||
|
id: "all-tags"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return shortcuts;
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed("site.top_tags", "shortcuts")
|
||||||
|
content(topTags, shortcuts) {
|
||||||
if (this.siteSettings.tags_sort_alphabetically && topTags) {
|
if (this.siteSettings.tags_sort_alphabetically && topTags) {
|
||||||
return topTags.sort();
|
return shortcuts.concat(topTags.sort());
|
||||||
} else {
|
} else {
|
||||||
return topTags;
|
return shortcuts.concat(topTags);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -141,11 +141,20 @@ export default ComboBoxComponent.extend(TagsMixin, {
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
onSelect(tagId) {
|
onSelect(tagId) {
|
||||||
let url = "/tags";
|
let url;
|
||||||
if (this.get("currentCategory")) {
|
|
||||||
url += this.get("currentCategory.url");
|
if (tagId === "all-tags") {
|
||||||
|
url = Discourse.getURL(this.get("allTagsUrl"));
|
||||||
|
} else if (tagId === "no-tags") {
|
||||||
|
url = Discourse.getURL(this.get("noTagsUrl"));
|
||||||
|
} else {
|
||||||
|
url = "/tags";
|
||||||
|
if (this.get("currentCategory")) {
|
||||||
|
url += this.get("currentCategory.url");
|
||||||
|
}
|
||||||
|
url = Discourse.getURL(`${url}/${tagId.toLowerCase()}`);
|
||||||
}
|
}
|
||||||
url = `${url}/${tagId.toLowerCase()}`;
|
|
||||||
DiscourseURL.routeTo(url);
|
DiscourseURL.routeTo(url);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
@import "common/select-kit/pinned-button";
|
@import "common/select-kit/pinned-button";
|
||||||
@import "common/select-kit/select-kit";
|
@import "common/select-kit/select-kit";
|
||||||
@import "common/select-kit/tag-chooser";
|
@import "common/select-kit/tag-chooser";
|
||||||
|
@import "common/select-kit/tag-drop";
|
||||||
@import "common/select-kit/toolbar-popup-menu-options";
|
@import "common/select-kit/toolbar-popup-menu-options";
|
||||||
@import "common/select-kit/topic-notifications-button";
|
@import "common/select-kit/topic-notifications-button";
|
||||||
@import "common/components/*";
|
@import "common/components/*";
|
||||||
|
|
|
@ -42,6 +42,12 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
||||||
|
&[data-value="all-categories"],
|
||||||
|
&[data-value="no-categories"] {
|
||||||
|
color: $tertiary;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
.category-desc {
|
.category-desc {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
color: $primary-medium;
|
color: $primary-medium;
|
||||||
|
|
13
app/assets/stylesheets/common/select-kit/tag-drop.scss
Normal file
13
app/assets/stylesheets/common/select-kit/tag-drop.scss
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
.select-kit {
|
||||||
|
&.combo-box {
|
||||||
|
&.tag-drop {
|
||||||
|
.select-kit-row {
|
||||||
|
&[data-value="all-tags"],
|
||||||
|
&[data-value="no-tags"] {
|
||||||
|
color: $tertiary;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -887,3 +887,26 @@ componentTest("onDeselect", {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
componentTest("noopRow", {
|
||||||
|
template: "{{single-select value=value content=content}}",
|
||||||
|
|
||||||
|
beforeEach() {
|
||||||
|
this.set("value", "blue");
|
||||||
|
this.set("content", [
|
||||||
|
{ id: "red", name: "Red", __sk_row_type: "noopRow" },
|
||||||
|
"blue",
|
||||||
|
"green"
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
async test(assert) {
|
||||||
|
await this.get("subject").expand();
|
||||||
|
await this.get("subject").selectRowByValue("red");
|
||||||
|
assert.equal(this.get("value"), "blue", "it doesn’t change the value");
|
||||||
|
|
||||||
|
await this.get("subject").expand();
|
||||||
|
await this.get("subject").selectRowByValue("green");
|
||||||
|
assert.equal(this.get("value"), "green");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -42,7 +42,7 @@ componentTest("default", {
|
||||||
|
|
||||||
assert.equal(
|
assert.equal(
|
||||||
this.get("subject")
|
this.get("subject")
|
||||||
.rowByIndex(0)
|
.rowByIndex(1)
|
||||||
.name(),
|
.name(),
|
||||||
"jeff",
|
"jeff",
|
||||||
"it has the correct tag"
|
"it has the correct tag"
|
||||||
|
@ -50,7 +50,7 @@ componentTest("default", {
|
||||||
|
|
||||||
assert.equal(
|
assert.equal(
|
||||||
this.get("subject")
|
this.get("subject")
|
||||||
.rowByIndex(1)
|
.rowByIndex(2)
|
||||||
.name(),
|
.name(),
|
||||||
"neil",
|
"neil",
|
||||||
"it has the correct tag"
|
"it has the correct tag"
|
||||||
|
@ -68,7 +68,7 @@ componentTest("default", {
|
||||||
await this.get("subject").fillInFilter("");
|
await this.get("subject").fillInFilter("");
|
||||||
assert.equal(
|
assert.equal(
|
||||||
this.get("subject")
|
this.get("subject")
|
||||||
.rowByIndex(0)
|
.rowByIndex(1)
|
||||||
.name(),
|
.name(),
|
||||||
"jeff",
|
"jeff",
|
||||||
"it returns top tags for an empty search"
|
"it returns top tags for an empty search"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user