BUGFIX/FEATURE: call out context for search.

This commit is contained in:
Sam
2014-06-17 17:53:45 +10:00
parent d85d34bac8
commit a288ff331d
8 changed files with 59 additions and 79 deletions

View File

@ -9,9 +9,32 @@
export default Em.ArrayController.extend(Discourse.Presence, { export default Em.ArrayController.extend(Discourse.Presence, {
contextChanged: function(){ contextChanged: function(){
this.setProperties({ term: "", content: [], resultCount: 0, urls: [] }); if(this.get('searchContextEnabled')){
this._dontSearch = true;
this.set('searchContextEnabled', false);
this._dontSearch = false;
}
}.observes("searchContext"), }.observes("searchContext"),
searchContextDescription: function(){
var ctx = this.get('searchContext');
if (ctx) {
switch(Em.get(ctx, 'type')) {
case 'topic':
return I18n.t('search.context.topic');
case 'user':
return I18n.t('search.context.user', {username: Em.get(ctx, 'user.username')});
case 'category':
return I18n.t('search.context.category', {category: Em.get(ctx, 'category.name')});
}
}
}.property('searchContext'),
searchContextEnabledChanged: function(){
if(this._dontSearch){ return; }
this.newSearchNeeded();
}.observes('searchContextEnabled'),
// If we need to perform another search // If we need to perform another search
newSearchNeeded: function() { newSearchNeeded: function() {
this.set('noResults', false); this.set('noResults', false);
@ -29,9 +52,14 @@ export default Em.ArrayController.extend(Discourse.Presence, {
var self = this; var self = this;
this.setProperties({ resultCount: 0, urls: [] }); this.setProperties({ resultCount: 0, urls: [] });
var context;
if(this.get('searchContextEnabled')){
context = this.get('searchContext');
}
return Discourse.Search.forTerm(term, { return Discourse.Search.forTerm(term, {
typeFilter: typeFilter, typeFilter: typeFilter,
searchContext: this.get('searchContext') searchContext: context
}).then(function(results) { }).then(function(results) {
var urls = []; var urls = [];
if (results) { if (results) {

View File

@ -1,5 +1,14 @@
{{view 'search-text-field' value=term searchContext=searchContext id="search-term"}} {{view 'search-text-field' value=term searchContextEnabled=searchContextEnabled searchContext=searchContext id="search-term"}}
{{#unless loading}} {{#if searchContext}}
<div>
<label>
{{input type="checkbox" name="searchContext" checked=searchContextEnabled}} {{searchContextDescription}}
</label>
</div>
{{/if}}
{{#if loading}}
<div class='searching'></div>
{{else}}
{{#unless noResults}} {{#unless noResults}}
{{#each resultType in content}} {{#each resultType in content}}
<ul> <ul>
@ -21,6 +30,4 @@
{{i18n search.no_results}} {{i18n search.no_results}}
</div> </div>
{{/unless}} {{/unless}}
{{else}} {{/if}}
<div class='searching'><i class='fa fa-spinner fa-spin'></i></div>
{{/unless}}

View File

@ -18,16 +18,10 @@ export default TextField.extend({
**/ **/
placeholder: function() { placeholder: function() {
var ctx = this.get('searchContext'); if(this.get('searchContextEnabled')){
if (ctx) { return "";
switch(Em.get(ctx, 'type')) {
case 'user':
return I18n.t('search.prefer.user', {username: Em.get(ctx, 'user.username')});
case 'category':
return I18n.t('search.prefer.category', {category: Em.get(ctx, 'category.name')});
}
} }
return I18n.t('search.title'); return I18n.t('search.title');
}.property('searchContext') }.property('searchContextEnabled')
}); });

View File

@ -649,9 +649,10 @@ en:
no_results: "No results found." no_results: "No results found."
searching: "Searching ..." searching: "Searching ..."
prefer: context:
user: "search will prefer results by @{{username}}" user: "Search posts by @{{username}}"
category: "search will prefer results in {{category}}" category: "Search the \"{{category}}\" category"
topic: "Search this topic"
site_map: "go to another topic list or category" site_map: "go to another topic list or category"
go_back: 'go back' go_back: 'go back'

View File

@ -76,8 +76,10 @@ class Search
send("#{@results.type_filter}_search") send("#{@results.type_filter}_search")
else else
@limit = Search.per_facet + 1 @limit = Search.per_facet + 1
user_search unless @search_context
category_search user_search
category_search
end
topic_search topic_search
end end
@ -161,14 +163,12 @@ class Search
if @search_context.present? if @search_context.present?
if @search_context.is_a?(User) if @search_context.is_a?(User)
# If the context is a user, prioritize that user's posts posts = posts.where("posts.user_id = #{@search_context.id}")
posts = posts.order("CASE WHEN posts.user_id = #{@search_context.id} THEN 0 ELSE 1 END")
elsif @search_context.is_a?(Category) elsif @search_context.is_a?(Category)
# If the context is a category, restrict posts to that category posts = posts.where("topics.category_id = #{@search_context.id}")
posts = posts.order("CASE WHEN topics.category_id = #{@search_context.id} THEN 0 ELSE 1 END")
elsif @search_context.is_a?(Topic) elsif @search_context.is_a?(Topic)
posts = posts.order("CASE WHEN topics.id = #{@search_context.id} THEN 0 ELSE 1 END, posts = posts.where("topics.id = #{@search_context.id}")
CASE WHEN topics.id = #{@search_context.id} THEN posts.post_number ELSE 999999 END") .order("posts.post_number")
end end
end end

View File

@ -162,8 +162,7 @@ describe Search do
post1.topic_id, post1.topic_id,
"_#{post2.id}", "_#{post2.id}",
"_#{post3.id}", "_#{post3.id}",
"_#{post4.id}", "_#{post4.id}"]
topic2.id]
end end
end end
@ -312,8 +311,6 @@ describe Search do
# should find topic created by searched user first # should find topic created by searched user first
Then { first_of_type(search_user, 'topic')[:id].should == post.topic_id } Then { first_of_type(search_user, 'topic')[:id].should == post.topic_id }
# results should also include topic by coding_horror
And { result_ids_for_type(search_user, 'topic').should include coding_horror_post.topic_id }
end end
context 'category as a search context' do context 'category as a search context' do
@ -326,9 +323,6 @@ describe Search do
When(:search_cat) { Search.new('hello', search_context: category).execute } When(:search_cat) { Search.new('hello', search_context: category).execute }
# should find topic in searched category first # should find topic in searched category first
Then { first_of_type(search_cat, 'topic')[:id].should == topic.id } Then { first_of_type(search_cat, 'topic')[:id].should == topic.id }
# results should also include topic without category
And { result_ids_for_type(search_cat, 'topic').should include topic_no_cat.id }
end end
end end

View File

@ -235,6 +235,7 @@ test("selecting a highlighted item", function() {
test("search query / the flow of the search", function() { test("search query / the flow of the search", function() {
Ember.run(function() { Ember.run(function() {
controller.set("searchContext", "context"); controller.set("searchContext", "context");
controller.set("searchContextEnabled", true);
controller.set("term", "ab"); controller.set("term", "ab");
}); });
ok(Discourse.Search.forTerm.calledWithExactly( ok(Discourse.Search.forTerm.calledWithExactly(

View File

@ -1,45 +0,0 @@
var view;
var placeholderUsesKeyAndContext = function(key, context) {
var placeholder = view.get("placeholder");
equal(placeholder.key, key, "placeholder contains correct message");
deepEqual(placeholder.context, context, "correct parameters are passed to the message");
};
module("view:search-text-field", {
setup: function() {
sinon.stub(I18n, "t", function(key, context) {
return {key: key, context: context};
});
view = viewClassFor('search-text-field').create();
},
teardown: function() {
I18n.t.restore();
}
});
test("formats placeholder correctly when no searchContext is provided", function() {
placeholderUsesKeyAndContext("search.title", undefined);
});
test("formats placeholder correctly when user searchContext is provided", function() {
view.set("searchContext", {
type: "user",
user: {
username: "userName"
}
});
placeholderUsesKeyAndContext("search.prefer.user", {username: "userName"});
});
test("formats placeholder correctly when category searchContext is provided", function() {
view.set("searchContext", {
type: "category",
category: {
name: "categoryName"
}
});
placeholderUsesKeyAndContext("search.prefer.category", {category: "categoryName"});
});