FEATURE: Category filtering
This commit is contained in:
parent
42ac7bb984
commit
10ec8b47a8
|
@ -0,0 +1,12 @@
|
||||||
|
import { default as computed } from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
@computed("category")
|
||||||
|
categoryName(category) {
|
||||||
|
return this.site.categories.findBy("id", category.id).name;
|
||||||
|
},
|
||||||
|
click() {
|
||||||
|
this.selectCategory(this.category);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
|
@ -16,7 +16,7 @@ function mergeCategories(results) {
|
||||||
export default Ember.Controller.extend({
|
export default Ember.Controller.extend({
|
||||||
application: Ember.inject.controller(),
|
application: Ember.inject.controller(),
|
||||||
queryParams: {
|
queryParams: {
|
||||||
filterCategory: "category",
|
filterCategories: "category",
|
||||||
filterTags: "tags",
|
filterTags: "tags",
|
||||||
searchTerm: "search",
|
searchTerm: "search",
|
||||||
selectedTopic: "topic"
|
selectedTopic: "topic"
|
||||||
|
@ -25,10 +25,11 @@ export default Ember.Controller.extend({
|
||||||
isLoadingMore: false,
|
isLoadingMore: false,
|
||||||
loadMoreUrl: Ember.computed.alias("model.topics.load_more_url"),
|
loadMoreUrl: Ember.computed.alias("model.topics.load_more_url"),
|
||||||
isTopicLoading: false,
|
isTopicLoading: false,
|
||||||
|
categories: Ember.computed.readOnly("model.categories"),
|
||||||
topics: Ember.computed.alias("model.topics.topic_list.topics"),
|
topics: Ember.computed.alias("model.topics.topic_list.topics"),
|
||||||
tags: Ember.computed.readOnly("model.tags"),
|
tags: Ember.computed.readOnly("model.tags"),
|
||||||
filterTags: null,
|
filterTags: null,
|
||||||
filterCategory: null,
|
filterCategories: null,
|
||||||
searchTerm: null,
|
searchTerm: null,
|
||||||
selectedTopic: null,
|
selectedTopic: null,
|
||||||
topic: null,
|
topic: null,
|
||||||
|
@ -93,6 +94,26 @@ export default Ember.Controller.extend({
|
||||||
|
|
||||||
this.send("refreshModel");
|
this.send("refreshModel");
|
||||||
},
|
},
|
||||||
|
updateSelectedCategories(category) {
|
||||||
|
let filter = this.filterCategories;
|
||||||
|
if (filter && filter.includes(category.id)) {
|
||||||
|
filter = filter
|
||||||
|
.replace(category.id, "")
|
||||||
|
.replace("|", "|")
|
||||||
|
.replace(/^\|+|\|+$/g, "");
|
||||||
|
} else if (filter) {
|
||||||
|
filter = `${filter}|${category.id}`;
|
||||||
|
} else {
|
||||||
|
filter = category.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setProperties({
|
||||||
|
filterCategories: filter,
|
||||||
|
selectedTopic: null
|
||||||
|
});
|
||||||
|
|
||||||
|
this.send("refreshModel");
|
||||||
|
},
|
||||||
|
|
||||||
performSearch(term) {
|
performSearch(term) {
|
||||||
if (term === "") {
|
if (term === "") {
|
||||||
|
@ -134,7 +155,7 @@ export default Ember.Controller.extend({
|
||||||
this.set("isLoading", true);
|
this.set("isLoading", true);
|
||||||
|
|
||||||
const params = this.getProperties(
|
const params = this.getProperties(
|
||||||
"filterCategory",
|
"filterCategories",
|
||||||
"filterTags",
|
"filterTags",
|
||||||
"searchTerm"
|
"searchTerm"
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,6 +3,8 @@ import { ajax } from "discourse/lib/ajax";
|
||||||
export default {
|
export default {
|
||||||
list(params) {
|
list(params) {
|
||||||
let filters = [];
|
let filters = [];
|
||||||
|
if (params.filterCategories)
|
||||||
|
filters.push(`category=${params.filterCategories}`);
|
||||||
if (params.filterTags) filters.push(`tags=${params.filterTags}`);
|
if (params.filterTags) filters.push(`tags=${params.filterTags}`);
|
||||||
if (params.searchTerm) filters.push(`search=${params.searchTerm}`);
|
if (params.searchTerm) filters.push(`search=${params.searchTerm}`);
|
||||||
if (params.page) filters.push(`page=${params.page}`);
|
if (params.page) filters.push(`page=${params.page}`);
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<div class="knowledge-explorer-category {{if category.active 'selected'}}">
|
||||||
|
{{#unless category.active}}
|
||||||
|
{{d-icon "plus"}}
|
||||||
|
{{/unless}}
|
||||||
|
<span class="category-id">{{categoryName}}</span>
|
||||||
|
<span class="category-count">({{category.count}})</span>
|
||||||
|
{{#if category.active}}
|
||||||
|
{{d-icon "times-circle"}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
|
@ -5,7 +5,18 @@
|
||||||
}}
|
}}
|
||||||
{{#conditional-loading-spinner condition=isLoading}}
|
{{#conditional-loading-spinner condition=isLoading}}
|
||||||
<div class="knowledge-explorer-browse">
|
<div class="knowledge-explorer-browse">
|
||||||
|
<div class="knowledge-explorer-filters">
|
||||||
|
<div class="knowledge-explorer-categories">
|
||||||
|
<h3>{{i18n 'knowledge_explorer.categories'}}</h3>
|
||||||
|
{{#each categories as |category|}}
|
||||||
|
{{knowledge-explorer-category
|
||||||
|
category=category
|
||||||
|
selectCategory=(action "updateSelectedCategories")
|
||||||
|
}}
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
<div class="knowledge-explorer-tags">
|
<div class="knowledge-explorer-tags">
|
||||||
|
<h3>{{i18n 'knowledge_explorer.tags'}}</h3>
|
||||||
{{#each tags as |tag|}}
|
{{#each tags as |tag|}}
|
||||||
{{knowledge-explorer-tag
|
{{knowledge-explorer-tag
|
||||||
tag=tag
|
tag=tag
|
||||||
|
@ -13,6 +24,7 @@
|
||||||
}}
|
}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{{#if selectedTopic}}
|
{{#if selectedTopic}}
|
||||||
{{#conditional-loading-spinner condition=isTopicLoading}}
|
{{#conditional-loading-spinner condition=isTopicLoading}}
|
||||||
{{knowledge-explorer-topic topic=topic}}
|
{{knowledge-explorer-topic topic=topic}}
|
||||||
|
|
|
@ -28,13 +28,15 @@
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.knowledge-explorer-tags {
|
.knowledge-explorer-filters {
|
||||||
flex-basis: 25%;
|
flex-basis: 25%;
|
||||||
|
}
|
||||||
|
.knowledge-explorer-tags, .knowledge-explorer-categories {
|
||||||
padding: 10px 10px 10px 0;
|
padding: 10px 10px 10px 0;
|
||||||
a {
|
a {
|
||||||
color: $primary;
|
color: $primary;
|
||||||
}
|
}
|
||||||
.knowledge-explorer-tag {
|
.knowledge-explorer-tag, .knowledge-explorer-category {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
|
@ -2,6 +2,8 @@ en:
|
||||||
js:
|
js:
|
||||||
knowledge_explorer:
|
knowledge_explorer:
|
||||||
title: "Knowledge Explorer"
|
title: "Knowledge Explorer"
|
||||||
|
categories: "Categories"
|
||||||
|
tags: "Tags"
|
||||||
search:
|
search:
|
||||||
results:
|
results:
|
||||||
one: "%{count} result found"
|
one: "%{count} result found"
|
||||||
|
|
|
@ -25,7 +25,7 @@ module KnowledgeExplorer
|
||||||
|
|
||||||
# filter results by selected category
|
# filter results by selected category
|
||||||
if @filters[:category].present?
|
if @filters[:category].present?
|
||||||
results = results.where('category_id IN (?)', @filters[:category])
|
results = results.where('category_id IN (?)', @filters[:category].split('|'))
|
||||||
end
|
end
|
||||||
|
|
||||||
# filter results by selected tags
|
# filter results by selected tags
|
||||||
|
@ -50,6 +50,7 @@ module KnowledgeExplorer
|
||||||
end
|
end
|
||||||
|
|
||||||
tags = tag_count(results)
|
tags = tag_count(results)
|
||||||
|
categories = categories_count(results)
|
||||||
|
|
||||||
results_length = results.length
|
results_length = results.length
|
||||||
|
|
||||||
|
@ -75,7 +76,7 @@ module KnowledgeExplorer
|
||||||
topic_list['load_more_url'] = nil
|
topic_list['load_more_url'] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
{ tags: tags, topics: topic_list }
|
{ tags: tags, categories: categories, topics: topic_list }
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag_count(results)
|
def tag_count(results)
|
||||||
|
@ -96,6 +97,22 @@ module KnowledgeExplorer
|
||||||
tags.sort_by { |tag| [tag[:active] ? 0 : 1, -tag[:count]] }
|
tags.sort_by { |tag| [tag[:active] ? 0 : 1, -tag[:count]] }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def categories_count(results)
|
||||||
|
categories = []
|
||||||
|
|
||||||
|
results.each do |topic|
|
||||||
|
active = @filters[:category].include?(topic.category_id.to_s) if @filters[:category]
|
||||||
|
if categories.none? { |item| item[:id] == topic.category_id }
|
||||||
|
categories << { id: topic.category_id, count: 1, active: active || false }
|
||||||
|
else
|
||||||
|
category_index = categories.index(categories.find { |item| item[:id] == topic.category_id })
|
||||||
|
categories[category_index][:count] += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
categories.sort_by { |category| [category[:active] ? 0 : 1, -category[:count]] }
|
||||||
|
end
|
||||||
|
|
||||||
def load_more_url
|
def load_more_url
|
||||||
filters = []
|
filters = []
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ describe KnowledgeExplorer::KnowledgeExplorerController do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when filtering by tag' do
|
context 'when filtering by tag' do
|
||||||
it 'should return a filtered list' do
|
it 'should return a list filtered by tag' do
|
||||||
get '/knowledge-explorer.json?tags=test'
|
get '/knowledge-explorer.json?tags=test'
|
||||||
|
|
||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
|
@ -76,5 +76,40 @@ describe KnowledgeExplorer::KnowledgeExplorerController do
|
||||||
expect(topics.size).to eq(1)
|
expect(topics.size).to eq(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when filtering by category' do
|
||||||
|
let!(:category2) { Fabricate(:category) }
|
||||||
|
let!(:topic3) { Fabricate(:topic, category: category2) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
SiteSetting.knowledge_explorer_categories = "#{category.id}|#{category2.id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should return a list filtered by category' do
|
||||||
|
get "/knowledge-explorer.json?category=#{category2.id}"
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
|
||||||
|
json = JSON.parse(response.body)
|
||||||
|
categories = json['categories']
|
||||||
|
topics = json['topics']['topic_list']['topics']
|
||||||
|
|
||||||
|
expect(categories.size).to eq(1)
|
||||||
|
expect(topics.size).to eq(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when searching' do
|
||||||
|
it 'should return a list filtered by search term in title' do
|
||||||
|
get "/knowledge-explorer.json?search=topic 1"
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
|
||||||
|
json = JSON.parse(response.body)
|
||||||
|
topics = json['topics']['topic_list']['topics']
|
||||||
|
|
||||||
|
expect(topics.size).to eq(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue