From 3d6b81222022d586473c4946c77ecedf1850d8a8 Mon Sep 17 00:00:00 2001 From: Isaac Janzen <50783505+janzenisaac@users.noreply.github.com> Date: Wed, 13 Sep 2023 14:32:12 -0500 Subject: [PATCH] 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 --- .../discourse/app/components/search-menu.hbs | 4 +- .../discourse/app/components/search-menu.js | 16 +++-- .../search-menu/menu-panel-contents.hbs | 4 +- .../search-menu/results/assistant-item.js | 1 + .../search-menu/results/initial-options.js | 4 +- .../discourse/app/services/search.js | 2 + .../discourse/app/widgets/header.js | 65 +++++++++---------- 7 files changed, 48 insertions(+), 48 deletions(-) diff --git a/app/assets/javascripts/discourse/app/components/search-menu.hbs b/app/assets/javascripts/discourse/app/components/search-menu.hbs index a8c9ca61da7..fbb0cc04ae5 100644 --- a/app/assets/javascripts/discourse/app/components/search-menu.hbs +++ b/app/assets/javascripts/discourse/app/components/search-menu.hbs @@ -1,6 +1,5 @@ - + \ No newline at end of file diff --git a/app/assets/javascripts/discourse/app/components/search-menu.js b/app/assets/javascripts/discourse/app/components/search-menu.js index 046ccf28403..49cd6e296c7 100644 --- a/app/assets/javascripts/discourse/app/components/search-menu.js +++ b/app/assets/javascripts/discourse/app/components/search-menu.js @@ -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); } } diff --git a/app/assets/javascripts/discourse/app/components/search-menu/menu-panel-contents.hbs b/app/assets/javascripts/discourse/app/components/search-menu/menu-panel-contents.hbs index 15cbcaae6a6..9caee2bb218 100644 --- a/app/assets/javascripts/discourse/app/components/search-menu/menu-panel-contents.hbs +++ b/app/assets/javascripts/discourse/app/components/search-menu/menu-panel-contents.hbs @@ -1,5 +1,5 @@
- {{#if @inTopicContext}} + {{#if this.search.inTopicContext}} -{{#if (and @inTopicContext (not @includesTopics))}} +{{#if (and this.search.inTopicContext (not @includesTopics))}} {{else}} {{#unless @loading}} diff --git a/app/assets/javascripts/discourse/app/components/search-menu/results/assistant-item.js b/app/assets/javascripts/discourse/app/components/search-menu/results/assistant-item.js index 7be9af66e54..4008f1a33a8 100644 --- a/app/assets/javascripts/discourse/app/components/search-menu/results/assistant-item.js +++ b/app/assets/javascripts/discourse/app/components/search-menu/results/assistant-item.js @@ -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, diff --git a/app/assets/javascripts/discourse/app/components/search-menu/results/initial-options.js b/app/assets/javascripts/discourse/app/components/search-menu/results/initial-options.js index 5c13732ae22..121a5c2eb5e 100644 --- a/app/assets/javascripts/discourse/app/components/search-menu/results/initial-options.js +++ b/app/assets/javascripts/discourse/app/components/search-menu/results/initial-options.js @@ -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(); diff --git a/app/assets/javascripts/discourse/app/services/search.js b/app/assets/javascripts/discourse/app/services/search.js index baef9d04aaf..2c9c03ea2d5 100644 --- a/app/assets/javascripts/discourse/app/services/search.js +++ b/app/assets/javascripts/discourse/app/services/search.js @@ -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 diff --git a/app/assets/javascripts/discourse/app/widgets/header.js b/app/assets/javascripts/discourse/app/widgets/header.js index 19c0c870f71..153ce0ec07b 100644 --- a/app/assets/javascripts/discourse/app/widgets/header.js +++ b/app/assets/javascripts/discourse/app/widgets/header.js @@ -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``, - { - closeSearchMenu: this.closeSearchMenu.bind(this), - inTopicContext: this.attrs.inTopicContext, - searchVisible: this.attrs.searchVisible, - animationClass: this.attrs.animationClass, - } + hbs``, + { 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();