mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 09:42:07 +08:00
FEATURE: Add review link to community section for logged in user (#18374)
When there are pending reviewables, the review section link is displayed in the main section. When there are no pending reviewables, the review section link is displayed under the more links drawer. Internal ref: /t/74210
This commit is contained in:
parent
bc97f3d1c1
commit
4b561277a9
|
@ -151,11 +151,11 @@ export default Component.extend({
|
|||
|
||||
// "fast track" to update the current user's reviewable count before the message bus finds out.
|
||||
if (performResult.reviewable_count !== undefined) {
|
||||
this.currentUser.set(
|
||||
"reviewable_count",
|
||||
this.currentUser.updateReviewableCount(
|
||||
performResult.reviewable_count
|
||||
);
|
||||
}
|
||||
|
||||
if (performResult.unseen_reviewable_count !== undefined) {
|
||||
this.currentUser.set(
|
||||
"unseen_reviewable_count",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Component from "@glimmer/component";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
|
||||
import {
|
||||
customSectionLinks,
|
||||
|
@ -13,29 +14,18 @@ export default class SidebarCommunitySection extends Component {
|
|||
@service appEvents;
|
||||
@service siteSettings;
|
||||
|
||||
@tracked sectionLinks;
|
||||
@tracked moreSectionLinks;
|
||||
@tracked moreSecondarySectionLinks;
|
||||
|
||||
callbackId;
|
||||
headerActionsIcon;
|
||||
headerActions;
|
||||
sectionLinks;
|
||||
moreSectionLinks;
|
||||
moreSecondarySectionLinks;
|
||||
callbackId;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
||||
this.moreSectionLinks = this.#initializeSectionLinks([
|
||||
...this.defaultMoreSectionLinks,
|
||||
...customSectionLinks,
|
||||
]);
|
||||
|
||||
this.moreSecondarySectionLinks = this.#initializeSectionLinks([
|
||||
...this.defaultMoreSecondarySectionLinks,
|
||||
...secondaryCustomSectionLinks,
|
||||
]);
|
||||
|
||||
this.sectionLinks = this.#initializeSectionLinks(
|
||||
this.defaultMainSectionLinks
|
||||
);
|
||||
this.refreshSectionLinks();
|
||||
|
||||
this.callbackId = this.topicTrackingState.onStateChange(() => {
|
||||
this.sectionLinks.forEach((sectionLink) => {
|
||||
|
@ -64,6 +54,22 @@ export default class SidebarCommunitySection extends Component {
|
|||
return [];
|
||||
}
|
||||
|
||||
refreshSectionLinks() {
|
||||
this.moreSectionLinks = this.#initializeSectionLinks([
|
||||
...this.defaultMoreSectionLinks,
|
||||
...customSectionLinks,
|
||||
]);
|
||||
|
||||
this.moreSecondarySectionLinks = this.#initializeSectionLinks([
|
||||
...this.defaultMoreSecondarySectionLinks,
|
||||
...secondaryCustomSectionLinks,
|
||||
]);
|
||||
|
||||
this.sectionLinks = this.#initializeSectionLinks(
|
||||
this.defaultMainSectionLinks
|
||||
);
|
||||
}
|
||||
|
||||
#initializeSectionLinks(sectionLinkClasses) {
|
||||
return sectionLinkClasses.reduce((links, sectionLinkClass) => {
|
||||
const sectionLink = this.#initializeSectionLink(sectionLinkClass);
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
{{did-insert this.registerClickListener}}
|
||||
{{will-destroy this.unregisterClickListener}} >
|
||||
|
||||
<div class="sidebar-more-section-link-details-content">
|
||||
<div class="sidebar-more-section-links-details-content">
|
||||
<div class="sidebar-more-section-links-details-content-main">
|
||||
{{#each this.sectionLinks as |sectionLink|}}
|
||||
<Sidebar::MoreSectionLink @sectionLink={{sectionLink}} />
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import I18n from "I18n";
|
||||
|
||||
import { bind } from "discourse-common/utils/decorators";
|
||||
import Composer from "discourse/models/composer";
|
||||
import { getOwner } from "discourse-common/lib/get-owner";
|
||||
import PermissionType from "discourse/models/permission-type";
|
||||
|
@ -12,6 +13,7 @@ import AboutSectionLink from "discourse/lib/sidebar/common/community-section/abo
|
|||
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 BadgesSectionLink from "discourse/lib/sidebar/common/community-section/badges-section-link";
|
||||
import ReviewSectionLink from "discourse/lib/sidebar/user/community-section/review-section-link";
|
||||
import SidebarCommonCommunitySection from "discourse/components/sidebar/common/community-section";
|
||||
|
||||
import { action } from "@ember/object";
|
||||
|
@ -29,19 +31,48 @@ export default class SidebarUserCommunitySection extends SidebarCommonCommunityS
|
|||
title: I18n.t("sidebar.sections.community.header_action_title"),
|
||||
},
|
||||
];
|
||||
|
||||
this.appEvents.on(
|
||||
"user-reviewable-count:changed",
|
||||
this._refreshSectionLinks
|
||||
);
|
||||
}
|
||||
|
||||
willDestroy() {
|
||||
this.appEvents.off(
|
||||
"user-reviewable-count:changed",
|
||||
this._refreshSectionLinks
|
||||
);
|
||||
}
|
||||
|
||||
@bind
|
||||
_refreshSectionLinks() {
|
||||
return this.refreshSectionLinks();
|
||||
}
|
||||
|
||||
get defaultMainSectionLinks() {
|
||||
return [
|
||||
const links = [
|
||||
EverythingSectionLink,
|
||||
TrackedSectionLink,
|
||||
MyPostsSectionLink,
|
||||
AdminSectionLink,
|
||||
];
|
||||
|
||||
if (this.currentUser.reviewable_count > 0) {
|
||||
links.push(ReviewSectionLink);
|
||||
}
|
||||
|
||||
return links;
|
||||
}
|
||||
|
||||
get defaultMoreSectionLinks() {
|
||||
return [GroupsSectionLink, UsersSectionLink, BadgesSectionLink];
|
||||
const links = [GroupsSectionLink, UsersSectionLink, BadgesSectionLink];
|
||||
|
||||
if (this.currentUser.reviewable_count === 0) {
|
||||
links.push(ReviewSectionLink);
|
||||
}
|
||||
|
||||
return links;
|
||||
}
|
||||
|
||||
get defaultMoreSecondarySectionLinks() {
|
||||
|
|
|
@ -28,10 +28,12 @@ export default {
|
|||
const channel = user.enable_redesigned_user_menu
|
||||
? `/reviewable_counts/${user.id}`
|
||||
: "/reviewable_counts";
|
||||
|
||||
bus.subscribe(channel, (data) => {
|
||||
if (data.reviewable_count >= 0) {
|
||||
user.set("reviewable_count", data.reviewable_count);
|
||||
user.updateReviewableCount(data.reviewable_count);
|
||||
}
|
||||
|
||||
if (user.redesigned_user_menu_enabled) {
|
||||
user.set("unseen_reviewable_count", data.unseen_reviewable_count);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import I18n from "I18n";
|
||||
|
||||
import BaseSectionLink from "discourse/lib/sidebar/base-community-section-link";
|
||||
|
||||
export default class ReviewSectionLink extends BaseSectionLink {
|
||||
get name() {
|
||||
return "review";
|
||||
}
|
||||
|
||||
get route() {
|
||||
return "review";
|
||||
}
|
||||
|
||||
get title() {
|
||||
return I18n.t("sidebar.sections.community.links.review.title");
|
||||
}
|
||||
|
||||
get text() {
|
||||
return I18n.t("sidebar.sections.community.links.review.content");
|
||||
}
|
||||
|
||||
get shouldDisplay() {
|
||||
return this.currentUser.can_review;
|
||||
}
|
||||
|
||||
get badgeText() {
|
||||
if (this.currentUser.reviewable_count > 0) {
|
||||
return I18n.t("sidebar.sections.community.links.review.pending_count", {
|
||||
count: this.currentUser.reviewable_count,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1059,6 +1059,11 @@ const User = RestModel.extend({
|
|||
this.appEvents.trigger("user-drafts:changed");
|
||||
},
|
||||
|
||||
updateReviewableCount(count) {
|
||||
this.set("reviewable_count", count);
|
||||
this.appEvents.trigger("user-reviewable-count:changed", count);
|
||||
},
|
||||
|
||||
isInDoNotDisturb() {
|
||||
return (
|
||||
this.do_not_disturb_until &&
|
||||
|
|
|
@ -68,6 +68,7 @@ export default DiscourseRoute.extend({
|
|||
const channel = this.currentUser.enable_redesigned_user_menu
|
||||
? `/reviewable_counts/${this.currentUser.id}`
|
||||
: "/reviewable_counts";
|
||||
|
||||
this.messageBus.subscribe(channel, (data) => {
|
||||
if (data.updates) {
|
||||
this.controller.reviewables.forEach((reviewable) => {
|
||||
|
@ -82,10 +83,6 @@ export default DiscourseRoute.extend({
|
|||
|
||||
deactivate() {
|
||||
this.messageBus.unsubscribe("/reviewable_claimed");
|
||||
const channel = this.currentUser.enable_redesigned_user_menu
|
||||
? `/reviewable_counts/${this.currentUser.id}`
|
||||
: "/reviewable_counts";
|
||||
this.messageBus.unsubscribe(channel);
|
||||
},
|
||||
|
||||
@action
|
||||
|
|
|
@ -710,6 +710,86 @@ acceptance("Sidebar - Logged on user - Community Section", function (needs) {
|
|||
);
|
||||
});
|
||||
|
||||
test("review link is not shown when user cannot review", async function (assert) {
|
||||
updateCurrentUser({ can_review: false });
|
||||
|
||||
await visit("/");
|
||||
|
||||
assert.notOk(
|
||||
exists(".sidebar-section-community .sidebar-section-link-review"),
|
||||
"review link is not shown"
|
||||
);
|
||||
|
||||
await click(
|
||||
".sidebar-section-community .sidebar-more-section-links-details-summary"
|
||||
);
|
||||
|
||||
assert.notOk(
|
||||
exists(".sidebar-section-community .sidebar-section-link-review"),
|
||||
"review link is not shown"
|
||||
);
|
||||
});
|
||||
|
||||
test("review link when user can review", async function (assert) {
|
||||
updateCurrentUser({
|
||||
can_review: true,
|
||||
reviewable_count: 0,
|
||||
});
|
||||
|
||||
await visit("/reivew");
|
||||
|
||||
assert.notOk(
|
||||
exists(".sidebar-section-community .sidebar-section-link-review.active"),
|
||||
"review link is shown as active when visiting the review route even if there are no pending reviewables"
|
||||
);
|
||||
|
||||
await visit("/");
|
||||
|
||||
assert.notOk(
|
||||
exists(".sidebar-section-community .sidebar-section-link-review"),
|
||||
"review link is not shown as part of the main section links"
|
||||
);
|
||||
|
||||
await click(
|
||||
".sidebar-section-community .sidebar-more-section-links-details-summary"
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
exists(
|
||||
".sidebar-section-community .sidebar-more-section-links-details-content .sidebar-section-link-review"
|
||||
),
|
||||
"review link is displayed in the more drawer"
|
||||
);
|
||||
|
||||
await publishToMessageBus("/reviewable_counts", {
|
||||
reviewable_count: 34,
|
||||
});
|
||||
|
||||
assert.ok(
|
||||
exists(".sidebar-section-community .sidebar-section-link-review"),
|
||||
"review link is shown as part of the main section links"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
query(
|
||||
".sidebar-section-community .sidebar-section-link-review .sidebar-section-link-content-badge"
|
||||
).textContent.trim(),
|
||||
"34 pending",
|
||||
"displays the pending reviewable count"
|
||||
);
|
||||
|
||||
await click(
|
||||
".sidebar-section-community .sidebar-more-section-links-details-summary"
|
||||
);
|
||||
|
||||
assert.notOk(
|
||||
exists(
|
||||
".sidebar-section-community .sidebar-more-section-links-details-content .sidebar-section-link-review"
|
||||
),
|
||||
"review link is not displayed in the more drawer"
|
||||
);
|
||||
});
|
||||
|
||||
test("new and unread count for tracked link", async function (assert) {
|
||||
const categories = Site.current().categories;
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
background: transparent;
|
||||
}
|
||||
|
||||
.sidebar-more-section-link-details-content {
|
||||
.sidebar-more-section-links-details-content {
|
||||
background-color: var(--secondary);
|
||||
box-shadow: shadow("dropdown");
|
||||
margin: 0 calc(var(--d-sidebar-row-horizontal-padding) * 2 / 3);
|
||||
|
|
|
@ -71,6 +71,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
.sidebar-section-link-review {
|
||||
.sidebar-section-link-content-badge {
|
||||
color: var(--danger);
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-section-link-prefix {
|
||||
flex-shrink: 0;
|
||||
|
||||
|
|
|
@ -4196,6 +4196,10 @@ en:
|
|||
draft_count:
|
||||
one: "%{count} draft"
|
||||
other: "%{count} drafts"
|
||||
review:
|
||||
content: "Review"
|
||||
title: "review"
|
||||
pending_count: "%{count} pending"
|
||||
|
||||
welcome_topic_banner:
|
||||
title: "Create your Welcome Topic"
|
||||
|
|
Loading…
Reference in New Issue
Block a user