FEATURE: Unseen feature indicator in admin sidebar (#28397)
This commit adds a blue dot next to the "What's New"
link in the admin sidebar if the user has not seen the
new features yet, as a followup to 3e5976f843
which removed the tab on the dashboard that had this same
functionality.
When the admin visits the "What's New" page they count
as having seen all the features straight away. This could
be something we want to change, but for now this keeps the
same functionality.
This commit is contained in:
parent
32195ed77e
commit
31a6d24053
|
@ -0,0 +1,10 @@
|
|||
import { inject as service } from "@ember/service";
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default class AdminWhatsNew extends DiscourseRoute {
|
||||
@service currentUser;
|
||||
|
||||
activate() {
|
||||
this.currentUser.set("has_unseen_features", false);
|
||||
}
|
||||
}
|
|
@ -19,9 +19,15 @@ export function clearAdditionalAdminSidebarSectionLinks() {
|
|||
}
|
||||
|
||||
class SidebarAdminSectionLink extends BaseCustomSidebarSectionLink {
|
||||
constructor({ adminSidebarNavLink, adminSidebarStateManager, router }) {
|
||||
constructor({
|
||||
adminSidebarNavLink,
|
||||
adminSidebarStateManager,
|
||||
router,
|
||||
currentUser,
|
||||
}) {
|
||||
super(...arguments);
|
||||
this.router = router;
|
||||
this.currentUser = currentUser;
|
||||
this.adminSidebarNavLink = adminSidebarNavLink;
|
||||
this.adminSidebarStateManager = adminSidebarStateManager;
|
||||
}
|
||||
|
@ -90,12 +96,38 @@ class SidebarAdminSectionLink extends BaseCustomSidebarSectionLink {
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
get suffixType() {
|
||||
if (this.#hasUnseenFeatures) {
|
||||
return "icon";
|
||||
}
|
||||
}
|
||||
|
||||
get suffixValue() {
|
||||
if (this.#hasUnseenFeatures) {
|
||||
return "circle";
|
||||
}
|
||||
}
|
||||
|
||||
get suffixCSSClass() {
|
||||
if (this.#hasUnseenFeatures) {
|
||||
return "admin-sidebar-nav-link__dot";
|
||||
}
|
||||
}
|
||||
|
||||
get #hasUnseenFeatures() {
|
||||
return (
|
||||
this.adminSidebarNavLink.name === "admin_whats_new" &&
|
||||
this.currentUser.hasUnseenFeatures
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function defineAdminSection(
|
||||
adminNavSectionData,
|
||||
adminSidebarStateManager,
|
||||
router
|
||||
router,
|
||||
currentUser
|
||||
) {
|
||||
const AdminNavSection = class extends BaseCustomSidebarSection {
|
||||
constructor() {
|
||||
|
@ -130,6 +162,7 @@ function defineAdminSection(
|
|||
adminSidebarNavLink: sectionLinkData,
|
||||
adminSidebarStateManager: this.adminSidebarStateManager,
|
||||
router,
|
||||
currentUser,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -349,7 +382,8 @@ export default class AdminSidebarPanel extends BaseCustomSidebarPanel {
|
|||
return defineAdminSection(
|
||||
adminNavSectionData,
|
||||
this.adminSidebarStateManager,
|
||||
router
|
||||
router,
|
||||
currentUser
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -250,6 +250,11 @@ export default class User extends RestModel.extend(Evented) {
|
|||
// prevents staff property to be overridden
|
||||
set staff(value) {}
|
||||
|
||||
@computed("has_unseen_features")
|
||||
get hasUnseenFeatures() {
|
||||
return this.staff && this.get("has_unseen_features");
|
||||
}
|
||||
|
||||
destroySession() {
|
||||
return ajax(`/session/${this.username}`, { type: "DELETE" });
|
||||
}
|
||||
|
|
|
@ -4,3 +4,7 @@
|
|||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-sidebar-nav-link__dot {
|
||||
color: var(--tertiary-med-or-tertiary);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,8 @@ class CurrentUserSerializer < BasicUserSerializer
|
|||
:can_view_raw_email,
|
||||
:use_glimmer_topic_list?,
|
||||
:login_method,
|
||||
:render_experimental_about_page
|
||||
:render_experimental_about_page,
|
||||
:has_unseen_features
|
||||
|
||||
delegate :user_stat, to: :object, private: true
|
||||
delegate :any_posts, :draft_count, :pending_posts_count, :read_faq?, to: :user_stat
|
||||
|
@ -142,6 +143,14 @@ class CurrentUserSerializer < BasicUserSerializer
|
|||
object.staff?
|
||||
end
|
||||
|
||||
def has_unseen_features
|
||||
DiscourseUpdates.has_unseen_features?(object.id)
|
||||
end
|
||||
|
||||
def include_has_unseen_features?
|
||||
object.staff?
|
||||
end
|
||||
|
||||
def render_experimental_about_page
|
||||
object.in_any_groups?(SiteSetting.experimental_redesigned_about_page_groups_map)
|
||||
end
|
||||
|
|
|
@ -2,9 +2,17 @@
|
|||
|
||||
describe "Admin New Features Page", type: :system do
|
||||
let(:new_features_page) { PageObjects::Pages::AdminNewFeatures.new }
|
||||
let(:sidebar) { PageObjects::Components::NavigationMenu::Sidebar.new }
|
||||
fab!(:admin)
|
||||
|
||||
before { sign_in(admin) }
|
||||
before do
|
||||
SiteSetting.navigation_menu = "sidebar"
|
||||
SiteSetting.admin_sidebar_enabled_groups = [
|
||||
Group::AUTO_GROUPS[:admins],
|
||||
Group::AUTO_GROUPS[:moderators],
|
||||
]
|
||||
sign_in(admin)
|
||||
end
|
||||
|
||||
it "displays new features with screenshot taking precedence over emoji" do
|
||||
DiscourseUpdates.stubs(:new_features).returns(
|
||||
|
@ -81,4 +89,17 @@ describe "Admin New Features Page", type: :system do
|
|||
expect(new_features_page).to have_emoji
|
||||
expect(new_features_page).to have_no_screenshot
|
||||
end
|
||||
|
||||
it "displays a new feature indicator on the sidebar and clears it when navigating to what's new" do
|
||||
DiscourseUpdates.stubs(:has_unseen_features?).returns(true)
|
||||
visit "/admin"
|
||||
sidebar.toggle_all_sections
|
||||
expect(sidebar.find_section_link("admin_whats_new")).to have_css(
|
||||
".sidebar-section-link-suffix.admin-sidebar-nav-link__dot",
|
||||
)
|
||||
sidebar.find_section_link("admin_whats_new").click
|
||||
expect(sidebar.find_section_link("admin_whats_new")).to have_no_css(
|
||||
".sidebar-section-link-suffix.admin-sidebar-nav-link__dot",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -132,6 +132,10 @@ module PageObjects
|
|||
expect(section_link["title"]).to eq(title)
|
||||
end
|
||||
|
||||
def find_section_link(name)
|
||||
find(".#{SIDEBAR_SECTION_LINK_SELECTOR}[data-link-name='#{name}']")
|
||||
end
|
||||
|
||||
def primary_section_links(slug)
|
||||
all("[data-section-name='#{slug}'] .sidebar-section-link-wrapper").map(&:text)
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue