mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-12-03 12:27:35 -05:00
206 lines
5.2 KiB
JavaScript
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();
|
|
}
|
|
}
|
|
});
|