diff --git a/app/assets/javascripts/discourse/app/components/sidebar.hbs b/app/assets/javascripts/discourse/app/components/sidebar.hbs index 2ccf92362e6..a00d6704470 100644 --- a/app/assets/javascripts/discourse/app/components/sidebar.hbs +++ b/app/assets/javascripts/discourse/app/components/sidebar.hbs @@ -1,4 +1,12 @@ + {{#if this.showSwitchPanelButtonsOnTop}} + + {{/if}} + {{#if this.showMainPanel}} {{/if}} - {{#each this.switchPanelButtons as |button|}} - - {{/each}} + {{/unless}} \ No newline at end of file diff --git a/app/assets/javascripts/discourse/app/components/sidebar.js b/app/assets/javascripts/discourse/app/components/sidebar.js index 5fa3d37c529..5518721c16b 100644 --- a/app/assets/javascripts/discourse/app/components/sidebar.js +++ b/app/assets/javascripts/discourse/app/components/sidebar.js @@ -2,17 +2,17 @@ import Component from "@glimmer/component"; import { tracked } from "@glimmer/tracking"; import { bind } from "discourse-common/utils/decorators"; import { inject as service } from "@ember/service"; +import { action } from "@ember/object"; import { currentPanelKey, customPanels as sidebarCustomPanels, } from "discourse/lib/sidebar/custom-sections"; -import { action } from "@ember/object"; export default class Sidebar extends Component { @service appEvents; @service site; + @service siteSettings; @service currentUser; - @service router; @tracked currentPanelKey = currentPanelKey; constructor() { @@ -33,6 +33,10 @@ export default class Sidebar extends Component { ); } + get showSwitchPanelButtonsOnTop() { + return this.siteSettings.default_sidebar_switch_panel_position === "top"; + } + get switchPanelButtons() { if (sidebarCustomPanels.length === 1 || !this.currentUser) { return []; @@ -69,14 +73,7 @@ export default class Sidebar extends Component { } @action - switchPanel(panel) { - this.currentPanel.lastKnownURL = this.router.currentURL; - this.currentPanelKey = panel.key; - const url = panel.lastKnownURL || panel.switchButtonDefaultUrl; - if (url === "/") { - this.router.transitionTo("latest"); - } else { - this.router.transitionTo(url); - } + setCurrentPanelKey(key) { + this.currentPanelKey = key; } } diff --git a/app/assets/javascripts/discourse/app/components/sidebar/switch-panel-buttons.hbs b/app/assets/javascripts/discourse/app/components/sidebar/switch-panel-buttons.hbs new file mode 100644 index 00000000000..aee2505a104 --- /dev/null +++ b/app/assets/javascripts/discourse/app/components/sidebar/switch-panel-buttons.hbs @@ -0,0 +1,8 @@ +{{#each @buttons as |button|}} + +{{/each}} \ No newline at end of file diff --git a/app/assets/javascripts/discourse/app/components/sidebar/switch-panel-buttons.js b/app/assets/javascripts/discourse/app/components/sidebar/switch-panel-buttons.js new file mode 100644 index 00000000000..f5f49cb35db --- /dev/null +++ b/app/assets/javascripts/discourse/app/components/sidebar/switch-panel-buttons.js @@ -0,0 +1,19 @@ +import Component from "@glimmer/component"; +import { inject as service } from "@ember/service"; +import { action } from "@ember/object"; + +export default class SwitchPanelButtons extends Component { + @service router; + + @action + switchPanel(currentPanel, panel) { + currentPanel.lastKnownURL = this.router.currentURL; + this.args.setCurrentPanelKey(panel.key); + const url = panel.lastKnownURL || panel.switchButtonDefaultUrl; + if (url === "/") { + this.router.transitionTo("discovery.latest"); + } else { + this.router.transitionTo(url); + } + } +} diff --git a/app/assets/javascripts/discourse/app/lib/sidebar/custom-sections.js b/app/assets/javascripts/discourse/app/lib/sidebar/custom-sections.js index e162dc30aeb..c2f2d579242 100644 --- a/app/assets/javascripts/discourse/app/lib/sidebar/custom-sections.js +++ b/app/assets/javascripts/discourse/app/lib/sidebar/custom-sections.js @@ -19,7 +19,7 @@ class MainSidebarPanel { } get switchButtonDefaultUrl() { - return "/latest"; + return "/"; } } diff --git a/app/assets/javascripts/discourse/tests/acceptance/sidebar-plugin-api-test.js b/app/assets/javascripts/discourse/tests/acceptance/sidebar-plugin-api-test.js index c8443369ef1..c19e1731b52 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/sidebar-plugin-api-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/sidebar-plugin-api-test.js @@ -1025,5 +1025,23 @@ acceptance("Sidebar - Plugin API", function (needs) { assert .dom(".sidebar-section[data-section-name='test-chat-channels']") .doesNotExist(); + assert.dom(".sidebar-sections + button").exists(); + + assert + .dom("#d-sidebar .sidebar-sections + .sidebar__panel-switch-button") + .exists(); + assert + .dom("#d-sidebar .sidebar__panel-switch-button + .sidebar-sections") + .doesNotExist(); + + this.siteSettings.default_sidebar_switch_panel_position = "top"; + await visit("/"); + + assert + .dom("#d-sidebar .sidebar-sections + .sidebar__panel-switch-button") + .doesNotExist(); + assert + .dom("#d-sidebar .sidebar__panel-switch-button + .sidebar-sections") + .exists(); }); }); diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index b0fb18e7c7b..70428a480ac 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -2357,6 +2357,7 @@ en: enable_offline_indicator: "Display a message to users when it is detected that they have no network connection" default_sidebar_link_to_filtered_list: "Make navigation menu links link to filtered list by default." default_sidebar_show_count_of_new_items: "Make navigation menu links show count of new items instead of badges by default." + default_sidebar_switch_panel_position: "Position of sidebar switch panel buttons" retain_web_hook_events_period_days: "Number of days to retain web hook event records." retry_web_hook_events: "Automatically retry failed web hook events for 4 times. Time gaps between the retries are 1, 5, 25 and 125 minutes." diff --git a/config/site_settings.yml b/config/site_settings.yml index 2a9fcf9e022..51b3a72f2cd 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -2160,6 +2160,13 @@ navigation: type: tag_list default: "" client: true + default_sidebar_switch_panel_position: + default: "bottom" + type: enum + client: true + choices: + - "top" + - "bottom" embedding: embed_by_username: