mirror of
https://github.com/discourse/discourse.git
synced 2025-09-06 10:50:21 +08:00
FEATURE: ui for ordering search results in full page mode
This commit is contained in:
parent
d97e78b942
commit
a4ace3f08e
5 changed files with 139 additions and 5 deletions
|
@ -3,6 +3,13 @@ import showModal from 'discourse/lib/show-modal';
|
||||||
import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
|
import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
|
||||||
import Category from 'discourse/models/category';
|
import Category from 'discourse/models/category';
|
||||||
|
|
||||||
|
const SortOrders = [
|
||||||
|
{name: I18n.t('search.relevance'), id: 0},
|
||||||
|
{name: I18n.t('search.latest_post'), id: 1, term: 'order:latest'},
|
||||||
|
{name: I18n.t('search.most_liked'), id: 2, term: 'order:likes'},
|
||||||
|
{name: I18n.t('search.most_viewed'), id: 3, term: 'order:views'},
|
||||||
|
];
|
||||||
|
|
||||||
export default Ember.Controller.extend({
|
export default Ember.Controller.extend({
|
||||||
needs: ["application"],
|
needs: ["application"],
|
||||||
|
|
||||||
|
@ -13,6 +20,13 @@ export default Ember.Controller.extend({
|
||||||
context_id: null,
|
context_id: null,
|
||||||
context: null,
|
context: null,
|
||||||
searching: false,
|
searching: false,
|
||||||
|
sortOrder: 0,
|
||||||
|
sortOrders: SortOrders,
|
||||||
|
|
||||||
|
@computed('model.posts')
|
||||||
|
resultCount(posts){
|
||||||
|
return posts && posts.length;
|
||||||
|
},
|
||||||
|
|
||||||
@computed('q')
|
@computed('q')
|
||||||
hasAutofocus(q) {
|
hasAutofocus(q) {
|
||||||
|
@ -51,18 +65,61 @@ export default Ember.Controller.extend({
|
||||||
return !!(searching || !isValidSearchTerm(searchTerm));
|
return !!(searching || !isValidSearchTerm(searchTerm));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@computed('q')
|
||||||
|
noSortQ(q) {
|
||||||
|
if (q) {
|
||||||
|
SortOrders.forEach((order) => {
|
||||||
|
if (q.indexOf(order.term) > -1){
|
||||||
|
q = q.replace(order.term, "");
|
||||||
|
q = q.trim();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return q;
|
||||||
|
},
|
||||||
|
|
||||||
|
_searchOnSortChange: true,
|
||||||
|
|
||||||
|
setSearchTerm(term) {
|
||||||
|
this._searchOnSortChange = false;
|
||||||
|
if (term) {
|
||||||
|
SortOrders.forEach((order) => {
|
||||||
|
if (term.indexOf(order.term) > -1){
|
||||||
|
this.set('sortOrder', order.id);
|
||||||
|
term = term.replace(order.term, "");
|
||||||
|
term = term.trim();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this._searchOnSortChange = true;
|
||||||
|
this.set('searchTerm', term);
|
||||||
|
},
|
||||||
|
|
||||||
|
@observes('sortOrder')
|
||||||
|
triggerSearch(){
|
||||||
|
if (this._searchOnSortChange) {
|
||||||
|
this.search();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
@observes('model')
|
@observes('model')
|
||||||
modelChanged() {
|
modelChanged() {
|
||||||
if (this.get("searchTerm") !== this.get("q")) {
|
if (this.get("searchTerm") !== this.get("q")) {
|
||||||
this.set("searchTerm", this.get("q"));
|
this.setSearchTerm(this.get("q"));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@computed('q')
|
||||||
|
showLikeCount(q) {
|
||||||
|
console.log(q);
|
||||||
|
return q && q.indexOf("order:likes") > -1;
|
||||||
|
},
|
||||||
|
|
||||||
@observes('q')
|
@observes('q')
|
||||||
qChanged() {
|
qChanged() {
|
||||||
const model = this.get("model");
|
const model = this.get("model");
|
||||||
if (model && this.get("model.q") !== this.get("q")) {
|
if (model && this.get("model.q") !== this.get("q")) {
|
||||||
this.set("searchTerm", this.get("q"));
|
this.setSearchTerm(this.get("q"));
|
||||||
this.send("search");
|
this.send("search");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -80,11 +137,16 @@ export default Ember.Controller.extend({
|
||||||
|
|
||||||
const router = Discourse.__container__.lookup('router:main');
|
const router = Discourse.__container__.lookup('router:main');
|
||||||
|
|
||||||
this.set("q", this.get("searchTerm"));
|
|
||||||
this.set("model", null);
|
|
||||||
|
|
||||||
var args = { q: this.get("searchTerm") };
|
var args = { q: this.get("searchTerm") };
|
||||||
|
|
||||||
|
const sortOrder = this.get("sortOrder");
|
||||||
|
if (sortOrder && SortOrders[sortOrder].term) {
|
||||||
|
args.q += " " + SortOrders[sortOrder].term;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.set("q", args.q);
|
||||||
|
this.set("model", null);
|
||||||
|
|
||||||
const skip = this.get("skip_context");
|
const skip = this.get("skip_context");
|
||||||
if ((!skip && this.get('context')) || skip==="false"){
|
if ((!skip && this.get('context')) || skip==="false"){
|
||||||
args.search_context = {
|
args.search_context = {
|
||||||
|
|
|
@ -37,6 +37,22 @@
|
||||||
</h3>
|
</h3>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
|
|
||||||
|
{{#if model.posts}}
|
||||||
|
<div class='search-title clearfix'>
|
||||||
|
<div class='result-count'>
|
||||||
|
<span>
|
||||||
|
{{{i18n "search.result_count" count=resultCount term=noSortQ}}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class='sort-by'>
|
||||||
|
<span class='desc'>
|
||||||
|
{{i18n "search.sort_by"}}
|
||||||
|
</span>
|
||||||
|
{{combo-box value=sortOrder content=sortOrders castInteger="true"}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{#each model.posts as |result|}}
|
{{#each model.posts as |result|}}
|
||||||
<div class='fps-result'>
|
<div class='fps-result'>
|
||||||
<div class='topic'>
|
<div class='topic'>
|
||||||
|
@ -65,6 +81,13 @@
|
||||||
{{/highlight-text}}
|
{{/highlight-text}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
{{#if showLikeCount}}
|
||||||
|
{{#if result.like_count}}
|
||||||
|
<span class='like-count'>
|
||||||
|
{{result.like_count}} <i class="icon fa fa-heart"></i>
|
||||||
|
</span>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
.fps-result {
|
.fps-result {
|
||||||
|
|
||||||
|
.like-count {
|
||||||
|
color: dark-light-choose(scale-color($primary, $lightness: 40%), scale-color($secondary, $lightness: 60%));
|
||||||
|
.fa { color: $love; font-size: 12px; }
|
||||||
|
}
|
||||||
|
|
||||||
.badge-wrapper span.badge-category {
|
.badge-wrapper span.badge-category {
|
||||||
max-width: inherit;
|
max-width: inherit;
|
||||||
}
|
}
|
||||||
|
@ -78,3 +83,37 @@
|
||||||
.panel-body-contents .search-context label {
|
.panel-body-contents .search-context label {
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-title {
|
||||||
|
|
||||||
|
.term {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
.result-count {
|
||||||
|
float: left;
|
||||||
|
span {
|
||||||
|
line-height: 28px;
|
||||||
|
height: 28px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
margin: 10px 0 15px;
|
||||||
|
max-width: 675px;
|
||||||
|
border-bottom: 3px solid dark-light-diff($primary, $secondary, 90%, -75%);
|
||||||
|
width: 100%;
|
||||||
|
.sort-by {
|
||||||
|
.desc {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
margin-bottom: 0;
|
||||||
|
width: auto;
|
||||||
|
min-width: 150px;
|
||||||
|
}
|
||||||
|
float: right;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ class SearchPostSerializer < PostSerializer
|
||||||
|
|
||||||
has_one :topic, serializer: TopicListItemSerializer
|
has_one :topic, serializer: TopicListItemSerializer
|
||||||
|
|
||||||
|
attributes :like_count
|
||||||
|
|
||||||
attributes :blurb
|
attributes :blurb
|
||||||
def blurb
|
def blurb
|
||||||
options[:result].blurb(object)
|
options[:result].blurb(object)
|
||||||
|
|
|
@ -968,8 +968,16 @@ en:
|
||||||
image_link: "link your image will point to"
|
image_link: "link your image will point to"
|
||||||
|
|
||||||
search:
|
search:
|
||||||
|
sort_by: "Sort by"
|
||||||
|
relevance: "Relevance"
|
||||||
|
latest_post: "Latest Post"
|
||||||
|
most_viewed: "Most Viewed"
|
||||||
|
most_liked: "Most Liked"
|
||||||
select_all: "Select All"
|
select_all: "Select All"
|
||||||
clear_all: "Clear All"
|
clear_all: "Clear All"
|
||||||
|
result_count:
|
||||||
|
one: "1 result for <span class='term'>\"{{term}}\"</span>"
|
||||||
|
other: "{{count}} results for <span class='term'>\"{{term}}\"</span>"
|
||||||
title: "search topics, posts, users, or categories"
|
title: "search topics, posts, users, or categories"
|
||||||
no_results: "No results found."
|
no_results: "No results found."
|
||||||
no_more_results: "No more results found."
|
no_more_results: "No more results found."
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue