DEV: Add plugin API to extend search results (#12966)
This commit is contained in:
parent
9190e4390f
commit
ff4fb9c771
|
@ -20,7 +20,7 @@ export default DiscourseRoute.extend({
|
||||||
search_type: params.searchType,
|
search_type: params.searchType,
|
||||||
term: params.term,
|
term: params.term,
|
||||||
},
|
},
|
||||||
}).then((json) => {
|
}).then(async (json) => {
|
||||||
// Add zero values for missing dates
|
// Add zero values for missing dates
|
||||||
if (json.term.data.length > 0) {
|
if (json.term.data.length > 0) {
|
||||||
const startDate =
|
const startDate =
|
||||||
|
@ -31,7 +31,9 @@ export default DiscourseRoute.extend({
|
||||||
json.term.data = fillMissingDates(json.term.data, startDate, endDate);
|
json.term.data = fillMissingDates(json.term.data, startDate, endDate);
|
||||||
}
|
}
|
||||||
if (json.term.search_result) {
|
if (json.term.search_result) {
|
||||||
json.term.search_result = translateResults(json.term.search_result);
|
json.term.search_result = await translateResults(
|
||||||
|
json.term.search_result
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const model = EmberObject.create({ type: "search_log_term" });
|
const model = EmberObject.create({ type: "search_log_term" });
|
||||||
|
|
|
@ -245,8 +245,8 @@ export default Controller.extend({
|
||||||
const searchKey = getSearchKey(args);
|
const searchKey = getSearchKey(args);
|
||||||
|
|
||||||
ajax("/search", { data: args })
|
ajax("/search", { data: args })
|
||||||
.then((results) => {
|
.then(async (results) => {
|
||||||
const model = translateResults(results) || {};
|
const model = (await translateResults(results)) || {};
|
||||||
|
|
||||||
if (results.grouped_search_result) {
|
if (results.grouped_search_result) {
|
||||||
this.set("q", results.grouped_search_result.term);
|
this.set("q", results.grouped_search_result.term);
|
||||||
|
|
|
@ -72,9 +72,10 @@ import { registerTopicFooterButton } from "discourse/lib/register-topic-footer-b
|
||||||
import { replaceFormatter } from "discourse/lib/utilities";
|
import { replaceFormatter } from "discourse/lib/utilities";
|
||||||
import { replaceTagRenderer } from "discourse/lib/render-tag";
|
import { replaceTagRenderer } from "discourse/lib/render-tag";
|
||||||
import { setNewCategoryDefaultColors } from "discourse/routes/new-category";
|
import { setNewCategoryDefaultColors } from "discourse/routes/new-category";
|
||||||
|
import { addSearchResultsCallback } from "discourse/lib/search";
|
||||||
|
|
||||||
// If you add any methods to the API ensure you bump up this number
|
// If you add any methods to the API ensure you bump up this number
|
||||||
const PLUGIN_API_VERSION = "0.11.4";
|
const PLUGIN_API_VERSION = "0.11.5";
|
||||||
|
|
||||||
class PluginApi {
|
class PluginApi {
|
||||||
constructor(version, container) {
|
constructor(version, container) {
|
||||||
|
@ -1281,6 +1282,21 @@ class PluginApi {
|
||||||
setNewCategoryDefaultColors(backgroundColor, textColor) {
|
setNewCategoryDefaultColors(backgroundColor, textColor) {
|
||||||
setNewCategoryDefaultColors(backgroundColor, textColor);
|
setNewCategoryDefaultColors(backgroundColor, textColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to modify search results before displaying them.
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* api.addSearchResultsCallback((results) => {
|
||||||
|
* results.topics.push(Topic.create({ ... }));
|
||||||
|
* return results;
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
addSearchResultsCallback(callback) {
|
||||||
|
addSearchResultsCallback(callback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// from http://stackoverflow.com/questions/6832596/how-to-compare-software-version-number-using-js-only-number
|
// from http://stackoverflow.com/questions/6832596/how-to-compare-software-version-number-using-js-only-number
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import Category from "discourse/models/category";
|
import Category from "discourse/models/category";
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
import { Promise } from "rsvp";
|
||||||
import Post from "discourse/models/post";
|
import Post from "discourse/models/post";
|
||||||
import Topic from "discourse/models/topic";
|
import Topic from "discourse/models/topic";
|
||||||
import User from "discourse/models/user";
|
import User from "discourse/models/user";
|
||||||
|
@ -15,6 +16,12 @@ import { search as searchCategoryTag } from "discourse/lib/category-tag-search";
|
||||||
import { userPath } from "discourse/lib/url";
|
import { userPath } from "discourse/lib/url";
|
||||||
import userSearch from "discourse/lib/user-search";
|
import userSearch from "discourse/lib/user-search";
|
||||||
|
|
||||||
|
const translateResultsCallbacks = [];
|
||||||
|
|
||||||
|
export function addSearchResultsCallback(callback) {
|
||||||
|
translateResultsCallbacks.push(callback);
|
||||||
|
}
|
||||||
|
|
||||||
export function translateResults(results, opts) {
|
export function translateResults(results, opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
|
||||||
|
@ -84,9 +91,29 @@ export function translateResults(results, opts) {
|
||||||
})
|
})
|
||||||
.compact();
|
.compact();
|
||||||
|
|
||||||
results.resultTypes = [];
|
return translateResultsCallbacks
|
||||||
|
.reduce(
|
||||||
|
(promise, callback) => promise.then((r) => callback(r)),
|
||||||
|
Promise.resolve(results)
|
||||||
|
)
|
||||||
|
.then((results_) => {
|
||||||
|
translateGroupedSearchResults(results_, opts);
|
||||||
|
|
||||||
// TODO: consider refactoring front end to take a better structure
|
if (
|
||||||
|
!results_.topics.length &&
|
||||||
|
!results_.posts.length &&
|
||||||
|
!results_.users.length &&
|
||||||
|
!results_.categories.length
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EmberObject.create(results_);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function translateGroupedSearchResults(results, opts) {
|
||||||
|
results.resultTypes = [];
|
||||||
const groupedSearchResult = results.grouped_search_result;
|
const groupedSearchResult = results.grouped_search_result;
|
||||||
if (groupedSearchResult) {
|
if (groupedSearchResult) {
|
||||||
[
|
[
|
||||||
|
@ -121,15 +148,6 @@ export function translateResults(results, opts) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const noResults = !!(
|
|
||||||
!results.topics.length &&
|
|
||||||
!results.posts.length &&
|
|
||||||
!results.users.length &&
|
|
||||||
!results.categories.length
|
|
||||||
);
|
|
||||||
|
|
||||||
return noResults ? null : EmberObject.create(results);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function searchForTerm(term, opts) {
|
export function searchForTerm(term, opts) {
|
||||||
|
@ -157,12 +175,9 @@ export function searchForTerm(term, opts) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let promise = ajax("/search/query", { data: data });
|
let ajaxPromise = ajax("/search/query", { data });
|
||||||
|
const promise = ajaxPromise.then((res) => translateResults(res, opts));
|
||||||
promise.then((results) => {
|
promise.abort = ajaxPromise.abort;
|
||||||
return translateResults(results, opts);
|
|
||||||
});
|
|
||||||
|
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,11 +52,11 @@ export default DiscourseRoute.extend({
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}).then((results) => {
|
}).then(async (results) => {
|
||||||
const grouped_search_result = results
|
const grouped_search_result = results
|
||||||
? results.grouped_search_result
|
? results.grouped_search_result
|
||||||
: {};
|
: {};
|
||||||
const model = (results && translateResults(results)) || {
|
const model = (results && (await translateResults(results))) || {
|
||||||
grouped_search_result,
|
grouped_search_result,
|
||||||
};
|
};
|
||||||
setTransient("lastSearch", { searchKey, model }, 5);
|
setTransient("lastSearch", { searchKey, model }, 5);
|
||||||
|
|
|
@ -55,12 +55,12 @@ const SearchHelper = {
|
||||||
fullSearchUrl,
|
fullSearchUrl,
|
||||||
});
|
});
|
||||||
this._activeSearch
|
this._activeSearch
|
||||||
.then((content) => {
|
.then((results) => {
|
||||||
// we ensure the current search term is the one used
|
// we ensure the current search term is the one used
|
||||||
// when starting the query
|
// when starting the query
|
||||||
if (term === searchData.term) {
|
if (results && term === searchData.term) {
|
||||||
searchData.noResults = content.resultTypes.length === 0;
|
searchData.noResults = results.resultTypes.length === 0;
|
||||||
searchData.results = content;
|
searchData.results = results;
|
||||||
|
|
||||||
if (searchContext && searchContext.type === "topic") {
|
if (searchContext && searchContext.type === "topic") {
|
||||||
widget.appEvents.trigger("post-stream:refresh", { force: true });
|
widget.appEvents.trigger("post-stream:refresh", { force: true });
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
|
||||||
module("Unit | Utility | search", function () {
|
module("Unit | Utility | search", function () {
|
||||||
test("unescapesEmojisInBlurbs", function (assert) {
|
test("unescapesEmojisInBlurbs", async function (assert) {
|
||||||
const source = {
|
const source = {
|
||||||
posts: [
|
posts: [
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@ module("Unit | Utility | search", function () {
|
||||||
grouped_search_result: false,
|
grouped_search_result: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const results = translateResults(source);
|
const results = await translateResults(source);
|
||||||
const blurb = results.posts[0].get("blurb");
|
const blurb = results.posts[0].get("blurb");
|
||||||
|
|
||||||
assert.ok(blurb.indexOf("thinking.png"));
|
assert.ok(blurb.indexOf("thinking.png"));
|
||||||
|
|
|
@ -21,6 +21,10 @@ class SearchPostSerializer < BasicPostSerializer
|
||||||
options[:result].blurb(object)
|
options[:result].blurb(object)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def include_blurb?
|
||||||
|
options[:result].present?
|
||||||
|
end
|
||||||
|
|
||||||
def include_cooked?
|
def include_cooked?
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue