discourse/app/assets/javascripts/discourse/controllers/full-page-search.js.es6
2015-11-10 16:30:39 +01:00

206 lines
5.2 KiB
JavaScript

import { translateResults, searchContextDescription, getSearchKey, isValidSearchTerm } from "discourse/lib/search";
import showModal from 'discourse/lib/show-modal';
import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
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({
needs: ["application"],
loading: Em.computed.not("model"),
queryParams: ["q", "context_id", "context", "skip_context"],
q: null,
selected: [],
context_id: null,
context: null,
searching: false,
sortOrder: 0,
sortOrders: SortOrders,
@computed('model.posts')
resultCount(posts){
return posts && posts.length;
},
@computed('q')
hasAutofocus(q) {
return Em.isEmpty(q);
},
@computed('skip_context', 'context')
searchContextEnabled: {
get(skip,context){
return (!skip && context) || skip === "false";
},
set(val) {
this.set('skip_context', val ? "false" : "true" );
}
},
@computed('context', 'context_id')
searchContextDescription(context, id){
var name = id;
if (context === 'category') {
var category = Category.findById(id);
if (!category) {return;}
name = category.get('name');
}
return searchContextDescription(context, name);
},
@computed('q')
searchActive(q){
return isValidSearchTerm(q);
},
@computed('searchTerm', 'searching')
searchButtonDisabled(searchTerm, searching) {
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 Handlebars.Utils.escapeExpression(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')
modelChanged() {
if (this.get("searchTerm") !== this.get("q")) {
this.setSearchTerm(this.get("q"));
}
},
@computed('q')
showLikeCount(q) {
return q && q.indexOf("order:likes") > -1;
},
@observes('q')
qChanged() {
const model = this.get("model");
if (model && this.get("model.q") !== this.get("q")) {
this.setSearchTerm(this.get("q"));
this.send("search");
}
},
@observes('loading')
_showFooter() {
this.set("controllers.application.showFooter", !this.get("loading"));
},
canBulkSelect: Em.computed.alias('currentUser.staff'),
search(){
if (this.get("searching")) return;
this.set("searching", true);
const router = Discourse.__container__.lookup('router:main');
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");
if ((!skip && this.get('context')) || skip==="false"){
args.search_context = {
type: this.get('context'),
id: this.get('context_id')
};
}
const searchKey = getSearchKey(args);
Discourse.ajax("/search", { data: args }).then(results => {
const model = translateResults(results) || {};
router.transientCache('lastSearch', { searchKey, model }, 5);
this.set("model", model);
}).finally(() => { this.set("searching",false); });
},
actions: {
selectAll() {
this.get('selected').addObjects(this.get('model.posts').map(r => r.topic));
// Doing this the proper way is a HUGE pain,
// we can hack this to work by observing each on the array
// in the component, however, when we select ANYTHING, we would force
// 50 traversals of the list
// This hack is cheap and easy
$('.fps-result input[type=checkbox]').prop('checked', true);
},
clearAll() {
this.get('selected').clear();
$('.fps-result input[type=checkbox]').prop('checked', false);
},
toggleBulkSelect() {
this.toggleProperty('bulkSelectEnabled');
this.get('selected').clear();
},
refresh() {
this.set('bulkSelectEnabled', false);
this.get('selected').clear();
this.search();
},
showSearchHelp() {
// TODO: dupe code should be centralized
Discourse.ajax("/static/search_help.html", { dataType: 'html' }).then((model) => {
showModal('searchHelp', { model });
});
},
search() {
if (this.get("searchButtonDisabled")) return;
this.search();
}
}
});