DEV: Add sidebar community section for anonymous user

This commit is contained in:
Alan Guo Xiang Tan 2022-08-24 11:23:43 +08:00
parent e9e6ab688c
commit eb12daa7f8
24 changed files with 230 additions and 94 deletions

View File

@ -2,7 +2,8 @@
{{#if this.currentUser}} {{#if this.currentUser}}
<Sidebar::User::Sections @collapsableSections={{true}}/> <Sidebar::User::Sections @collapsableSections={{true}}/>
{{else}} {{else}}
<Sidebar::Anonymous::Sections /> <Sidebar::Anonymous::Sections @collapsableSections={{true}}/>
{{/if}} {{/if}}
<Sidebar::Footer /> <Sidebar::Footer />
</DSection> </DSection>

View File

@ -0,0 +1,24 @@
import SidebarCommonCommunitySection from "discourse/components/sidebar/common/community-section";
import EverythingSectionLink from "discourse/lib/sidebar/common/community-section/everything-section-link";
import AboutSectionLink from "discourse/lib/sidebar/common/community-section/about-section-link";
import FAQSectionLink from "discourse/lib/sidebar/common/community-section/faq-section-link";
import GroupsSectionLink from "discourse/lib/sidebar/common/community-section/groups-section-link";
import UsersSectionLink from "discourse/lib/sidebar/common/community-section/users-section-link";
import BadgesSectionLink from "discourse/lib/sidebar/common/community-section/badges-section-link";
export default class SidebarAnonymousCommunitySection extends SidebarCommonCommunitySection {
constructor() {
super(...arguments);
this.defaultMoreSectionLinks = [GroupsSectionLink, BadgesSectionLink];
this.defaultMoreSecondarySectionLinks = [];
this.defaultMainSectionLinks = [
EverythingSectionLink,
UsersSectionLink,
AboutSectionLink,
FAQSectionLink,
];
}
}

View File

@ -1,6 +1,8 @@
<div class="sidebar-sections sidebar-sections-anonymous"> <div class="sidebar-sections sidebar-sections-anonymous">
<Sidebar::Anonymous::CategoriesSection /> <Sidebar::Anonymous::CommunitySection @collapsable={{@collapsableSections}} />
<Sidebar::Anonymous::CategoriesSection @collapsable={{@collapsableSections}} />
{{#if this.siteSettings.tagging_enabled}} {{#if this.siteSettings.tagging_enabled}}
<Sidebar::Anonymous::TagsSection /> <Sidebar::Anonymous::TagsSection @collapsable={{@collapsableSections}} />
{{/if}} {{/if}}
</div> </div>

View File

@ -1,8 +1,8 @@
<Sidebar::Section <Sidebar::Section
@sectionName="community" @sectionName="community"
@headerLinkText={{i18n "sidebar.sections.community.header_link_text"}} @headerLinkText={{i18n "sidebar.sections.community.header_link_text"}}
@headerActionsIcon="plus" @headerActionsIcon={{this.headerActionsIcon}}
@headerActions={{array (hash action=this.composeTopic title=(i18n "sidebar.sections.community.header_action_title"))}} @headerActions={{this.headerActions}}
@collapsable={{@collapsable}} > @collapsable={{@collapsable}} >
{{#each this.sectionLinks as |sectionLink|}} {{#each this.sectionLinks as |sectionLink|}}

View File

@ -0,0 +1,66 @@
import Component from "@glimmer/component";
import { inject as service } from "@ember/service";
import {
customSectionLinks,
secondaryCustomSectionLinks,
} from "discourse/lib/sidebar/custom-community-section-links";
export default class SidebarCommunitySection extends Component {
@service router;
@service topicTrackingState;
@service currentUser;
@service appEvents;
@service siteSettings;
// Override in child
defaultMainSectionLinks = [];
defaultAdminMainSectionLinks = [];
defaultMoreSectionLinks = [];
defaultMoreSecondarySectionLinks = [];
headerActionsIcon;
headerActions;
get moreSectionLinks() {
return [...this.defaultMoreSectionLinks, ...customSectionLinks].map(
(sectionLinkClass) => {
return this.#initializeSectionLink(sectionLinkClass);
}
);
}
get moreSecondarySectionLinks() {
return [
...this.defaultMoreSecondarySectionLinks,
...secondaryCustomSectionLinks,
].map((sectionLinkClass) => {
return this.#initializeSectionLink(sectionLinkClass);
});
}
get mainSectionLinks() {
return this.currentUser?.staff
? [...this.defaultMainSectionLinks, ...this.defaultAdminMainSectionLinks]
: [...this.defaultMainSectionLinks];
}
get sectionLinks() {
return this.mainSectionLinks.map((sectionLinkClass) => {
return this.#initializeSectionLink(sectionLinkClass);
});
}
willDestroy() {
this.sectionLinks.forEach((sectionLink) => sectionLink.teardown());
}
#initializeSectionLink(sectionLinkClass) {
return new sectionLinkClass({
topicTrackingState: this.topicTrackingState,
currentUser: this.currentUser,
appEvents: this.appEvents,
router: this.router,
siteSettings: this.siteSettings,
});
}
}

View File

@ -1,70 +1,50 @@
import Component from "@glimmer/component"; import I18n from "I18n";
import Composer from "discourse/models/composer"; import Composer from "discourse/models/composer";
import { getOwner } from "discourse-common/lib/get-owner"; import { getOwner } from "discourse-common/lib/get-owner";
import PermissionType from "discourse/models/permission-type"; import PermissionType from "discourse/models/permission-type";
import { import EverythingSectionLink from "discourse/lib/sidebar/common/community-section/everything-section-link";
customSectionLinks,
secondaryCustomSectionLinks,
} from "discourse/lib/sidebar/user/custom-community-section-links";
import EverythingSectionLink from "discourse/lib/sidebar/user/community-section/everything-section-link";
import TrackedSectionLink from "discourse/lib/sidebar/user/community-section/tracked-section-link"; import TrackedSectionLink from "discourse/lib/sidebar/user/community-section/tracked-section-link";
import MyPostsSectionLink from "discourse/lib/sidebar/user/community-section/my-posts-section-link"; import MyPostsSectionLink from "discourse/lib/sidebar/user/community-section/my-posts-section-link";
import GroupsSectionLink from "discourse/lib/sidebar/user/community-section/groups-section-link"; import GroupsSectionLink from "discourse/lib/sidebar/common/community-section/groups-section-link";
import UsersSectionLink from "discourse/lib/sidebar/user/community-section/users-section-link"; import UsersSectionLink from "discourse/lib/sidebar/common/community-section/users-section-link";
import AboutSectionLink from "discourse/lib/sidebar/user/community-section/about-section-link"; import AboutSectionLink from "discourse/lib/sidebar/common/community-section/about-section-link";
import FAQSectionLink from "discourse/lib/sidebar/user/community-section/faq-section-link"; import FAQSectionLink from "discourse/lib/sidebar/common/community-section/faq-section-link";
import AdminSectionLink from "discourse/lib/sidebar/user/community-section/admin-section-link"; import AdminSectionLink from "discourse/lib/sidebar/user/community-section/admin-section-link";
import BadgesSectionLink from "discourse/lib/sidebar/user/community-section/badges-section-link"; import BadgesSectionLink from "discourse/lib/sidebar/common/community-section/badges-section-link";
import SidebarCommonCommunitySection from "discourse/components/sidebar/common/community-section";
import { inject as service } from "@ember/service";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { next } from "@ember/runloop"; import { next } from "@ember/runloop";
const MAIN_SECTION_LINKS = [ export default class SidebarUserCommunitySection extends SidebarCommonCommunitySection {
EverythingSectionLink, constructor() {
TrackedSectionLink, super(...arguments);
MyPostsSectionLink,
];
const ADMIN_MAIN_SECTION_LINKS = [AdminSectionLink]; this.defaultMoreSectionLinks = [
GroupsSectionLink,
UsersSectionLink,
BadgesSectionLink,
];
const MORE_SECTION_LINKS = [ this.defaultMoreSecondarySectionLinks = [AboutSectionLink, FAQSectionLink];
GroupsSectionLink,
UsersSectionLink,
BadgesSectionLink,
];
const MORE_SECONDARY_SECTION_LINKS = [AboutSectionLink, FAQSectionLink];
export default class SidebarUserCommunitySection extends Component { this.defaultMainSectionLinks = [
@service router; EverythingSectionLink,
@service topicTrackingState; TrackedSectionLink,
@service currentUser; MyPostsSectionLink,
@service appEvents; ];
@service siteSettings;
moreSectionLinks = [...MORE_SECTION_LINKS, ...customSectionLinks].map( this.defaultAdminMainSectionLinks = [AdminSectionLink];
(sectionLinkClass) => {
return this.#initializeSectionLink(sectionLinkClass);
}
);
moreSecondarySectionLinks = [ this.headerActionsIcon = "plus";
...MORE_SECONDARY_SECTION_LINKS,
...secondaryCustomSectionLinks,
].map((sectionLinkClass) => {
return this.#initializeSectionLink(sectionLinkClass);
});
#mainSectionLinks = this.currentUser.staff this.headerActions = [
? [...MAIN_SECTION_LINKS, ...ADMIN_MAIN_SECTION_LINKS] {
: [...MAIN_SECTION_LINKS]; action: this.composeTopic,
title: I18n.t("sidebar.sections.community.header_action_title"),
sectionLinks = this.#mainSectionLinks.map((sectionLinkClass) => { },
return this.#initializeSectionLink(sectionLinkClass); ];
});
willDestroy() {
this.sectionLinks.forEach((sectionLink) => sectionLink.teardown());
} }
@action @action
@ -85,14 +65,4 @@ export default class SidebarUserCommunitySection extends Component {
getOwner(this).lookup("controller:composer").open(composerArgs); getOwner(this).lookup("controller:composer").open(composerArgs);
}); });
} }
#initializeSectionLink(sectionLinkClass) {
return new sectionLinkClass({
topicTrackingState: this.topicTrackingState,
currentUser: this.currentUser,
appEvents: this.appEvents,
router: this.router,
siteSettings: this.siteSettings,
});
}
} }

View File

@ -1,5 +1,5 @@
import Component from "@glimmer/component"; import Component from "@glimmer/component";
import { customSections as sidebarCustomSections } from "discourse/lib/sidebar/user/custom-sections"; import { customSections as sidebarCustomSections } from "discourse/lib/sidebar/custom-sections";
import { getOwner, setOwner } from "@ember/application"; import { getOwner, setOwner } from "@ember/application";
import { inject as service } from "@ember/service"; import { inject as service } from "@ember/service";

View File

@ -95,8 +95,8 @@ import {
import { CUSTOM_USER_SEARCH_OPTIONS } from "select-kit/components/user-chooser"; import { CUSTOM_USER_SEARCH_OPTIONS } from "select-kit/components/user-chooser";
import { downloadCalendar } from "discourse/lib/download-calendar"; import { downloadCalendar } from "discourse/lib/download-calendar";
import { consolePrefix } from "discourse/lib/source-identifier"; import { consolePrefix } from "discourse/lib/source-identifier";
import { addSectionLink as addCustomCommunitySectionLink } from "discourse/lib/sidebar/user/custom-community-section-links"; import { addSectionLink as addCustomCommunitySectionLink } from "discourse/lib/sidebar/custom-community-section-links";
import { addSidebarSection } from "discourse/lib/sidebar/user/custom-sections"; import { addSidebarSection } from "discourse/lib/sidebar/custom-sections";
import DiscourseURL from "discourse/lib/url"; import DiscourseURL from "discourse/lib/url";
import { registerNotificationTypeRenderer } from "discourse/lib/notification-types-manager"; import { registerNotificationTypeRenderer } from "discourse/lib/notification-types-manager";
import { registerUserMenuTab } from "discourse/lib/user-menu/tab"; import { registerUserMenuTab } from "discourse/lib/user-menu/tab";

View File

@ -1,7 +1,7 @@
/** /**
* Base class representing a sidebar topics section link interface. * Base class representing a sidebar communtiy section link interface.
*/ */
export default class BaseSectionLink { export default class BaseCommunitySectionLink {
constructor({ constructor({
topicTrackingState, topicTrackingState,
currentUser, currentUser,

View File

@ -1,6 +1,6 @@
import I18n from "I18n"; import I18n from "I18n";
import BaseSectionLink from "discourse/lib/sidebar/user/community-section/base-section-link"; import BaseSectionLink from "discourse/lib/sidebar/base-community-section-link";
export default class AboutSectionLink extends BaseSectionLink { export default class AboutSectionLink extends BaseSectionLink {
get name() { get name() {

View File

@ -1,6 +1,6 @@
import I18n from "I18n"; import I18n from "I18n";
import BaseSectionLink from "discourse/lib/sidebar/user/community-section/base-section-link"; import BaseSectionLink from "discourse/lib/sidebar/base-community-section-link";
export default class BadgesSectionLink extends BaseSectionLink { export default class BadgesSectionLink extends BaseSectionLink {
get name() { get name() {

View File

@ -2,7 +2,7 @@ import I18n from "I18n";
import { tracked } from "@glimmer/tracking"; import { tracked } from "@glimmer/tracking";
import { bind } from "discourse-common/utils/decorators"; import { bind } from "discourse-common/utils/decorators";
import BaseSectionLink from "discourse/lib/sidebar/user/community-section/base-section-link"; import BaseSectionLink from "discourse/lib/sidebar/base-community-section-link";
export default class EverythingSectionLink extends BaseSectionLink { export default class EverythingSectionLink extends BaseSectionLink {
@tracked totalUnread = 0; @tracked totalUnread = 0;
@ -12,15 +12,19 @@ export default class EverythingSectionLink extends BaseSectionLink {
constructor() { constructor() {
super(...arguments); super(...arguments);
this.callbackId = this.topicTrackingState.onStateChange( if (this.currentUser) {
this._refreshCounts this.callbackId = this.topicTrackingState.onStateChange(
); this._refreshCounts
);
this._refreshCounts(); this._refreshCounts();
}
} }
teardown() { teardown() {
this.topicTrackingState.offStateChange(this.callbackId); if (this.callbackId) {
this.topicTrackingState.offStateChange(this.callbackId);
}
} }
@bind @bind

View File

@ -1,6 +1,6 @@
import I18n from "I18n"; import I18n from "I18n";
import BaseSectionLink from "discourse/lib/sidebar/user/community-section/base-section-link"; import BaseSectionLink from "discourse/lib/sidebar/base-community-section-link";
export default class FAQSectionLink extends BaseSectionLink { export default class FAQSectionLink extends BaseSectionLink {
get name() { get name() {

View File

@ -1,6 +1,6 @@
import I18n from "I18n"; import I18n from "I18n";
import BaseSectionLink from "discourse/lib/sidebar/user/community-section/base-section-link"; import BaseSectionLink from "discourse/lib/sidebar/base-community-section-link";
export default class GroupsSectionLink extends BaseSectionLink { export default class GroupsSectionLink extends BaseSectionLink {
get name() { get name() {

View File

@ -1,6 +1,6 @@
import I18n from "I18n"; import I18n from "I18n";
import BaseSectionLink from "discourse/lib/sidebar/user/community-section/base-section-link"; import BaseSectionLink from "discourse/lib/sidebar/base-community-section-link";
export default class UsersSectionLink extends BaseSectionLink { export default class UsersSectionLink extends BaseSectionLink {
get name() { get name() {

View File

@ -1,4 +1,4 @@
import BaseSectionLink from "discourse/lib/sidebar/user/community-section/base-section-link"; import BaseCommunitySectionLink from "discourse/lib/sidebar/base-community-section-link";
export let customSectionLinks = []; export let customSectionLinks = [];
export let secondaryCustomSectionLinks = []; export let secondaryCustomSectionLinks = [];
@ -44,8 +44,8 @@ class RouteInfoHelper {
* Appends an additional section link to the Community section under the "More..." links drawer. * Appends an additional section link to the Community section under the "More..." links drawer.
* *
* @callback addSectionLinkCallback * @callback addSectionLinkCallback
* @param {BaseSectionLink} baseSectionLink Factory class to inherit from. * @param {BaseCommunitySectionLink} baseCommunitySectionLink Factory class to inherit from.
* @returns {BaseSectionLink} A class that extends BaseSectionLink. * @returns {BaseCommunitySectionLink} A class that extends BaseCommunitySectionLink.
* *
* @param {(addSectionLinkCallback|Object)} args - A callback function or an Object. * @param {(addSectionLinkCallback|Object)} args - A callback function or an Object.
* @param {string} args.name - The name of the link. Needs to be dasherized and lowercase. * @param {string} args.name - The name of the link. Needs to be dasherized and lowercase.
@ -59,9 +59,9 @@ export function addSectionLink(args, secondary) {
const links = secondary ? secondaryCustomSectionLinks : customSectionLinks; const links = secondary ? secondaryCustomSectionLinks : customSectionLinks;
if (typeof args === "function") { if (typeof args === "function") {
links.push(args.call(this, BaseSectionLink)); links.push(args.call(this, BaseCommunitySectionLink));
} else { } else {
const klass = class extends BaseSectionLink { const klass = class extends BaseCommunitySectionLink {
constructor() { constructor() {
super(...arguments); super(...arguments);

View File

@ -1,5 +1,5 @@
import BaseCustomSidebarSection from "discourse/lib/sidebar/user/base-custom-sidebar-section"; import BaseCustomSidebarSection from "discourse/lib/sidebar/base-custom-sidebar-section";
import BaseCustomSidebarSectionLink from "discourse/lib/sidebar/user/base-custom-sidebar-section-link"; import BaseCustomSidebarSectionLink from "discourse/lib/sidebar/base-custom-sidebar-section-link";
export const customSections = []; export const customSections = [];

View File

@ -1,6 +1,6 @@
import I18n from "I18n"; import I18n from "I18n";
import BaseSectionLink from "discourse/lib/sidebar/user/community-section/base-section-link"; import BaseSectionLink from "discourse/lib/sidebar/base-community-section-link";
export default class AdminSectionLink extends BaseSectionLink { export default class AdminSectionLink extends BaseSectionLink {
get name() { get name() {

View File

@ -1,7 +1,7 @@
import I18n from "I18n"; import I18n from "I18n";
import { tracked } from "@glimmer/tracking"; import { tracked } from "@glimmer/tracking";
import BaseSectionLink from "discourse/lib/sidebar/user/community-section/base-section-link"; import BaseSectionLink from "discourse/lib/sidebar/base-community-section-link";
const USER_DRAFTS_CHANGED_EVENT = "user-drafts:changed"; const USER_DRAFTS_CHANGED_EVENT = "user-drafts:changed";

View File

@ -2,7 +2,7 @@ import I18n from "I18n";
import { tracked } from "@glimmer/tracking"; import { tracked } from "@glimmer/tracking";
import { bind } from "discourse-common/utils/decorators"; import { bind } from "discourse-common/utils/decorators";
import BaseSectionLink from "discourse/lib/sidebar/user/community-section/base-section-link"; import BaseSectionLink from "discourse/lib/sidebar/base-community-section-link";
import { isTrackedTopic } from "discourse/lib/topic-list-tracked-filter"; import { isTrackedTopic } from "discourse/lib/topic-list-tracked-filter";
export default class TrackedSectionLink extends BaseSectionLink { export default class TrackedSectionLink extends BaseSectionLink {

View File

@ -0,0 +1,69 @@
import I18n from "I18n";
import { test } from "qunit";
import { acceptance, queryAll } from "discourse/tests/helpers/qunit-helpers";
import { click, visit } from "@ember/test-helpers";
acceptance("Sidebar - Anonymous user - Community Section", function (needs) {
needs.settings({
enable_experimental_sidebar_hamburger: true,
enable_sidebar: true,
});
test("everything, users, about and FAQ section links are shown by default ", async function (assert) {
await visit("/");
const sectionLinks = queryAll(
".sidebar-section-community .sidebar-section-link"
);
assert.strictEqual(
sectionLinks[0].textContent.trim(),
I18n.t("sidebar.sections.community.links.everything.content"),
"displays the everything section link first"
);
assert.strictEqual(
sectionLinks[1].textContent.trim(),
I18n.t("sidebar.sections.community.links.users.content"),
"displays the users section link second"
);
assert.strictEqual(
sectionLinks[2].textContent.trim(),
I18n.t("about.simple_title"),
"displays the about section link third"
);
assert.strictEqual(
sectionLinks[3].textContent.trim(),
I18n.t("faq"),
"displays the FAQ section link last"
);
});
test("groups and badges section links are shown in more...", async function (assert) {
await visit("/");
await click(
".sidebar-section-community .sidebar-more-section-links-details-summary"
);
const sectionLinks = queryAll(
".sidebar-more-section-links-details-content-main .sidebar-section-link"
);
assert.strictEqual(
sectionLinks[0].textContent.trim(),
I18n.t("sidebar.sections.community.links.groups.content"),
"displays the groups section link first"
);
assert.strictEqual(
sectionLinks[1].textContent.trim(),
I18n.t("badges.title"),
"displays the badges section link second"
);
});
});

View File

@ -62,7 +62,7 @@ import {
setTestPresence, setTestPresence,
} from "discourse/lib/user-presence"; } from "discourse/lib/user-presence";
import PreloadStore from "discourse/lib/preload-store"; import PreloadStore from "discourse/lib/preload-store";
import { resetDefaultSectionLinks as resetTopicsSectionLinks } from "discourse/lib/sidebar/user/custom-community-section-links"; import { resetDefaultSectionLinks as resetTopicsSectionLinks } from "discourse/lib/sidebar/custom-community-section-links";
import { import {
clearBlockDecorateCallbacks, clearBlockDecorateCallbacks,
clearTagDecorateCallbacks, clearTagDecorateCallbacks,
@ -71,7 +71,7 @@ import {
import { clearTagsHtmlCallbacks } from "discourse/lib/render-tags"; import { clearTagsHtmlCallbacks } from "discourse/lib/render-tags";
import { clearToolbarCallbacks } from "discourse/components/d-editor"; import { clearToolbarCallbacks } from "discourse/components/d-editor";
import { clearExtraHeaderIcons } from "discourse/widgets/header"; import { clearExtraHeaderIcons } from "discourse/widgets/header";
import { resetSidebarSection } from "discourse/lib/sidebar/user/custom-sections"; import { resetSidebarSection } from "discourse/lib/sidebar/custom-sections";
import { resetNotificationTypeRenderers } from "discourse/lib/notification-types-manager"; import { resetNotificationTypeRenderers } from "discourse/lib/notification-types-manager";
import { resetUserMenuTabs } from "discourse/lib/user-menu/tab"; import { resetUserMenuTabs } from "discourse/lib/user-menu/tab";
import { reset as resetLinkLookup } from "discourse/lib/link-lookup"; import { reset as resetLinkLookup } from "discourse/lib/link-lookup";