mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 18:30:26 -06:00
DEV: Move relevant glimmer search menu logic to service (#23483)
This will allow initializing the glimmer search menu without having to pass args directly from header.js widget, to help themes and plugins with search customizations --------- Co-authored-by: Mark VanLandingham <markvanlan@gmail.com>
This commit is contained in:
parent
6b218636ab
commit
3d6b812220
@ -1,6 +1,5 @@
|
||||
<MenuPanel @animationClass={{@animationClass}}>
|
||||
<MenuPanel @animationClass={{this.animationClass}}>
|
||||
<SearchMenu::MenuPanelContents
|
||||
@inTopicContext={{this.inTopicContext}}
|
||||
@clearTopicContext={{this.clearTopicContext}}
|
||||
@clearPMInboxContext={{this.clearPMInboxContext}}
|
||||
@inPMInboxContext={{this.inPMInboxContext}}
|
||||
@ -19,7 +18,6 @@
|
||||
@searchTopics={{this.includesTopics}}
|
||||
@typeFilter={{this.typeFilter}}
|
||||
@updateTypeFilter={{this.updateTypeFilter}}
|
||||
@toggleSearchMenu={{@toggleSearchMenu}}
|
||||
@closeSearchMenu={{@closeSearchMenu}}
|
||||
/>
|
||||
</MenuPanel>
|
@ -39,8 +39,8 @@ export default class SearchMenu extends Component {
|
||||
@service currentUser;
|
||||
@service siteSettings;
|
||||
@service appEvents;
|
||||
@service site;
|
||||
|
||||
@tracked inTopicContext = this.args.inTopicContext;
|
||||
@tracked loading = false;
|
||||
@tracked results = {};
|
||||
@tracked noResults = false;
|
||||
@ -53,12 +53,18 @@ export default class SearchMenu extends Component {
|
||||
_debouncer = null;
|
||||
_activeSearch = null;
|
||||
|
||||
get animationClass() {
|
||||
return this.site.mobileView || this.site.narrowDesktopView
|
||||
? "slide-in"
|
||||
: "drop-down";
|
||||
}
|
||||
|
||||
get includesTopics() {
|
||||
return this.typeFilter !== DEFAULT_TYPE_FILTER;
|
||||
}
|
||||
|
||||
get searchContext() {
|
||||
if (this.inTopicContext || this.inPMInboxContext) {
|
||||
if (this.search.inTopicContext || this.inPMInboxContext) {
|
||||
return this.search.searchContext;
|
||||
}
|
||||
|
||||
@ -102,7 +108,7 @@ export default class SearchMenu extends Component {
|
||||
searchTermChanged(term, opts = {}) {
|
||||
this.typeFilter = opts.searchTopics ? null : DEFAULT_TYPE_FILTER;
|
||||
if (opts.setTopicContext) {
|
||||
this.inTopicContext = true;
|
||||
this.search.inTopicContext = true;
|
||||
}
|
||||
this.search.activeGlobalSearchTerm = term;
|
||||
this.triggerSearch();
|
||||
@ -129,7 +135,7 @@ export default class SearchMenu extends Component {
|
||||
|
||||
@action
|
||||
clearTopicContext() {
|
||||
this.inTopicContext = false;
|
||||
this.search.inTopicContext = false;
|
||||
}
|
||||
|
||||
// for cancelling debounced search
|
||||
@ -286,7 +292,7 @@ export default class SearchMenu extends Component {
|
||||
}
|
||||
} else {
|
||||
this.loading = false;
|
||||
if (!this.inTopicContext) {
|
||||
if (!this.search.inTopicContext) {
|
||||
this._debouncer = discourseDebounce(this, this.perform, 400);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div class="search-input">
|
||||
{{#if @inTopicContext}}
|
||||
{{#if this.search.inTopicContext}}
|
||||
<DButton
|
||||
@icon="times"
|
||||
@label="search.in_this_topic"
|
||||
@ -42,7 +42,7 @@
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{#if (and @inTopicContext (not @includesTopics))}}
|
||||
{{#if (and this.search.inTopicContext (not @includesTopics))}}
|
||||
<SearchMenu::BrowserSearchTip />
|
||||
{{else}}
|
||||
{{#unless @loading}}
|
||||
|
@ -95,6 +95,7 @@ export default class AssistantItem extends Component {
|
||||
} else {
|
||||
updatedValue = this.prefix.trim();
|
||||
}
|
||||
|
||||
const inTopicContext = this.search.searchContext?.type === "topic";
|
||||
this.args.searchTermChanged(updatedValue, {
|
||||
searchTopics: !inTopicContext || this.search.activeGlobalSearchTerm,
|
||||
|
@ -28,7 +28,7 @@ export default class InitialOptions extends Component {
|
||||
this.contextTypeComponent =
|
||||
SEARCH_CONTEXT_TYPE_COMPONENTS[this.search.searchContext.type];
|
||||
// set attributes for the component
|
||||
this.attributesForSearchContextType(this.search.searchContext.type);
|
||||
this.setAttributesForSearchContextType(this.search.searchContext.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -39,7 +39,7 @@ export default class InitialOptions extends Component {
|
||||
: false;
|
||||
}
|
||||
|
||||
attributesForSearchContextType(type) {
|
||||
setAttributesForSearchContextType(type) {
|
||||
switch (type) {
|
||||
case "topic":
|
||||
this.topicContextType();
|
||||
|
@ -11,6 +11,8 @@ export default class Search extends Service {
|
||||
@tracked activeGlobalSearchTerm = "";
|
||||
@tracked searchContext;
|
||||
@tracked highlightTerm;
|
||||
@tracked inTopicContext = false;
|
||||
@tracked visible = false;
|
||||
|
||||
// only relative for the widget search menu
|
||||
searchContextEnabled = false; // checkbox to scope search
|
||||
|
@ -244,6 +244,7 @@ createWidget(
|
||||
);
|
||||
|
||||
createWidget("header-icons", {
|
||||
services: ["search"],
|
||||
tagName: "ul.icons.d-header-icons",
|
||||
|
||||
html(attrs) {
|
||||
@ -264,7 +265,7 @@ createWidget("header-icons", {
|
||||
icon: "search",
|
||||
iconId: SEARCH_BUTTON_ID,
|
||||
action: "toggleSearchMenu",
|
||||
active: attrs.searchVisible,
|
||||
active: attrs.searchVisible || this.search.visible,
|
||||
href: getURL("/search"),
|
||||
classNames: ["search-dropdown"],
|
||||
});
|
||||
@ -421,6 +422,7 @@ createWidget("revamped-user-menu-wrapper", {
|
||||
});
|
||||
|
||||
createWidget("glimmer-search-menu-wrapper", {
|
||||
services: ["search"],
|
||||
buildAttributes() {
|
||||
return { "data-click-outside": true, "aria-live": "polite" };
|
||||
},
|
||||
@ -434,18 +436,8 @@ createWidget("glimmer-search-menu-wrapper", {
|
||||
new RenderGlimmer(
|
||||
this,
|
||||
"div.widget-component-connector",
|
||||
hbs`<SearchMenu
|
||||
@inTopicContext={{@data.inTopicContext}}
|
||||
@searchVisible={{@data.searchVisible}}
|
||||
@animationClass={{@data.animationClass}}
|
||||
@closeSearchMenu={{@data.closeSearchMenu}}
|
||||
/>`,
|
||||
{
|
||||
closeSearchMenu: this.closeSearchMenu.bind(this),
|
||||
inTopicContext: this.attrs.inTopicContext,
|
||||
searchVisible: this.attrs.searchVisible,
|
||||
animationClass: this.attrs.animationClass,
|
||||
}
|
||||
hbs`<SearchMenu @closeSearchMenu={{@data.closeSearchMenu}} />`,
|
||||
{ closeSearchMenu: this.closeSearchMenu.bind(this) }
|
||||
),
|
||||
];
|
||||
},
|
||||
@ -481,8 +473,7 @@ export default createWidget("header", {
|
||||
|
||||
html(attrs, state) {
|
||||
let inTopicRoute = false;
|
||||
|
||||
if (this.state.inTopicContext) {
|
||||
if (this.state.inTopicContext || this.search.inTopicContext) {
|
||||
inTopicRoute = this.router.currentRouteName.startsWith("topic.");
|
||||
}
|
||||
|
||||
@ -490,7 +481,7 @@ export default createWidget("header", {
|
||||
const headerIcons = this.attach("header-icons", {
|
||||
hamburgerVisible: state.hamburgerVisible,
|
||||
userVisible: state.userVisible,
|
||||
searchVisible: state.searchVisible,
|
||||
searchVisible: state.searchVisible || this.search.visible,
|
||||
flagCount: attrs.flagCount,
|
||||
user: this.currentUser,
|
||||
sidebarEnabled: attrs.sidebarEnabled,
|
||||
@ -502,15 +493,11 @@ export default createWidget("header", {
|
||||
|
||||
const panels = [this.attach("header-buttons", attrs), headerIcons];
|
||||
|
||||
if (state.searchVisible) {
|
||||
if (state.searchVisible || this.search.visible) {
|
||||
if (this.currentUser?.experimental_search_menu_groups_enabled) {
|
||||
panels.push(
|
||||
this.attach("glimmer-search-menu-wrapper", {
|
||||
inTopicContext: state.inTopicContext && inTopicRoute,
|
||||
searchVisible: state.searchVisible,
|
||||
animationClass: this.animationClass(),
|
||||
})
|
||||
);
|
||||
this.search.inTopicContext =
|
||||
this.search.inTopicContext && inTopicRoute;
|
||||
panels.push(this.attach("glimmer-search-menu-wrapper"));
|
||||
} else {
|
||||
panels.push(
|
||||
this.attach("search-menu", {
|
||||
@ -563,21 +550,16 @@ export default createWidget("header", {
|
||||
},
|
||||
|
||||
updateHighlight() {
|
||||
if (!this.state.searchVisible) {
|
||||
this.search.set("highlightTerm", "");
|
||||
if (!this.state.searchVisible || !this.search.visible) {
|
||||
this.search.highlightTerm = "";
|
||||
}
|
||||
},
|
||||
|
||||
animationClass() {
|
||||
return this.site.mobileView || this.site.narrowDesktopView
|
||||
? "slide-in"
|
||||
: "drop-down";
|
||||
},
|
||||
|
||||
closeAll() {
|
||||
this.state.userVisible = false;
|
||||
this.state.hamburgerVisible = false;
|
||||
this.state.searchVisible = false;
|
||||
this.search.visible = false;
|
||||
this.toggleBodyScrolling(false);
|
||||
},
|
||||
|
||||
@ -618,12 +600,15 @@ export default createWidget("header", {
|
||||
}
|
||||
|
||||
this.state.searchVisible = !this.state.searchVisible;
|
||||
this.search.visible = !this.search.visible;
|
||||
this.updateHighlight();
|
||||
|
||||
if (this.state.searchVisible) {
|
||||
// only used by the widget search-menu
|
||||
this.focusSearchInput();
|
||||
} else {
|
||||
this.state.inTopicContext = false;
|
||||
this.search.inTopicContext = false;
|
||||
}
|
||||
},
|
||||
|
||||
@ -706,6 +691,7 @@ export default createWidget("header", {
|
||||
|
||||
togglePageSearch() {
|
||||
const { state } = this;
|
||||
this.search.inTopicContext = false;
|
||||
state.inTopicContext = false;
|
||||
|
||||
let showSearch = this.router.currentRouteName.startsWith("topic.");
|
||||
@ -721,13 +707,14 @@ export default createWidget("header", {
|
||||
$(".topic-post .cooked, .small-action:not(.time-gap)").length < total;
|
||||
}
|
||||
|
||||
if (state.searchVisible) {
|
||||
if (state.searchVisible || this.search.visible) {
|
||||
this.toggleSearchMenu();
|
||||
return showSearch;
|
||||
}
|
||||
|
||||
if (showSearch) {
|
||||
state.inTopicContext = true;
|
||||
this.search.inTopicContext = true;
|
||||
this.toggleSearchMenu();
|
||||
return false;
|
||||
}
|
||||
@ -738,7 +725,12 @@ export default createWidget("header", {
|
||||
domClean() {
|
||||
const { state } = this;
|
||||
|
||||
if (state.searchVisible || state.hamburgerVisible || state.userVisible) {
|
||||
if (
|
||||
state.searchVisible ||
|
||||
this.search.visible ||
|
||||
state.hamburgerVisible ||
|
||||
state.userVisible
|
||||
) {
|
||||
this.closeAll();
|
||||
}
|
||||
},
|
||||
@ -763,9 +755,8 @@ export default createWidget("header", {
|
||||
}
|
||||
},
|
||||
|
||||
// only used by the widget search-menu
|
||||
focusSearchInput() {
|
||||
// the glimmer search menu handles the focusing of the search
|
||||
// input within the search component
|
||||
if (
|
||||
this.state.searchVisible &&
|
||||
!this.currentUser?.experimental_search_menu_groups_enabled
|
||||
@ -778,11 +769,13 @@ export default createWidget("header", {
|
||||
}
|
||||
},
|
||||
|
||||
// only used by the widget search-menu
|
||||
setTopicContext() {
|
||||
this.state.inTopicContext = true;
|
||||
this.focusSearchInput();
|
||||
},
|
||||
|
||||
// only used by the widget search-menu
|
||||
clearContext() {
|
||||
this.state.inTopicContext = false;
|
||||
this.focusSearchInput();
|
||||
|
Loading…
Reference in New Issue
Block a user