mirror of
https://github.com/discourse/discourse.git
synced 2025-02-16 08:15:00 +00:00
UX: Move links in Sidebar footer under community section (#17774)
Now that we have a "more..." links drawer, we can move some of the links in footer into the links drawer. The footer itself does not have much horizontal or vertical space for us to work with and hence limits the amount of links which we can add to it.
This commit is contained in:
parent
53dd9b0c66
commit
d1d760ae7b
@ -8,6 +8,9 @@ import TrackedSectionLink from "discourse/lib/sidebar/community-section/tracked-
|
||||
import MyPostsSectionLink from "discourse/lib/sidebar/community-section/my-posts-section-link";
|
||||
import GroupsSectionLink from "discourse/lib/sidebar/community-section/groups-section-link";
|
||||
import UsersSectionLink from "discourse/lib/sidebar/community-section/users-section-link";
|
||||
import AboutSectionLink from "discourse/lib/sidebar/community-section/about-section-link";
|
||||
import FAQSectionLink from "discourse/lib/sidebar/community-section/faq-section-link";
|
||||
import AdminSectionLink from "discourse/lib/sidebar/community-section/admin-section-link";
|
||||
|
||||
import { inject as service } from "@ember/service";
|
||||
import { action } from "@ember/object";
|
||||
@ -19,7 +22,14 @@ const MAIN_SECTION_LINKS = [
|
||||
MyPostsSectionLink,
|
||||
];
|
||||
|
||||
const MORE_SECTION_LINKS = [GroupsSectionLink, UsersSectionLink];
|
||||
const ADMIN_MAIN_SECTION_LINKS = [AdminSectionLink];
|
||||
|
||||
const MORE_SECTION_LINKS = [
|
||||
GroupsSectionLink,
|
||||
UsersSectionLink,
|
||||
AboutSectionLink,
|
||||
FAQSectionLink,
|
||||
];
|
||||
|
||||
export default class SidebarCommunitySection extends GlimmerComponent {
|
||||
@service router;
|
||||
@ -31,11 +41,16 @@ export default class SidebarCommunitySection extends GlimmerComponent {
|
||||
currentUser: this.currentUser,
|
||||
appEvents: this.appEvents,
|
||||
router: this.router,
|
||||
siteSettings: this.siteSettings,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
sectionLinks = MAIN_SECTION_LINKS.map((sectionLinkClass) => {
|
||||
#mainSectionLinks = this.currentUser.staff
|
||||
? [...MAIN_SECTION_LINKS, ...ADMIN_MAIN_SECTION_LINKS]
|
||||
: [...MAIN_SECTION_LINKS];
|
||||
|
||||
sectionLinks = this.#mainSectionLinks.map((sectionLinkClass) => {
|
||||
return new sectionLinkClass({
|
||||
topicTrackingState: this.topicTrackingState,
|
||||
currentUser: this.currentUser,
|
||||
|
@ -8,6 +8,22 @@ export default class SectionLink extends GlimmerComponent {
|
||||
}
|
||||
}
|
||||
|
||||
get classNames() {
|
||||
return `${this.args.class} sidebar-section-link sidebar-section-link-${this.args.linkName}`;
|
||||
}
|
||||
|
||||
get models() {
|
||||
if (this.args.model) {
|
||||
return [this.args.model];
|
||||
}
|
||||
|
||||
if (this.args.models) {
|
||||
return this.args.models;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
get prefixCSS() {
|
||||
const color = this.args.prefixColor;
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
import I18n from "I18n";
|
||||
|
||||
import BaseSectionLink from "discourse/lib/sidebar/community-section/base-section-link";
|
||||
|
||||
export default class AboutSectionLink extends BaseSectionLink {
|
||||
get name() {
|
||||
return "about";
|
||||
}
|
||||
|
||||
get route() {
|
||||
return "about";
|
||||
}
|
||||
|
||||
get title() {
|
||||
return I18n.t("about.simple_title");
|
||||
}
|
||||
|
||||
get text() {
|
||||
return I18n.t("about.simple_title");
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
import I18n from "I18n";
|
||||
|
||||
import BaseSectionLink from "discourse/lib/sidebar/community-section/base-section-link";
|
||||
|
||||
export default class AdminSectionLink extends BaseSectionLink {
|
||||
get name() {
|
||||
return "admin";
|
||||
}
|
||||
|
||||
get route() {
|
||||
return "admin";
|
||||
}
|
||||
|
||||
get title() {
|
||||
return I18n.t("admin_title");
|
||||
}
|
||||
|
||||
get text() {
|
||||
return I18n.t("admin_title");
|
||||
}
|
||||
}
|
@ -2,11 +2,18 @@
|
||||
* Base class representing a sidebar topics section link interface.
|
||||
*/
|
||||
export default class BaseSectionLink {
|
||||
constructor({ topicTrackingState, currentUser, appEvents, router } = {}) {
|
||||
constructor({
|
||||
topicTrackingState,
|
||||
currentUser,
|
||||
appEvents,
|
||||
router,
|
||||
siteSettings,
|
||||
} = {}) {
|
||||
this.router = router;
|
||||
this.topicTrackingState = topicTrackingState;
|
||||
this.currentUser = currentUser;
|
||||
this.appEvents = appEvents;
|
||||
this.siteSettings = siteSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -28,6 +35,11 @@ export default class BaseSectionLink {
|
||||
this._notImplemented();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} href attribute for the link. This property will take precedence over the `route` property when set.
|
||||
*/
|
||||
get href() {}
|
||||
|
||||
/**
|
||||
* @returns {Object} Model for <LinkTo> component. See https://api.emberjs.com/ember/release/classes/Ember.Templates.components/methods/LinkTo?anchor=LinkTo
|
||||
*/
|
||||
|
@ -0,0 +1,25 @@
|
||||
import I18n from "I18n";
|
||||
|
||||
import BaseSectionLink from "discourse/lib/sidebar/community-section/base-section-link";
|
||||
|
||||
export default class FAQSectionLink extends BaseSectionLink {
|
||||
get name() {
|
||||
return "faq";
|
||||
}
|
||||
|
||||
get route() {
|
||||
return "faq";
|
||||
}
|
||||
|
||||
get href() {
|
||||
return this.siteSettings.faq_url;
|
||||
}
|
||||
|
||||
get title() {
|
||||
return I18n.t("faq");
|
||||
}
|
||||
|
||||
get text() {
|
||||
return I18n.t("faq");
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@
|
||||
{{#each this.sectionLinks as |sectionLink|}}
|
||||
<Sidebar::SectionLink
|
||||
@linkName={{sectionLink.name}}
|
||||
@href={{sectionLink.href}}
|
||||
@route={{sectionLink.route}}
|
||||
@query={{sectionLink.query}}
|
||||
@title={{sectionLink.title}}
|
||||
|
@ -1,17 +1,5 @@
|
||||
<div class="sidebar-footer-wrapper">
|
||||
<div class="sidebar-footer-container">
|
||||
<div class="sidebar-footer-links">
|
||||
<LinkTo @route="about" title={{i18n "about.simple_title"}} class="sidebar-footer-link sidebar-footer-link-about">
|
||||
{{i18n "about.simple_title"}}
|
||||
</LinkTo>
|
||||
|
||||
{{#if this.currentUser.staff}}
|
||||
<LinkTo @route="admin" title={{i18n "admin_title"}} class="sidebar-footer-link sidebar-footer-link-admin">
|
||||
{{i18n "admin_title"}}
|
||||
</LinkTo>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="sidebar-footer-actions">
|
||||
<DButton
|
||||
@action={{route-action "showKeyboardShortcutsHelp"}}
|
||||
|
@ -25,6 +25,7 @@
|
||||
<Sidebar::SectionLink
|
||||
@linkName={{sectionLink.name}}
|
||||
@route={{sectionLink.route}}
|
||||
@href={{sectionLink.href}}
|
||||
@query={{sectionLink.query}}
|
||||
@title={{sectionLink.title}}
|
||||
@content={{sectionLink.text}}
|
||||
|
@ -1,63 +1,71 @@
|
||||
<div class="sidebar-section-link-wrapper">
|
||||
<Sidebar::SectionLinkTo
|
||||
@class={{concat @class (concat " sidebar-section-link sidebar-section-link-" @linkName)}}
|
||||
@route={{@route}}
|
||||
@query={{@query}}
|
||||
@models={{if @model (array @model) (if @models @models (array))}}
|
||||
@current-when={{@currentWhen}}
|
||||
@title={{@title}}
|
||||
>
|
||||
{{#if @prefixValue }}
|
||||
<span class="sidebar-section-link-prefix {{@prefixType}} {{@prefixCSSClass}}" style={{this.prefixCSS}}>
|
||||
{{#if (eq @prefixType "image")}}
|
||||
<img src={{@prefixValue}} class="prefix-image">
|
||||
{{/if}}
|
||||
{{#if @href}}
|
||||
<a href={{@href}} rel="noopener noreferrer" target="_blank" class={{this.classNames}} title={{@title}}>
|
||||
<span class="sidebar-section-link-content-text">
|
||||
{{@content}}
|
||||
</span>
|
||||
</a>
|
||||
{{else}}
|
||||
<Sidebar::SectionLinkTo
|
||||
@class={{this.classNames}}
|
||||
@route={{@route}}
|
||||
@query={{@query}}
|
||||
@models={{this.models}}
|
||||
@current-when={{@currentWhen}}
|
||||
@title={{@title}}
|
||||
>
|
||||
{{#if @prefixValue }}
|
||||
<span class="sidebar-section-link-prefix {{@prefixType}} {{@prefixCSSClass}}" style={{this.prefixCSS}}>
|
||||
{{#if (eq @prefixType "image")}}
|
||||
<img src={{@prefixValue}} class="prefix-image">
|
||||
{{/if}}
|
||||
|
||||
{{#if (eq @prefixType "text")}}
|
||||
{{@prefixValue}}
|
||||
{{/if}}
|
||||
{{#if (eq @prefixType "text")}}
|
||||
{{@prefixValue}}
|
||||
{{/if}}
|
||||
|
||||
{{#if (eq @prefixType "icon")}}
|
||||
{{d-icon @prefixValue class="prefix-icon"}}
|
||||
{{/if}}
|
||||
{{#if (eq @prefixType "icon")}}
|
||||
{{d-icon @prefixValue class="prefix-icon"}}
|
||||
{{/if}}
|
||||
|
||||
{{#if @prefixBadge}}
|
||||
{{d-icon @prefixBadge class="prefix-badge"}}
|
||||
{{/if}}
|
||||
{{#if @prefixBadge}}
|
||||
{{d-icon @prefixBadge class="prefix-badge"}}
|
||||
{{/if}}
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
<span class="sidebar-section-link-content-text">
|
||||
{{@content}}
|
||||
</span>
|
||||
|
||||
{{#if @badgeText}}
|
||||
<span class="sidebar-section-link-content-badge">
|
||||
{{@badgeText}}
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
{{#if @suffixValue}}
|
||||
<span class="sidebar-section-link-suffix {{@suffixType}} {{@suffixCSSClass}}">
|
||||
{{#if (eq @suffixType "icon")}}
|
||||
{{d-icon @suffixValue}}
|
||||
{{/if}}
|
||||
</span>
|
||||
{{/if}}
|
||||
</Sidebar::SectionLinkTo>
|
||||
|
||||
{{#if @hoverValue}}
|
||||
<span class="sidebar-section-link-hover">
|
||||
<button
|
||||
type="button"
|
||||
title={{@hoverTitle}}
|
||||
class="sidebar-section-hover-button"
|
||||
{{on "click" @hoverAction}}
|
||||
>
|
||||
{{#if (eq @hoverType "icon")}}
|
||||
{{d-icon @hoverValue class="hover-icon"}}
|
||||
{{/if}}
|
||||
</button>
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
<span class="sidebar-section-link-content-text">
|
||||
{{@content}}
|
||||
</span>
|
||||
|
||||
{{#if @badgeText}}
|
||||
<span class="sidebar-section-link-content-badge">
|
||||
{{@badgeText}}
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
{{#if @suffixValue}}
|
||||
<span class="sidebar-section-link-suffix {{@suffixType}} {{@suffixCSSClass}}">
|
||||
{{#if (eq @suffixType "icon")}}
|
||||
{{d-icon @suffixValue}}
|
||||
{{/if}}
|
||||
</span>
|
||||
{{/if}}
|
||||
</Sidebar::SectionLinkTo>
|
||||
|
||||
{{#if @hoverValue}}
|
||||
<span class="sidebar-section-link-hover">
|
||||
<button
|
||||
type="button"
|
||||
title={{@hoverTitle}}
|
||||
class="sidebar-section-hover-button"
|
||||
{{on "click" @hoverAction}}
|
||||
>
|
||||
{{#if (eq @hoverType "icon")}}
|
||||
{{d-icon @hoverValue class="hover-icon"}}
|
||||
{{/if}}
|
||||
</button>
|
||||
</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
@ -1,6 +1,11 @@
|
||||
import I18n from "I18n";
|
||||
import { test } from "qunit";
|
||||
import { click, currentURL, visit } from "@ember/test-helpers";
|
||||
import {
|
||||
click,
|
||||
currentRouteName,
|
||||
currentURL,
|
||||
visit,
|
||||
} from "@ember/test-helpers";
|
||||
import {
|
||||
acceptance,
|
||||
count,
|
||||
@ -8,6 +13,7 @@ import {
|
||||
loggedInUser,
|
||||
publishToMessageBus,
|
||||
query,
|
||||
updateCurrentUser,
|
||||
} from "discourse/tests/helpers/qunit-helpers";
|
||||
import topicFixtures from "discourse/tests/fixtures/discovery-fixtures";
|
||||
import { cloneJSON } from "discourse-common/lib/object";
|
||||
@ -293,6 +299,71 @@ acceptance("Sidebar - Community Section", function (needs) {
|
||||
);
|
||||
});
|
||||
|
||||
test("navigating to about from sidebar", async function (assert) {
|
||||
await visit("/");
|
||||
|
||||
await click(
|
||||
".sidebar-section-community .sidebar-more-section-links-details-summary"
|
||||
);
|
||||
|
||||
await click(".sidebar-section-community .sidebar-section-link-about");
|
||||
|
||||
assert.strictEqual(
|
||||
currentURL(),
|
||||
"/about",
|
||||
"navigates to about route correctly"
|
||||
);
|
||||
});
|
||||
|
||||
test("navigating to FAQ from sidebar", async function (assert) {
|
||||
await visit("/");
|
||||
|
||||
await click(
|
||||
".sidebar-section-community .sidebar-more-section-links-details-summary"
|
||||
);
|
||||
|
||||
await click(".sidebar-section-community .sidebar-section-link-faq");
|
||||
|
||||
assert.strictEqual(
|
||||
currentURL(),
|
||||
"/faq",
|
||||
"navigates to faq route correctly"
|
||||
);
|
||||
});
|
||||
|
||||
test("navigating to custom FAQ URL from sidebar", async function (assert) {
|
||||
this.siteSettings.faq_url = "http://some.faq.url";
|
||||
|
||||
await visit("/");
|
||||
|
||||
await click(
|
||||
".sidebar-section-community .sidebar-more-section-links-details-summary"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
query(".sidebar-section-community .sidebar-section-link-faq").href,
|
||||
"http://some.faq.url/",
|
||||
"href attribute is set to custom FAQ URL on the section link"
|
||||
);
|
||||
});
|
||||
|
||||
test("navigating to admin from sidebar", async function (assert) {
|
||||
await visit("/");
|
||||
await click(".sidebar-section-community .sidebar-section-link-admin");
|
||||
|
||||
assert.strictEqual(currentRouteName(), "admin.dashboard.general");
|
||||
});
|
||||
|
||||
test("admin section link is not shown to non-staff users", async function (assert) {
|
||||
updateCurrentUser({ admin: false, moderator: false });
|
||||
|
||||
await visit("/");
|
||||
|
||||
assert.notOk(
|
||||
exists(".sidebar-section-community .sidebar-section-link-admin")
|
||||
);
|
||||
});
|
||||
|
||||
test("clicking on my posts link", async function (assert) {
|
||||
await visit("/t/280");
|
||||
await click(".sidebar-section-community .sidebar-section-link-my-posts");
|
||||
|
@ -1,12 +1,8 @@
|
||||
import I18n from "I18n";
|
||||
|
||||
import { test } from "qunit";
|
||||
import { click, currentRouteName, visit } from "@ember/test-helpers";
|
||||
import {
|
||||
acceptance,
|
||||
exists,
|
||||
updateCurrentUser,
|
||||
} from "discourse/tests/helpers/qunit-helpers";
|
||||
import { click, visit } from "@ember/test-helpers";
|
||||
import { acceptance, exists } from "discourse/tests/helpers/qunit-helpers";
|
||||
|
||||
acceptance("Sidebar - Anon User", function () {
|
||||
// Don't show sidebar for anon user until we know what we want to display
|
||||
@ -98,13 +94,6 @@ acceptance(
|
||||
enable_sidebar: true,
|
||||
});
|
||||
|
||||
test("navigating to about route using sidebar", async function (assert) {
|
||||
await visit("/");
|
||||
await click(".sidebar-footer-link-about");
|
||||
|
||||
assert.strictEqual(currentRouteName(), "about");
|
||||
});
|
||||
|
||||
test("viewing keyboard shortcuts using sidebar", async function (assert) {
|
||||
await visit("/");
|
||||
await click(
|
||||
@ -119,21 +108,6 @@ acceptance(
|
||||
);
|
||||
});
|
||||
|
||||
test("navigating to admin route using sidebar", async function (assert) {
|
||||
await visit("/");
|
||||
await click(".sidebar-footer-link-admin");
|
||||
|
||||
assert.strictEqual(currentRouteName(), "admin.dashboard.general");
|
||||
});
|
||||
|
||||
test("admin link is not shown in sidebar for non-admin user", async function (assert) {
|
||||
updateCurrentUser({ admin: false, moderator: false });
|
||||
|
||||
await visit("/");
|
||||
|
||||
assert.notOk(exists(".sidebar-footer-link-admin"));
|
||||
});
|
||||
|
||||
test("sidebar is disabled on wizard route", async function (assert) {
|
||||
await visit("/wizard");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user