mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 11:44:49 +08:00
DEV: Convert header buttons to use new headerButtons
API (#26014)
This commit is contained in:
parent
0bc0efbd0a
commit
91f52e79ab
|
@ -5,7 +5,8 @@ import { action } from "@ember/object";
|
|||
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
|
||||
import { service } from "@ember/service";
|
||||
import { modifier } from "ember-modifier";
|
||||
import { and, not, or } from "truth-helpers";
|
||||
import { and, eq, not, or } from "truth-helpers";
|
||||
import DAG from "discourse/lib/dag";
|
||||
import scrollLock from "discourse/lib/scroll-lock";
|
||||
import DiscourseURL from "discourse/lib/url";
|
||||
import { scrollTop } from "discourse/mixins/scroll-top";
|
||||
|
@ -15,10 +16,25 @@ import HamburgerDropdownWrapper from "./glimmer-header/hamburger-dropdown-wrappe
|
|||
import Icons from "./glimmer-header/icons";
|
||||
import SearchMenuWrapper from "./glimmer-header/search-menu-wrapper";
|
||||
import UserMenuWrapper from "./glimmer-header/user-menu-wrapper";
|
||||
import PluginOutlet from "./plugin-outlet";
|
||||
|
||||
const SEARCH_BUTTON_ID = "search-button";
|
||||
|
||||
let headerButtons;
|
||||
resetHeaderButtons();
|
||||
|
||||
function resetHeaderButtons() {
|
||||
headerButtons = new DAG({ defaultPosition: { before: "auth" } });
|
||||
headerButtons.add("auth");
|
||||
}
|
||||
|
||||
export function headerButtonsDAG() {
|
||||
return headerButtons;
|
||||
}
|
||||
|
||||
export function clearExtraHeaderButtons() {
|
||||
resetHeaderButtons();
|
||||
}
|
||||
|
||||
export default class GlimmerHeader extends Component {
|
||||
@service router;
|
||||
@service search;
|
||||
|
@ -166,17 +182,17 @@ export default class GlimmerHeader extends Component {
|
|||
>
|
||||
|
||||
<span class="header-buttons">
|
||||
<PluginOutlet @name="before-header-buttons" />
|
||||
|
||||
{{#unless this.currentUser}}
|
||||
<AuthButtons
|
||||
@showCreateAccount={{@showCreateAccount}}
|
||||
@showLogin={{@showLogin}}
|
||||
@canSignUp={{@canSignUp}}
|
||||
/>
|
||||
{{/unless}}
|
||||
|
||||
<PluginOutlet @name="after-header-buttons" />
|
||||
{{#each (headerButtons.resolve) as |entry|}}
|
||||
{{#if (and (eq entry.key "auth") (not this.currentUser))}}
|
||||
<AuthButtons
|
||||
@showCreateAccount={{@showCreateAccount}}
|
||||
@showLogin={{@showLogin}}
|
||||
@canSignUp={{@canSignUp}}
|
||||
/>
|
||||
{{else if entry.value}}
|
||||
<entry.value />
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</span>
|
||||
|
||||
{{#if
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
import { addPluginDocumentTitleCounter } from "discourse/components/d-document";
|
||||
import { addToolbarCallback } from "discourse/components/d-editor";
|
||||
import { addCategorySortCriteria } from "discourse/components/edit-category-settings";
|
||||
import { headerButtonsDAG } from "discourse/components/glimmer-header";
|
||||
import { headerIconsDAG } from "discourse/components/glimmer-header/icons";
|
||||
import { forceDropdownForMenuPanels as glimmerForceDropdownForMenuPanels } from "discourse/components/glimmer-site-header";
|
||||
import { addGlobalNotice } from "discourse/components/global-notice";
|
||||
|
@ -143,7 +144,7 @@ import { modifySelectKit } from "select-kit/mixins/plugin-api";
|
|||
// docs/CHANGELOG-JAVASCRIPT-PLUGIN-API.md whenever you change the version
|
||||
// using the format described at https://keepachangelog.com/en/1.0.0/.
|
||||
|
||||
export const PLUGIN_API_VERSION = "1.28.0";
|
||||
export const PLUGIN_API_VERSION = "1.29.0";
|
||||
|
||||
const DEPRECATED_HEADER_WIDGETS = [
|
||||
"header",
|
||||
|
@ -1864,6 +1865,40 @@ class PluginApi {
|
|||
return headerIconsDAG();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows for manipulation of the header buttons. This includes, adding, removing, or modifying the order of buttons.
|
||||
*
|
||||
* Only the passing of components is supported, and by default the buttons are added to the left of exisiting buttons.
|
||||
*
|
||||
* Example: Add a `foo` button to the header buttons after the auth buttons
|
||||
* ```
|
||||
* api.headerButtons.add(
|
||||
* "foo",
|
||||
* FooComponent,
|
||||
* { after: "auth" }
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* Example: Remove the `foo` button from the header buttons
|
||||
* ```
|
||||
* api.headerButtons.delete("foo")
|
||||
* ```
|
||||
*
|
||||
* Example: Reposition the `foo` button to be before the `bar` and after the `baz` button
|
||||
* ```
|
||||
* api.headerButtons.reposition("foo", { before: "bar", after: "baz" })
|
||||
* ```
|
||||
*
|
||||
* Example: Check if the `foo` button is present in the header buttons (returns true of false)
|
||||
* ```
|
||||
* api.headerButtons.has("foo")
|
||||
* ```
|
||||
*
|
||||
**/
|
||||
get headerButtons() {
|
||||
return headerButtonsDAG();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a widget to the header-icon ul. The widget must already be created. You can create new widgets
|
||||
* in a theme or plugin via an initializer prior to calling this function.
|
||||
|
|
|
@ -2,6 +2,7 @@ import { schedule } from "@ember/runloop";
|
|||
import { hbs } from "ember-cli-htmlbars";
|
||||
import $ from "jquery";
|
||||
import { h } from "virtual-dom";
|
||||
import { headerButtonsDAG } from "discourse/components/glimmer-header";
|
||||
import { headerIconsDAG } from "discourse/components/glimmer-header/icons";
|
||||
import { addExtraUserClasses } from "discourse/helpers/user-avatar";
|
||||
import { wantsNewWindow } from "discourse/lib/intercept-click";
|
||||
|
@ -26,10 +27,17 @@ export const PANEL_WRAPPER_ID = "additional-panel-wrapper";
|
|||
let _extraHeaderIcons;
|
||||
clearExtraHeaderIcons();
|
||||
|
||||
let _extraHeaderButtons;
|
||||
clearExtraHeaderButtons();
|
||||
|
||||
export function clearExtraHeaderIcons() {
|
||||
_extraHeaderIcons = headerIconsDAG();
|
||||
}
|
||||
|
||||
export function clearExtraHeaderButtons() {
|
||||
_extraHeaderButtons = headerButtonsDAG();
|
||||
}
|
||||
|
||||
export const dropdown = {
|
||||
buildClasses(attrs) {
|
||||
let classes = attrs.classNames || [];
|
||||
|
@ -496,6 +504,10 @@ export default createWidget("header", {
|
|||
buildKey: () => `header`,
|
||||
services: ["router", "search"],
|
||||
|
||||
init() {
|
||||
registerWidgetShim("extra-button", "div.wrapper", hbs`<@data.component />`);
|
||||
},
|
||||
|
||||
defaultState() {
|
||||
let states = {
|
||||
searchVisible: false,
|
||||
|
@ -531,22 +543,19 @@ export default createWidget("header", {
|
|||
return headerIcons;
|
||||
}
|
||||
|
||||
const panels = [
|
||||
h("span.header-buttons", [
|
||||
new RenderGlimmer(
|
||||
this,
|
||||
"span.before-header-buttons",
|
||||
hbs`<PluginOutlet @name="before-header-buttons"/>`
|
||||
),
|
||||
this.attach("header-buttons", attrs),
|
||||
new RenderGlimmer(
|
||||
this,
|
||||
"span.after-header-buttons",
|
||||
hbs`<PluginOutlet @name="after-header-buttons"/>`
|
||||
),
|
||||
]),
|
||||
headerIcons,
|
||||
];
|
||||
const buttons = [];
|
||||
const resolvedButtons = _extraHeaderButtons.resolve();
|
||||
resolvedButtons.forEach((button) => {
|
||||
if (button.key === "auth") {
|
||||
return;
|
||||
}
|
||||
buttons.push(this.attach("extra-button", { component: button.value }));
|
||||
});
|
||||
|
||||
buttons.push(this.attach("header-buttons", attrs));
|
||||
|
||||
const panels = [];
|
||||
panels.push(h("span.header-buttons", buttons), headerIcons);
|
||||
|
||||
if (this.search.visible) {
|
||||
this.search.inTopicContext = this.search.inTopicContext && inTopicRoute;
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
import { visit } from "@ember/test-helpers";
|
||||
import { test } from "qunit";
|
||||
import { AUTO_GROUPS } from "discourse/lib/constants";
|
||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
|
||||
|
||||
// TODO: Consolidate these tests into a single acceptance test once the Glimmer
|
||||
// header is the default.
|
||||
acceptance("Header API - authenticated", function (needs) {
|
||||
needs.user();
|
||||
|
||||
test("can add buttons to the header", async function (assert) {
|
||||
withPluginApi("1.29.0", (api) => {
|
||||
api.headerButtons.add("test", <template>
|
||||
<button class="test-button">Test</button>
|
||||
</template>);
|
||||
});
|
||||
|
||||
await visit("/");
|
||||
assert.dom("button.test-button").exists("button is displayed");
|
||||
});
|
||||
});
|
||||
|
||||
acceptance("Header API - anonymous", function () {
|
||||
test("can add buttons to the header", async function (assert) {
|
||||
withPluginApi("1.29.0", (api) => {
|
||||
api.headerButtons.add("test", <template>
|
||||
<button class="test-button">Test</button>
|
||||
</template>);
|
||||
});
|
||||
|
||||
await visit("/");
|
||||
assert.dom("button.test-button").exists("button is displayed");
|
||||
});
|
||||
|
||||
test("buttons are positioned to the left of the auth buttons by default", async function (assert) {
|
||||
withPluginApi("1.29.0", (api) => {
|
||||
api.headerButtons.add("test", <template>
|
||||
<button class="test-button">Test</button>
|
||||
</template>);
|
||||
});
|
||||
|
||||
await visit("/");
|
||||
const testButton = document.querySelector(".test-button");
|
||||
const authButtons = document.querySelector(".auth-buttons");
|
||||
assert.equal(
|
||||
testButton.compareDocumentPosition(authButtons),
|
||||
Node.DOCUMENT_POSITION_FOLLOWING,
|
||||
"Test button is positioned before auth-buttons"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
acceptance("Glimmer Header API - authenticated", function (needs) {
|
||||
needs.user({ groups: AUTO_GROUPS.everyone });
|
||||
needs.settings({
|
||||
experimental_glimmer_header_groups: AUTO_GROUPS.everyone,
|
||||
});
|
||||
|
||||
test("can add buttons to the header", async function (assert) {
|
||||
withPluginApi("1.29.0", (api) => {
|
||||
api.headerButtons.add("test", <template>
|
||||
<button class="test-button">Test</button>
|
||||
</template>);
|
||||
});
|
||||
|
||||
await visit("/");
|
||||
assert.dom("button.test-button").exists("button is displayed");
|
||||
});
|
||||
|
||||
test("buttons can be repositioned", async function (assert) {
|
||||
withPluginApi("1.29.0", (api) => {
|
||||
api.headerButtons.add("test1", <template>
|
||||
<button class="test1-button">Test1</button>
|
||||
</template>);
|
||||
|
||||
api.headerButtons.add(
|
||||
"test2",
|
||||
<template><button class="test2-button">Test2</button></template>,
|
||||
{ before: "test1" }
|
||||
);
|
||||
});
|
||||
|
||||
await visit("/");
|
||||
const test1 = document.querySelector(".test1-button");
|
||||
const test2 = document.querySelector(".test2-button");
|
||||
assert.equal(
|
||||
test2.compareDocumentPosition(test1),
|
||||
Node.DOCUMENT_POSITION_FOLLOWING,
|
||||
"Test2 button is positioned before Test1 button"
|
||||
);
|
||||
});
|
||||
});
|
|
@ -18,6 +18,7 @@ import {
|
|||
cleanUpComposerUploadPreProcessor,
|
||||
} from "discourse/components/composer-editor";
|
||||
import { clearToolbarCallbacks } from "discourse/components/d-editor";
|
||||
import { clearExtraHeaderButtons as clearExtraGlimmerHeaderButtons } from "discourse/components/glimmer-header";
|
||||
import { clearExtraHeaderIcons as clearExtraGlimmerHeaderIcons } from "discourse/components/glimmer-header/icons";
|
||||
import { clearBulkButtons } from "discourse/components/modal/topic-bulk-actions";
|
||||
import { resetWidgetCleanCallbacks } from "discourse/components/mount-widget";
|
||||
|
@ -83,7 +84,10 @@ import {
|
|||
currentSettings,
|
||||
mergeSettings,
|
||||
} from "discourse/tests/helpers/site-settings";
|
||||
import { clearExtraHeaderIcons } from "discourse/widgets/header";
|
||||
import {
|
||||
clearExtraHeaderButtons,
|
||||
clearExtraHeaderIcons,
|
||||
} from "discourse/widgets/header";
|
||||
import { resetDecorators as resetPostCookedDecorators } from "discourse/widgets/post-cooked";
|
||||
import { resetPostMenuExtraButtons } from "discourse/widgets/post-menu";
|
||||
import { resetDecorators } from "discourse/widgets/widget";
|
||||
|
@ -225,7 +229,9 @@ export function testCleanup(container, app) {
|
|||
resetNotificationTypeRenderers();
|
||||
resetSidebarPanels();
|
||||
clearExtraGlimmerHeaderIcons();
|
||||
clearExtraGlimmerHeaderButtons();
|
||||
clearExtraHeaderIcons();
|
||||
clearExtraHeaderButtons();
|
||||
resetOnKeyUpCallbacks();
|
||||
resetItemSelectCallbacks();
|
||||
resetUserMenuTabs();
|
||||
|
|
|
@ -7,6 +7,10 @@ in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.29.0] - 2024-03-05
|
||||
|
||||
- added `headerButtons` which allows for manipulation of the header butttons. This includes, adding, removing, or modifying the order of buttons.
|
||||
|
||||
## [1.28.0] - 2024-02-21
|
||||
|
||||
- added `headerIcons` which allows for manipulation of the header icons. This includes, adding, removing, or modifying the order of icons.
|
||||
|
|
Loading…
Reference in New Issue
Block a user