mirror of
https://github.com/discourse/discourse.git
synced 2025-05-22 07:53:49 +08:00
BUGFIX/FEATURE: call out context for search.
This commit is contained in:
@ -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) {
|
||||||
|
@ -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}}
|
|
||||||
|
@ -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')
|
||||||
});
|
});
|
||||||
|
@ -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'
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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(
|
||||||
|
@ -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"});
|
|
||||||
});
|
|
Reference in New Issue
Block a user