FEATURE: new API to add panels to sidebar (#22534)
Define new concept of panels in sidebar. Panels are wrappers around sidebar sections. In the future, it allows creating full focus mode by switching between panels. A new API method called addSidebarPanel was added. Default main panel is already registered and by default all API sections are mounted to main.
This commit is contained in:
parent
9ef2a2ac9b
commit
20ec7ac174
|
@ -1,7 +1,26 @@
|
|||
<DSection @pageClass="has-sidebar" @id="d-sidebar" @class="sidebar-container">
|
||||
<Sidebar::Sections
|
||||
@currentUser={{this.currentUser}}
|
||||
@collapsableSections={{true}}
|
||||
/>
|
||||
{{#if this.showMainPanel}}
|
||||
<Sidebar::Sections
|
||||
@currentUser={{this.currentUser}}
|
||||
@collapsableSections={{true}}
|
||||
@panel={{this.currentPanel}}
|
||||
/>
|
||||
{{else}}
|
||||
<Sidebar::ApiPanels
|
||||
@currentUser={{this.currentUser}}
|
||||
@collapsableSections={{true}}
|
||||
@panel={{this.currentPanel}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
{{#each this.switchPanelButtons as |button|}}
|
||||
<DButton
|
||||
@action={{action "switchPanel" button}}
|
||||
@class="btn-default sidebar__panel-switch-button"
|
||||
@icon={{button.switchButtonIcon}}
|
||||
@translatedLabel={{button.switchButtonLabel}}
|
||||
/>
|
||||
{{/each}}
|
||||
|
||||
<Sidebar::Footer />
|
||||
</DSection>
|
|
@ -1,11 +1,19 @@
|
|||
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 {
|
||||
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 currentUser;
|
||||
@service router;
|
||||
@tracked currentPanelKey = currentPanelKey;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
@ -15,6 +23,24 @@ export default class Sidebar extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
get showMainPanel() {
|
||||
return this.currentPanelKey === "main";
|
||||
}
|
||||
|
||||
get currentPanel() {
|
||||
return sidebarCustomPanels.find(
|
||||
(panel) => panel.key === this.currentPanelKey
|
||||
);
|
||||
}
|
||||
|
||||
get switchPanelButtons() {
|
||||
if (sidebarCustomPanels.length === 1 || !this.currentUser) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return sidebarCustomPanels.filter((panel) => panel !== this.currentPanel);
|
||||
}
|
||||
|
||||
@bind
|
||||
collapseSidebar(event) {
|
||||
let shouldCollapseSidebar = false;
|
||||
|
@ -41,4 +67,16 @@ export default class Sidebar extends Component {
|
|||
document.removeEventListener("click", this.collapseSidebar);
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<div class="sidebar-sections">
|
||||
<Sidebar::ApiSections
|
||||
@sections={{this.customSections}}
|
||||
@collapsable={{@collapsableSections}}
|
||||
/>
|
||||
</div>
|
|
@ -0,0 +1,20 @@
|
|||
import Component from "@glimmer/component";
|
||||
import { getOwner, setOwner } from "@ember/application";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default class SidebarApiPanels extends Component {
|
||||
@service siteSettings;
|
||||
@service currentUser;
|
||||
@service site;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
||||
this.customSections =
|
||||
this.args.panel?.sections?.map((customSection) => {
|
||||
const section = new customSection();
|
||||
setOwner(section, getOwner(this));
|
||||
return section;
|
||||
}) || [];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
{{#each @sections as |customSection|}}
|
||||
<Sidebar::Section
|
||||
@sectionName={{customSection.name}}
|
||||
@headerLinkText={{customSection.text}}
|
||||
@headerLinkTitle={{customSection.title}}
|
||||
@headerActionsIcon={{customSection.actionsIcon}}
|
||||
@headerActions={{customSection.actions}}
|
||||
@willDestroy={{customSection.willDestroy}}
|
||||
@collapsable={{@collapsableSections}}
|
||||
@displaySection={{customSection.displaySection}}
|
||||
>
|
||||
|
||||
{{#each customSection.links as |link|}}
|
||||
<Sidebar::SectionLink
|
||||
@linkName={{link.name}}
|
||||
@class={{link.classNames}}
|
||||
@route={{link.route}}
|
||||
@model={{link.model}}
|
||||
@models={{link.models}}
|
||||
@title={{link.title}}
|
||||
@contentCSSClass={{link.contentCSSClass}}
|
||||
@prefixColor={{link.prefixColor}}
|
||||
@prefixBadge={{link.prefixBadge}}
|
||||
@prefixType={{link.prefixType}}
|
||||
@prefixValue={{link.prefixValue}}
|
||||
@prefixCSSClass={{link.prefixCSSClass}}
|
||||
@suffixType={{link.suffixType}}
|
||||
@suffixValue={{link.suffixValue}}
|
||||
@suffixCSSClass={{link.suffixCSSClass}}
|
||||
@hoverType={{link.hoverType}}
|
||||
@hoverValue={{link.hoverValue}}
|
||||
@hoverAction={{link.hoverAction}}
|
||||
@hoverTitle={{link.hoverTitle}}
|
||||
@currentWhen={{link.currentWhen}}
|
||||
@didInsert={{link.didInsert}}
|
||||
@willDestroy={{link.willDestroy}}
|
||||
@content={{link.text}}
|
||||
@contentComponent={{component
|
||||
link.contentComponent
|
||||
status=link.contentComponentArgs
|
||||
}}
|
||||
/>
|
||||
{{/each}}
|
||||
</Sidebar::Section>
|
||||
{{/each}}
|
|
@ -1,5 +1,8 @@
|
|||
{{#if @currentUser}}
|
||||
<Sidebar::User::Sections @collapsableSections={{@collapsableSections}} />
|
||||
<Sidebar::User::Sections
|
||||
@collapsableSections={{@collapsableSections}}
|
||||
@panel={{@panel}}
|
||||
/>
|
||||
{{else}}
|
||||
<Sidebar::Anonymous::Sections @collapsableSections={{@collapsableSections}} />
|
||||
{{/if}}
|
|
@ -10,49 +10,8 @@
|
|||
<Sidebar::User::MessagesSection @collapsable={{@collapsableSections}} />
|
||||
{{/if}}
|
||||
|
||||
{{#each this.customSections as |customSection|}}
|
||||
<Sidebar::Section
|
||||
@sectionName={{customSection.name}}
|
||||
@headerLinkText={{customSection.text}}
|
||||
@headerLinkTitle={{customSection.title}}
|
||||
@headerActionsIcon={{customSection.actionsIcon}}
|
||||
@headerActions={{customSection.actions}}
|
||||
@willDestroy={{customSection.willDestroy}}
|
||||
@collapsable={{@collapsableSections}}
|
||||
@displaySection={{customSection.displaySection}}
|
||||
>
|
||||
|
||||
{{#each customSection.links as |link|}}
|
||||
<Sidebar::SectionLink
|
||||
@linkName={{link.name}}
|
||||
@class={{link.classNames}}
|
||||
@route={{link.route}}
|
||||
@model={{link.model}}
|
||||
@models={{link.models}}
|
||||
@title={{link.title}}
|
||||
@contentCSSClass={{link.contentCSSClass}}
|
||||
@prefixColor={{link.prefixColor}}
|
||||
@prefixBadge={{link.prefixBadge}}
|
||||
@prefixType={{link.prefixType}}
|
||||
@prefixValue={{link.prefixValue}}
|
||||
@prefixCSSClass={{link.prefixCSSClass}}
|
||||
@suffixType={{link.suffixType}}
|
||||
@suffixValue={{link.suffixValue}}
|
||||
@suffixCSSClass={{link.suffixCSSClass}}
|
||||
@hoverType={{link.hoverType}}
|
||||
@hoverValue={{link.hoverValue}}
|
||||
@hoverAction={{link.hoverAction}}
|
||||
@hoverTitle={{link.hoverTitle}}
|
||||
@currentWhen={{link.currentWhen}}
|
||||
@didInsert={{link.didInsert}}
|
||||
@willDestroy={{link.willDestroy}}
|
||||
@content={{link.text}}
|
||||
@contentComponent={{component
|
||||
link.contentComponent
|
||||
status=link.contentComponentArgs
|
||||
}}
|
||||
/>
|
||||
{{/each}}
|
||||
</Sidebar::Section>
|
||||
{{/each}}
|
||||
<Sidebar::ApiSections
|
||||
@sections={{this.customSections}}
|
||||
@collapsable={{@collapsableSections}}
|
||||
/>
|
||||
</div>
|
|
@ -1,21 +1,21 @@
|
|||
import Component from "@glimmer/component";
|
||||
import { customSections as sidebarCustomSections } from "discourse/lib/sidebar/custom-sections";
|
||||
import { getOwner, setOwner } from "@ember/application";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { cached } from "@glimmer/tracking";
|
||||
|
||||
export default class SidebarUserSections extends Component {
|
||||
@service siteSettings;
|
||||
@service currentUser;
|
||||
@service site;
|
||||
|
||||
@cached
|
||||
get customSections() {
|
||||
return sidebarCustomSections.map((customSection) => {
|
||||
const section = new customSection({ sidebar: this });
|
||||
setOwner(section, getOwner(this));
|
||||
return section;
|
||||
});
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
||||
this.customSections =
|
||||
this.args.panel?.sections?.map((customSection) => {
|
||||
const section = new customSection();
|
||||
setOwner(section, getOwner(this));
|
||||
return section;
|
||||
}) || [];
|
||||
}
|
||||
|
||||
get enableMessagesSection() {
|
||||
|
|
|
@ -105,7 +105,11 @@ import { CUSTOM_USER_SEARCH_OPTIONS } from "select-kit/components/user-chooser";
|
|||
import { downloadCalendar } from "discourse/lib/download-calendar";
|
||||
import { consolePrefix } from "discourse/lib/source-identifier";
|
||||
import { addSectionLink as addCustomCommunitySectionLink } from "discourse/lib/sidebar/custom-community-section-links";
|
||||
import { addSidebarSection } from "discourse/lib/sidebar/custom-sections";
|
||||
import {
|
||||
addSidebarPanel,
|
||||
addSidebarSection,
|
||||
setSidebarPanel,
|
||||
} from "discourse/lib/sidebar/custom-sections";
|
||||
import {
|
||||
registerCustomCategoryLockIcon,
|
||||
registerCustomCategorySectionLinkPrefix,
|
||||
|
@ -126,7 +130,7 @@ import { _addBulkButton } from "discourse/controllers/topic-bulk-actions";
|
|||
// based on Semantic Versioning 2.0.0. Please update the changelog at
|
||||
// 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.7.1";
|
||||
export const PLUGIN_API_VERSION = "1.8.0";
|
||||
|
||||
// This helper prevents us from applying the same `modifyClass` over and over in test mode.
|
||||
function canModify(klass, type, resolverName, changes) {
|
||||
|
@ -2029,6 +2033,44 @@ class PluginApi {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL. Do not use.
|
||||
* Support for adding a Sidebar panel by returning a class which extends from the BaseCustomSidebarPanel
|
||||
* class interface. See `lib/sidebar/user/base-custom-sidebar-panel.js` for documentation on the BaseCustomSidebarPanel class
|
||||
* interface.
|
||||
*
|
||||
* ```
|
||||
* api.addSidebarPanel((BaseCustomSidebarPanel) => {
|
||||
* const ChatSidebarPanel = class extends BaseCustomSidebarPanel {
|
||||
* get key() {
|
||||
* return "chat";
|
||||
* }
|
||||
* get switchButtonLabel() {
|
||||
* return I18n.t("sidebar.panels.chat.label");
|
||||
* }
|
||||
* get switchButtonIcon() {
|
||||
* return "d-chat";
|
||||
* }
|
||||
* get switchButtonDefaultUrl() {
|
||||
* return "/chat";
|
||||
* }
|
||||
* };
|
||||
* return ChatSidebarPanel;
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
addSidebarPanel(func) {
|
||||
addSidebarPanel(func);
|
||||
}
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL. Do not use.
|
||||
* Support for setting a Sidebar panel.
|
||||
*/
|
||||
setSidebarPanel(name) {
|
||||
setSidebarPanel(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Support for adding a Sidebar section by returning a class which extends from the BaseCustomSidebarSection
|
||||
* class interface. See `lib/sidebar/user/base-custom-sidebar-section.js` for documentation on the BaseCustomSidebarSection class
|
||||
|
@ -2148,8 +2190,8 @@ class PluginApi {
|
|||
* })
|
||||
* ```
|
||||
*/
|
||||
addSidebarSection(func) {
|
||||
addSidebarSection(func);
|
||||
addSidebarSection(func, panelKey = "main") {
|
||||
addSidebarSection(func, panelKey);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* Base class representing a sidebar section header interface.
|
||||
*/
|
||||
export default class BaseCustomSidebarPanel {
|
||||
sections = [];
|
||||
|
||||
/**
|
||||
* @returns {string} Identifier for sidebar panel
|
||||
*/
|
||||
get key() {
|
||||
this.#notImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} Text for the switch button
|
||||
*/
|
||||
get switchButtonLabel() {
|
||||
this.#notImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} Icon for the switch button
|
||||
*/
|
||||
get switchButtonIcon() {
|
||||
this.#notImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} Default path to panel
|
||||
*/
|
||||
get switchButtonDefaultUrl() {
|
||||
this.#notImplemented();
|
||||
}
|
||||
|
||||
#notImplemented() {
|
||||
throw "not implemented";
|
||||
}
|
||||
}
|
|
@ -2,10 +2,6 @@
|
|||
* Base class representing a sidebar section header interface.
|
||||
*/
|
||||
export default class BaseCustomSidebarSection {
|
||||
constructor({ sidebar } = {}) {
|
||||
this.sidebar = sidebar;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The name of the section header. Needs to be dasherized and lowercase.
|
||||
*/
|
||||
|
|
|
@ -1,14 +1,55 @@
|
|||
import BaseCustomSidebarSection from "discourse/lib/sidebar/base-custom-sidebar-section";
|
||||
import BaseCustomSidebarPanel from "discourse/lib/sidebar/base-custom-sidebar-panel";
|
||||
import BaseCustomSidebarSectionLink from "discourse/lib/sidebar/base-custom-sidebar-section-link";
|
||||
import I18n from "I18n";
|
||||
|
||||
export const customSections = [];
|
||||
class MainSidebarPanel {
|
||||
sections = [];
|
||||
|
||||
export function addSidebarSection(func) {
|
||||
customSections.push(
|
||||
get key() {
|
||||
return "main";
|
||||
}
|
||||
|
||||
get switchButtonLabel() {
|
||||
return I18n.t("sidebar.panels.forum.label");
|
||||
}
|
||||
|
||||
get switchButtonIcon() {
|
||||
return "random";
|
||||
}
|
||||
|
||||
get switchButtonDefaultUrl() {
|
||||
return "/latest";
|
||||
}
|
||||
}
|
||||
|
||||
export let customPanels = [new MainSidebarPanel()];
|
||||
|
||||
export let currentPanelKey = "main";
|
||||
|
||||
export function addSidebarPanel(func) {
|
||||
const panelClass = func.call(this, BaseCustomSidebarPanel);
|
||||
customPanels.push(new panelClass());
|
||||
}
|
||||
|
||||
export function setSidebarPanel(name) {
|
||||
currentPanelKey = name;
|
||||
}
|
||||
|
||||
export function addSidebarSection(func, panelKey) {
|
||||
const panel = customPanels.find((p) => p.key === panelKey);
|
||||
if (!panel) {
|
||||
// eslint-disable-next-line no-console
|
||||
return console.warn(
|
||||
`Error adding section to ${panelKey} because panel doens't exist. Check addSidebarPanel API.`
|
||||
);
|
||||
}
|
||||
panel.sections.push(
|
||||
func.call(this, BaseCustomSidebarSection, BaseCustomSidebarSectionLink)
|
||||
);
|
||||
}
|
||||
|
||||
export function resetSidebarSection() {
|
||||
customSections.length = 0;
|
||||
export function resetSidebarPanels() {
|
||||
customPanels = [new MainSidebarPanel()];
|
||||
currentPanelKey = "main";
|
||||
}
|
||||
|
|
|
@ -874,4 +874,122 @@ acceptance("Sidebar - Plugin API", function (needs) {
|
|||
resetCustomTagSectionLinkPrefixIcons();
|
||||
}
|
||||
});
|
||||
|
||||
test("New custom sidebar panel and option to set default", async function (assert) {
|
||||
withPluginApi(PLUGIN_API_VERSION, (api) => {
|
||||
api.addSidebarPanel((BaseCustomSidebarPanel) => {
|
||||
const ChatSidebarPanel = class extends BaseCustomSidebarPanel {
|
||||
get key() {
|
||||
return "new-panel";
|
||||
}
|
||||
|
||||
get switchButtonLabel() {
|
||||
"New panel";
|
||||
}
|
||||
|
||||
get switchButtonIcon() {
|
||||
return "d-chat";
|
||||
}
|
||||
|
||||
get switchButtonDefaultUrl() {
|
||||
return "/chat";
|
||||
}
|
||||
};
|
||||
return ChatSidebarPanel;
|
||||
});
|
||||
api.addSidebarSection(
|
||||
(BaseCustomSidebarSection, BaseCustomSidebarSectionLink) => {
|
||||
return class extends BaseCustomSidebarSection {
|
||||
get name() {
|
||||
return "test-chat-channels";
|
||||
}
|
||||
|
||||
get text() {
|
||||
return "chat channels text";
|
||||
}
|
||||
|
||||
get actionsIcon() {
|
||||
return "cog";
|
||||
}
|
||||
|
||||
get links() {
|
||||
return [
|
||||
new (class extends BaseCustomSidebarSectionLink {
|
||||
get name() {
|
||||
return "random-channel";
|
||||
}
|
||||
|
||||
get classNames() {
|
||||
return "my-class-name";
|
||||
}
|
||||
|
||||
get route() {
|
||||
return "topic";
|
||||
}
|
||||
|
||||
get models() {
|
||||
return ["some-slug", 1];
|
||||
}
|
||||
|
||||
get title() {
|
||||
return "random channel title";
|
||||
}
|
||||
|
||||
get text() {
|
||||
return "random channel text";
|
||||
}
|
||||
|
||||
get prefixType() {
|
||||
return "icon";
|
||||
}
|
||||
|
||||
get prefixValue() {
|
||||
return "d-chat";
|
||||
}
|
||||
|
||||
get prefixColor() {
|
||||
return "FF0000";
|
||||
}
|
||||
|
||||
get prefixBadge() {
|
||||
return "lock";
|
||||
}
|
||||
|
||||
get suffixType() {
|
||||
return "icon";
|
||||
}
|
||||
|
||||
get suffixValue() {
|
||||
return "circle";
|
||||
}
|
||||
|
||||
get suffixCSSClass() {
|
||||
return "unread";
|
||||
}
|
||||
})(),
|
||||
];
|
||||
}
|
||||
};
|
||||
},
|
||||
"new-panel"
|
||||
);
|
||||
api.setSidebarPanel("new-panel");
|
||||
});
|
||||
|
||||
await visit("/");
|
||||
|
||||
assert.strictEqual(
|
||||
query(
|
||||
".sidebar-section[data-section-name='test-chat-channels'] .sidebar-section-header-text"
|
||||
).textContent.trim(),
|
||||
"chat channels text",
|
||||
"displays header with correct text"
|
||||
);
|
||||
|
||||
await click(".sidebar__panel-switch-button");
|
||||
|
||||
assert
|
||||
.dom(".sidebar-section[data-section-name='test-chat-channels']")
|
||||
.doesNotExist();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -80,7 +80,7 @@ import {
|
|||
import { clearTagsHtmlCallbacks } from "discourse/lib/render-tags";
|
||||
import { clearToolbarCallbacks } from "discourse/components/d-editor";
|
||||
import { clearExtraHeaderIcons } from "discourse/widgets/header";
|
||||
import { resetSidebarSection } from "discourse/lib/sidebar/custom-sections";
|
||||
import { resetSidebarPanels } from "discourse/lib/sidebar/custom-sections";
|
||||
import { resetNotificationTypeRenderers } from "discourse/lib/notification-types-manager";
|
||||
import { resetUserMenuTabs } from "discourse/lib/user-menu/tab";
|
||||
import { reset as resetLinkLookup } from "discourse/lib/link-lookup";
|
||||
|
@ -214,7 +214,7 @@ export function testCleanup(container, app) {
|
|||
clearResolverOptions();
|
||||
clearTagsHtmlCallbacks();
|
||||
clearToolbarCallbacks();
|
||||
resetSidebarSection();
|
||||
resetSidebarPanels();
|
||||
resetNotificationTypeRenderers();
|
||||
clearExtraHeaderIcons();
|
||||
resetOnKeyDownCallbacks();
|
||||
|
|
|
@ -281,3 +281,10 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar__panel-switch-button {
|
||||
margin: 1em 1.3em 0 1.3em;
|
||||
&:last-of-type {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2041,7 +2041,7 @@ en:
|
|||
|
||||
summary:
|
||||
in_progress: "Summarizing topic using AI..."
|
||||
summarized_on: "Summarized with %{method} on %{date}"
|
||||
summarized_on: "Summarized with %{method} on %{date}"
|
||||
enabled_description: "You're viewing this topic top replies: the most interesting posts as determined by the community."
|
||||
description:
|
||||
one: "There is <b>%{count}</b> reply."
|
||||
|
@ -4527,6 +4527,9 @@ en:
|
|||
title: "Flagged posts and other queued items"
|
||||
pending_count: "%{count} pending"
|
||||
global_section: "Global section, visible to everyone"
|
||||
panels:
|
||||
forum:
|
||||
label: Forum
|
||||
|
||||
welcome_topic_banner:
|
||||
title: "Create your Welcome Topic"
|
||||
|
|
|
@ -110,10 +110,11 @@ export default {
|
|||
};
|
||||
|
||||
const SidebarChatChannelsSection = class extends BaseCustomSidebarSection {
|
||||
@service currentUser;
|
||||
@tracked currentUserCanJoinPublicChannels =
|
||||
this.sidebar.currentUser &&
|
||||
(this.sidebar.currentUser.staff ||
|
||||
this.sidebar.currentUser.has_joinable_public_channels);
|
||||
this.currentUser &&
|
||||
(this.currentUser.staff ||
|
||||
this.currentUser.has_joinable_public_channels);
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
|
Loading…
Reference in New Issue