mirror of
https://github.com/discourse/discourse.git
synced 2024-11-27 05:23:37 +08:00
DEV: Plugin outlets / extension points in search-menu (#21642)
This commit is contained in:
parent
bb21476f68
commit
c3a734380e
|
@ -95,9 +95,11 @@ import { replaceTagRenderer } from "discourse/lib/render-tag";
|
|||
import { registerCustomLastUnreadUrlCallback } from "discourse/models/topic";
|
||||
import { setNewCategoryDefaultColors } from "discourse/routes/new-category";
|
||||
import { addSearchResultsCallback } from "discourse/lib/search";
|
||||
import { addOnKeyDownCallback } from "discourse/widgets/search-menu";
|
||||
import {
|
||||
addQuickSearchRandomTip,
|
||||
addSearchSuggestion,
|
||||
removeDefaultQuickSearchRandomTips,
|
||||
} from "discourse/widgets/search-menu-results";
|
||||
import { CUSTOM_USER_SEARCH_OPTIONS } from "select-kit/components/user-chooser";
|
||||
import { downloadCalendar } from "discourse/lib/download-calendar";
|
||||
|
@ -1707,6 +1709,25 @@ class PluginApi {
|
|||
downloadCalendar(title, dates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a function to be called when there is a keyDown even on the search-menu widget.
|
||||
* This function runs before the default logic, and if one callback returns a falsey value
|
||||
* the logic chain will stop, to prevent the core behavior from occuring.
|
||||
*
|
||||
* Example usage:
|
||||
* ```
|
||||
* api.addSearchMenuOnKeyDownCallback((searchMenu, event) => {
|
||||
* if (searchMenu.term === "stop") {
|
||||
* return false;
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
addSearchMenuOnKeyDownCallback(fn) {
|
||||
addOnKeyDownCallback(fn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a quick search tip shown randomly when the search dropdown is invoked on desktop.
|
||||
*
|
||||
|
@ -1726,6 +1747,19 @@ class PluginApi {
|
|||
addQuickSearchRandomTip(tip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the default quick search tips shown randomly when the search dropdown is invoked on desktop.
|
||||
*
|
||||
* Usage:
|
||||
* ```
|
||||
* api.removeDefaultQuickSearchRandomTips();
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
removeDefaultQuickSearchRandomTips(tip) {
|
||||
removeDefaultQuickSearchRandomTips(tip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom user search options.
|
||||
* It is heavily correlated with `register_groups_callback_for_users_search_controller_action` which allows defining custom filter.
|
||||
|
|
|
@ -8,12 +8,14 @@ import { dateNode } from "discourse/helpers/node";
|
|||
import { emojiUnescape } from "discourse/lib/text";
|
||||
import getURL from "discourse-common/lib/get-url";
|
||||
import { h } from "virtual-dom";
|
||||
import hbs from "discourse/widgets/hbs-compiler";
|
||||
import widgetHbs from "discourse/widgets/hbs-compiler";
|
||||
import highlightSearch from "discourse/lib/highlight-search";
|
||||
import { iconNode } from "discourse-common/lib/icon-library";
|
||||
import renderTag from "discourse/lib/render-tag";
|
||||
import { MODIFIER_REGEXP } from "discourse/widgets/search-menu";
|
||||
import User from "discourse/models/user";
|
||||
import { hbs } from "ember-cli-htmlbars";
|
||||
import RenderGlimmer from "discourse/widgets/render-glimmer";
|
||||
|
||||
const suggestionShortcuts = [
|
||||
"in:title",
|
||||
|
@ -73,6 +75,10 @@ export function addQuickSearchRandomTip(tip) {
|
|||
}
|
||||
}
|
||||
|
||||
export function removeDefaultQuickSearchRandomTips() {
|
||||
QUICK_TIPS = QUICK_TIPS.filter((tip) => !DEFAULT_QUICK_TIPS.includes(tip));
|
||||
}
|
||||
|
||||
export function resetQuickSearchRandomTips() {
|
||||
QUICK_TIPS = [].concat(DEFAULT_QUICK_TIPS);
|
||||
}
|
||||
|
@ -284,7 +290,14 @@ createWidget("search-menu-results", {
|
|||
tagName: "div.results",
|
||||
|
||||
html(attrs) {
|
||||
const { term, suggestionKeyword, results, searchTopics } = attrs;
|
||||
const {
|
||||
term,
|
||||
suggestionKeyword,
|
||||
inTopicContext,
|
||||
results,
|
||||
searchTopics,
|
||||
onLinkClicked,
|
||||
} = attrs;
|
||||
|
||||
if (suggestionKeyword) {
|
||||
return this.attach("search-menu-assistant", {
|
||||
|
@ -385,9 +398,41 @@ createWidget("search-menu-results", {
|
|||
}
|
||||
}
|
||||
|
||||
content.push(
|
||||
new RenderGlimmer(
|
||||
this,
|
||||
"div",
|
||||
hbs`<PluginOutlet @name="search-menu-results-top" @outletArgs={{@data.outletArgs}}/>`,
|
||||
{
|
||||
outletArgs: {
|
||||
searchTerm: term,
|
||||
inTopicContext,
|
||||
onLinkClicked,
|
||||
searchTopics,
|
||||
},
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
content.push(categoriesAndTags);
|
||||
content.push(usersAndGroups);
|
||||
|
||||
content.push(
|
||||
new RenderGlimmer(
|
||||
this,
|
||||
"div",
|
||||
hbs`<PluginOutlet @name="search-menu-results-bottom" @outletArgs={{@data.outletArgs}}/>`,
|
||||
{
|
||||
outletArgs: {
|
||||
searchTerm: term,
|
||||
inTopicContext,
|
||||
onLinkClicked,
|
||||
searchTopics,
|
||||
},
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
return content;
|
||||
},
|
||||
});
|
||||
|
@ -778,6 +823,7 @@ createWidget("search-menu-assistant-item", {
|
|||
value: this.attrs.slug,
|
||||
searchTopics: true,
|
||||
setTopicContext: this.attrs.setTopicContext,
|
||||
origin: this.attrs.origin,
|
||||
});
|
||||
e.preventDefault();
|
||||
return false;
|
||||
|
@ -790,10 +836,16 @@ createWidget("random-quick-tip", {
|
|||
buildKey: () => "random-quick-tip",
|
||||
|
||||
defaultState() {
|
||||
return QUICK_TIPS[Math.floor(Math.random() * QUICK_TIPS.length)];
|
||||
return QUICK_TIPS.length
|
||||
? QUICK_TIPS[Math.floor(Math.random() * QUICK_TIPS.length)]
|
||||
: {};
|
||||
},
|
||||
|
||||
html(attrs, state) {
|
||||
if (!Object.keys(state).length) {
|
||||
return;
|
||||
}
|
||||
|
||||
return [
|
||||
h(
|
||||
`span.tip-label${state.clickable ? ".tip-clickable" : ""}`,
|
||||
|
@ -819,7 +871,7 @@ createWidget("random-quick-tip", {
|
|||
createWidget("search-menu-recent-searches", {
|
||||
tagName: "div.search-menu-recent",
|
||||
|
||||
template: hbs`
|
||||
template: widgetHbs`
|
||||
<div class="heading">
|
||||
<h4>{{i18n "search.recent"}}</h4>
|
||||
{{flat-button
|
||||
|
@ -833,7 +885,7 @@ createWidget("search-menu-recent-searches", {
|
|||
{{#each this.currentUser.recent_searches as |slug|}}
|
||||
{{attach
|
||||
widget="search-menu-assistant-item"
|
||||
attrs=(hash slug=slug icon="history")
|
||||
attrs=(hash slug=slug icon="history" origin="recent-search")
|
||||
}}
|
||||
{{/each}}
|
||||
`,
|
||||
|
|
|
@ -27,6 +27,15 @@ export const DEFAULT_TYPE_FILTER = "exclude_topics";
|
|||
|
||||
const searchData = {};
|
||||
|
||||
const onKeyDownCallbacks = [];
|
||||
|
||||
export function addOnKeyDownCallback(fn) {
|
||||
onKeyDownCallbacks.push(fn);
|
||||
}
|
||||
export function resetOnKeyDownCallbacks() {
|
||||
onKeyDownCallbacks.clear();
|
||||
}
|
||||
|
||||
export function initSearchData() {
|
||||
searchData.loading = false;
|
||||
searchData.results = {};
|
||||
|
@ -322,6 +331,8 @@ export default createWidget("search-menu", {
|
|||
suggestionResults: searchData.suggestionResults,
|
||||
searchTopics: SearchHelper.includesTopics(),
|
||||
inPMInboxContext: this.state.inPMInboxContext,
|
||||
inTopicContext: this.state.inTopicContext,
|
||||
onLinkClicked: this.onLinkClicked.bind(this),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -348,6 +359,10 @@ export default createWidget("search-menu", {
|
|||
});
|
||||
},
|
||||
|
||||
onLinkClicked() {
|
||||
return this.sendWidgetAction("linkClickedEvent");
|
||||
},
|
||||
|
||||
mouseDown(e) {
|
||||
if (e.target === document.querySelector("input#search-term")) {
|
||||
this.state.inputSelectionEvent = true;
|
||||
|
@ -371,6 +386,18 @@ export default createWidget("search-menu", {
|
|||
},
|
||||
|
||||
keyDown(e) {
|
||||
if (
|
||||
onKeyDownCallbacks.length &&
|
||||
!onKeyDownCallbacks.some((fn) => fn(this, e))
|
||||
) {
|
||||
// Return early if any callbacks return false
|
||||
return;
|
||||
}
|
||||
|
||||
this.handleKeyDown(e);
|
||||
},
|
||||
|
||||
handleKeyDown(e) {
|
||||
if (e.key === "Escape") {
|
||||
this.sendWidgetAction("toggleSearchMenu");
|
||||
document.querySelector("#search-button").focus();
|
||||
|
|
|
@ -26,7 +26,10 @@ import { _clearSnapshots } from "select-kit/components/composer-actions";
|
|||
import { clearHTMLCache } from "discourse/helpers/custom-html";
|
||||
import deprecated from "discourse-common/lib/deprecated";
|
||||
import { restoreBaseUri } from "discourse-common/lib/get-url";
|
||||
import { initSearchData } from "discourse/widgets/search-menu";
|
||||
import {
|
||||
initSearchData,
|
||||
resetOnKeyDownCallbacks,
|
||||
} from "discourse/widgets/search-menu";
|
||||
import { resetPostMenuExtraButtons } from "discourse/widgets/post-menu";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { resetCustomPostMessageCallbacks } from "discourse/controllers/topic";
|
||||
|
@ -213,6 +216,7 @@ export function testCleanup(container, app) {
|
|||
resetSidebarSection();
|
||||
resetNotificationTypeRenderers();
|
||||
clearExtraHeaderIcons();
|
||||
resetOnKeyDownCallbacks();
|
||||
resetUserMenuTabs();
|
||||
resetLinkLookup();
|
||||
resetModelTransformers();
|
||||
|
|
Loading…
Reference in New Issue
Block a user