diff --git a/app/assets/javascripts/discourse/app/controllers/preferences/navigation-menu.js b/app/assets/javascripts/discourse/app/controllers/preferences/navigation-menu.js index 583abbec60e..9ec75d04f30 100644 --- a/app/assets/javascripts/discourse/app/controllers/preferences/navigation-menu.js +++ b/app/assets/javascripts/discourse/app/controllers/preferences/navigation-menu.js @@ -5,36 +5,27 @@ import I18n from "I18n"; import { popupAjaxError } from "discourse/lib/ajax-error"; -export const DEFAULT_LIST_DESTINATION = "default"; -export const UNREAD_LIST_DESTINATION = "unread_new"; - export default class extends Controller { @tracked saved = false; @tracked selectedSidebarCategories = []; @tracked selectedSidebarTagNames = []; + subpageTitle = I18n.t("user.preferences_nav.navigation_menu"); saveAttrNames = [ "sidebar_category_ids", "sidebar_tag_names", - "sidebar_list_destination", - ]; - - sidebarListDestinations = [ - { - name: I18n.t("user.experimental_sidebar.list_destination_default"), - value: DEFAULT_LIST_DESTINATION, - }, - { - name: I18n.t("user.experimental_sidebar.list_destination_unread_new"), - value: UNREAD_LIST_DESTINATION, - }, + "sidebar_link_to_filtered_list", + "sidebar_show_count_of_new_items", ]; @action save() { const initialSidebarCategoryIds = this.model.sidebarCategoryIds; - const initialSidebarListDestination = this.model.sidebar_list_destination; + const initialSidebarLinkToFilteredList = + this.model.sidebarLinkToFilteredList; + const initialSidebarShowCountOfNewItems = + this.model.sidebarShowCountOfNewItems; this.model.set( "sidebarCategoryIds", @@ -44,8 +35,12 @@ export default class extends Controller { this.model.set("sidebar_tag_names", this.selectedSidebarTagNames); this.model.set( - "user_option.sidebar_list_destination", - this.newSidebarListDestination + "user_option.sidebar_link_to_filtered_list", + this.newSidebarLinkToFilteredList + ); + this.model.set( + "user_option.sidebar_show_count_of_new_items", + this.newSidebarShowCountOfNewItems ); this.model @@ -54,22 +49,24 @@ export default class extends Controller { if (result.user.sidebar_tags) { this.model.set("sidebar_tags", result.user.sidebar_tags); } - this.model.set( - "sidebar_list_destination", - this.newSidebarListDestination - ); this.saved = true; }) .catch((error) => { this.model.set("sidebarCategoryIds", initialSidebarCategoryIds); + this.model.set( + "user_option.sidebar_link_to_filtered_list", + initialSidebarLinkToFilteredList + ); + this.model.set( + "user_option.sidebar_show_count_of_new_items", + initialSidebarShowCountOfNewItems + ); + popupAjaxError(error); }) .finally(() => { this.model.set("sidebar_tag_names", []); - if (initialSidebarListDestination !== this.newSidebarListDestination) { - window.location.reload(); - } }); } } diff --git a/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/everything-section-link.js b/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/everything-section-link.js index c541ad9b0c7..61657ada2ea 100644 --- a/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/everything-section-link.js +++ b/app/assets/javascripts/discourse/app/lib/sidebar/common/community-section/everything-section-link.js @@ -2,13 +2,10 @@ import I18n from "I18n"; import { tracked } from "@glimmer/tracking"; import BaseSectionLink from "discourse/lib/sidebar/base-community-section-link"; -import { UNREAD_LIST_DESTINATION } from "discourse/controllers/preferences/navigation-menu"; export default class EverythingSectionLink extends BaseSectionLink { @tracked totalUnread = 0; @tracked totalNew = 0; - @tracked hideCount = - this.currentUser?.sidebarListDestination !== UNREAD_LIST_DESTINATION; constructor() { super(...arguments); @@ -26,11 +23,15 @@ export default class EverythingSectionLink extends BaseSectionLink { this.totalUnread = this.topicTrackingState.countUnread(); - if (this.totalUnread === 0 || this.#linkToNew) { + if (this.totalUnread === 0 || this.#newNewViewEnabled) { this.totalNew = this.topicTrackingState.countNew(); } } + get showCount() { + return this.currentUser?.sidebarShowCountOfNewItems; + } + get name() { return "everything"; } @@ -55,16 +56,13 @@ export default class EverythingSectionLink extends BaseSectionLink { } get badgeText() { - if (this.#linkToNew) { - if (this.#unreadAndNewCount > 0) { - return this.#unreadAndNewCount.toString(); - } + if (!this.showCount) { return; } - if (this.hideCount) { - return; - } - if (this.totalUnread > 0) { + + if (this.#newNewViewEnabled && this.#unreadAndNewCount > 0) { + return this.#unreadAndNewCount.toString(); + } else if (this.totalUnread > 0) { return I18n.t("sidebar.unread_count", { count: this.totalUnread, }); @@ -76,19 +74,12 @@ export default class EverythingSectionLink extends BaseSectionLink { } get route() { - if (this.#linkToNew) { - if (this.#unreadAndNewCount > 0) { + if (this.currentUser?.sidebarLinkToFilteredList) { + if (this.#newNewViewEnabled && this.#unreadAndNewCount > 0) { return "discovery.new"; - } else { - return "discovery.latest"; - } - } else if ( - this.currentUser?.sidebarListDestination === UNREAD_LIST_DESTINATION - ) { - if (this.totalUnread > 0) { + } else if (this.totalUnread > 0) { return "discovery.unread"; - } - if (this.totalNew > 0) { + } else if (this.totalNew > 0) { return "discovery.new"; } } @@ -108,11 +99,7 @@ export default class EverythingSectionLink extends BaseSectionLink { } get suffixValue() { - if ( - this.hideCount && - (this.totalUnread || this.totalNew) && - !this.#linkToNew - ) { + if (!this.showCount && (this.totalUnread || this.totalNew)) { return "circle"; } } @@ -121,7 +108,7 @@ export default class EverythingSectionLink extends BaseSectionLink { return this.totalUnread + this.totalNew; } - get #linkToNew() { + get #newNewViewEnabled() { return !!this.currentUser?.new_new_view_enabled; } } diff --git a/app/assets/javascripts/discourse/app/lib/sidebar/user/categories-section/category-section-link.js b/app/assets/javascripts/discourse/app/lib/sidebar/user/categories-section/category-section-link.js index 26fcf5720f7..43fae208a45 100644 --- a/app/assets/javascripts/discourse/app/lib/sidebar/user/categories-section/category-section-link.js +++ b/app/assets/javascripts/discourse/app/lib/sidebar/user/categories-section/category-section-link.js @@ -5,7 +5,6 @@ import { get, set } from "@ember/object"; import { bind } from "discourse-common/utils/decorators"; import Category from "discourse/models/category"; -import { UNREAD_LIST_DESTINATION } from "discourse/controllers/preferences/navigation-menu"; const UNREAD_AND_NEW_COUNTABLE = { propertyName: "unreadAndNewCount", @@ -120,7 +119,7 @@ export default class CategorySectionLink { #countables() { const countables = []; - if (this.#linkToNew) { + if (this.#newNewViewEnabled) { countables.push(UNREAD_AND_NEW_COUNTABLE); } else { countables.push(...DEFAULT_COUNTABLES); @@ -149,8 +148,8 @@ export default class CategorySectionLink { return countables; } - get hideCount() { - return this.currentUser?.sidebarListDestination !== UNREAD_LIST_DESTINATION; + get showCount() { + return this.currentUser?.sidebarShowCountOfNewItems; } @bind @@ -221,7 +220,7 @@ export default class CategorySectionLink { } get badgeText() { - if (this.hideCount && !this.#linkToNew) { + if (!this.showCount) { return; } @@ -235,10 +234,7 @@ export default class CategorySectionLink { } get route() { - if ( - this.currentUser?.sidebarListDestination === UNREAD_LIST_DESTINATION || - this.#linkToNew - ) { + if (this.currentUser?.sidebarLinkToFilteredList) { const activeCountable = this.activeCountable; if (activeCountable) { @@ -250,7 +246,7 @@ export default class CategorySectionLink { } get query() { - if (this.currentUser?.sidebarListDestination === UNREAD_LIST_DESTINATION) { + if (this.currentUser?.sidebarLinkToFilteredList) { const activeCountable = this.activeCountable; if (activeCountable?.routeQuery) { @@ -268,12 +264,12 @@ export default class CategorySectionLink { } get suffixValue() { - if (this.hideCount && this.activeCountable && !this.#linkToNew) { + if (!this.showCount && this.activeCountable) { return "circle"; } } - get #linkToNew() { + get #newNewViewEnabled() { return !!this.currentUser?.new_new_view_enabled; } } diff --git a/app/assets/javascripts/discourse/app/lib/sidebar/user/community-section/my-posts-section-link.js b/app/assets/javascripts/discourse/app/lib/sidebar/user/community-section/my-posts-section-link.js index cc3b9988ed1..033143f430c 100644 --- a/app/assets/javascripts/discourse/app/lib/sidebar/user/community-section/my-posts-section-link.js +++ b/app/assets/javascripts/discourse/app/lib/sidebar/user/community-section/my-posts-section-link.js @@ -2,14 +2,11 @@ import I18n from "I18n"; import { tracked } from "@glimmer/tracking"; import BaseSectionLink from "discourse/lib/sidebar/base-community-section-link"; -import { UNREAD_LIST_DESTINATION } from "discourse/controllers/preferences/navigation-menu"; const USER_DRAFTS_CHANGED_EVENT = "user-drafts:changed"; export default class MyPostsSectionLink extends BaseSectionLink { @tracked draftCount = this.currentUser?.draft_count; - @tracked hideCount = - this.currentUser?.sidebarListDestination !== UNREAD_LIST_DESTINATION; constructor() { super(...arguments); @@ -37,6 +34,10 @@ export default class MyPostsSectionLink extends BaseSectionLink { this.draftCount = this.currentUser.draft_count; } + get showCount() { + return this.currentUser.sidebarShowCountOfNewItems; + } + get name() { return "my-posts"; } @@ -81,10 +82,13 @@ export default class MyPostsSectionLink extends BaseSectionLink { } get badgeText() { - if (this._hasDraft && this.currentUser?.new_new_view_enabled) { - return this.draftCount.toString(); + if (!this.showCount || !this._hasDraft) { + return; } - if (this._hasDraft && !this.hideCount) { + + if (this.currentUser.new_new_view_enabled) { + return this.draftCount.toString(); + } else { return I18n.t("sidebar.sections.community.links.my_posts.draft_count", { count: this.draftCount, }); @@ -111,7 +115,7 @@ export default class MyPostsSectionLink extends BaseSectionLink { } get suffixValue() { - if (this._hasDraft && this.hideCount) { + if (this._hasDraft && !this.showCount) { return "circle"; } } diff --git a/app/assets/javascripts/discourse/app/lib/sidebar/user/tags-section/tag-section-link.js b/app/assets/javascripts/discourse/app/lib/sidebar/user/tags-section/tag-section-link.js index 4f5d188c8c7..0aaaf5451bd 100644 --- a/app/assets/javascripts/discourse/app/lib/sidebar/user/tags-section/tag-section-link.js +++ b/app/assets/javascripts/discourse/app/lib/sidebar/user/tags-section/tag-section-link.js @@ -4,13 +4,10 @@ import { tracked } from "@glimmer/tracking"; import { bind } from "discourse-common/utils/decorators"; import BaseTagSectionLink from "discourse/lib/sidebar/user/tags-section/base-tag-section-link"; -import { UNREAD_LIST_DESTINATION } from "discourse/controllers/preferences/navigation-menu"; export default class TagSectionLink extends BaseTagSectionLink { @tracked totalUnread = 0; @tracked totalNew = 0; - @tracked hideCount = - this.currentUser?.sidebarListDestination !== UNREAD_LIST_DESTINATION; constructor({ topicTrackingState }) { super(...arguments); @@ -24,30 +21,28 @@ export default class TagSectionLink extends BaseTagSectionLink { tagId: this.tagName, }); - if (this.totalUnread === 0 || this.#linkToNew) { + if (this.totalUnread === 0 || this.#newNewViewEnabled) { this.totalNew = this.topicTrackingState.countNew({ tagId: this.tagName, }); } } + get showCount() { + return this.currentUser?.sidebarShowCountOfNewItems; + } + get models() { return [this.tagName]; } get route() { - if (this.#linkToNew) { - if (this.#unreadAndNewCount > 0) { + if (this.currentUser?.sidebarLinkToFilteredList) { + if (this.#newNewViewEnabled && this.#unreadAndNewCount > 0) { return "tag.showNew"; - } else { - return "tag.show"; - } - } - if (this.currentUser?.sidebarListDestination === UNREAD_LIST_DESTINATION) { - if (this.totalUnread > 0) { + } else if (this.totalUnread > 0) { return "tag.showUnread"; - } - if (this.totalNew > 0) { + } else if (this.totalNew > 0) { return "tag.showNew"; } } @@ -59,17 +54,13 @@ export default class TagSectionLink extends BaseTagSectionLink { } get badgeText() { - if (this.#linkToNew) { - if (this.#unreadAndNewCount > 0) { - return this.#unreadAndNewCount.toString(); - } + if (!this.showCount) { return; } - if (this.hideCount) { - return; - } - if (this.totalUnread > 0) { + if (this.#newNewViewEnabled && this.#unreadAndNewCount > 0) { + return this.#unreadAndNewCount.toString(); + } else if (this.totalUnread > 0) { return I18n.t("sidebar.unread_count", { count: this.totalUnread, }); @@ -89,11 +80,7 @@ export default class TagSectionLink extends BaseTagSectionLink { } get suffixValue() { - if ( - this.hideCount && - (this.totalUnread || this.totalNew) && - !this.#linkToNew - ) { + if (!this.showCount && (this.totalUnread || this.totalNew)) { return "circle"; } } @@ -102,7 +89,7 @@ export default class TagSectionLink extends BaseTagSectionLink { return this.totalUnread + this.totalNew; } - get #linkToNew() { + get #newNewViewEnabled() { return !!this.currentUser?.new_new_view_enabled; } } diff --git a/app/assets/javascripts/discourse/app/models/user.js b/app/assets/javascripts/discourse/app/models/user.js index 30f327232c6..b861f48564f 100644 --- a/app/assets/javascripts/discourse/app/models/user.js +++ b/app/assets/javascripts/discourse/app/models/user.js @@ -2,15 +2,7 @@ import EmberObject, { computed, get, getProperties } from "@ember/object"; import { camelize } from "@ember/string"; import cookie, { removeCookie } from "discourse/lib/cookie"; import { defaultHomepage, escapeExpression } from "discourse/lib/utilities"; -import { - alias, - equal, - filterBy, - gt, - mapBy, - or, - readOnly, -} from "@ember/object/computed"; +import { alias, equal, filterBy, gt, mapBy, or } from "@ember/object/computed"; import getURL, { getURLWithCDN } from "discourse-common/lib/get-url"; import { A } from "@ember/array"; import Badge from "discourse/models/badge"; @@ -137,7 +129,8 @@ let userOptionFields = [ "seen_popups", "default_calendar", "bookmark_auto_delete_preference", - "sidebar_list_destination", + "sidebar_link_to_filtered_list", + "sidebar_show_count_of_new_items", ]; export function addSaveableUserOptionField(fieldName) { @@ -410,7 +403,6 @@ const User = RestModel.extend({ sidebarSections: alias("sidebar_sections"), sidebarTagNames: mapBy("sidebarTags", "name"), - sidebarListDestination: readOnly("sidebar_list_destination"), changeUsername(new_username) { return ajax(userPath(`${this.username_lower}/preferences/username`), { @@ -919,6 +911,16 @@ const User = RestModel.extend({ return !this.siteSettings.enable_discourse_connect && canDeleteAccount; }, + @dependentKeyCompat + get sidebarLinkToFilteredList() { + return this.get("user_option.sidebar_link_to_filtered_list"); + }, + + @dependentKeyCompat + get sidebarShowCountOfNewItems() { + return this.get("user_option.sidebar_show_count_of_new_items"); + }, + delete() { if (this.can_delete_account) { return ajax(userPath(this.username + ".json"), { diff --git a/app/assets/javascripts/discourse/app/routes/preferences-navigation-menu.js b/app/assets/javascripts/discourse/app/routes/preferences-navigation-menu.js index a82ac9a5815..8f01ffdfe56 100644 --- a/app/assets/javascripts/discourse/app/routes/preferences-navigation-menu.js +++ b/app/assets/javascripts/discourse/app/routes/preferences-navigation-menu.js @@ -8,12 +8,13 @@ export default RestrictedUserRoute.extend({ const props = { model: user, selectedSidebarCategories: Category.findByIds(user.sidebarCategoryIds), + newSidebarLinkToFilteredList: user.sidebarLinkToFilteredList, + newSidebarShowCountOfNewItems: user.sidebarShowCountOfNewItems, }; if (this.siteSettings.tagging_enabled) { props.selectedSidebarTagNames = user.sidebarTagNames; } - props.newSidebarListDestination = user.sidebarListDestination; controller.setProperties(props); }, diff --git a/app/assets/javascripts/discourse/app/templates/preferences/navigation-menu.hbs b/app/assets/javascripts/discourse/app/templates/preferences/navigation-menu.hbs index 2de39d91d4a..ce03f6496e5 100644 --- a/app/assets/javascripts/discourse/app/templates/preferences/navigation-menu.hbs +++ b/app/assets/javascripts/discourse/app/templates/preferences/navigation-menu.hbs @@ -46,16 +46,20 @@ "user.experimental_sidebar.navigation_section" }} -
+
- +
diff --git a/app/assets/javascripts/discourse/tests/acceptance/sidebar-plugin-api-test.js b/app/assets/javascripts/discourse/tests/acceptance/sidebar-plugin-api-test.js index 81e57e843c1..879271a56ba 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/sidebar-plugin-api-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/sidebar-plugin-api-test.js @@ -16,7 +16,6 @@ import { resetCustomCountables, } from "discourse/lib/sidebar/user/categories-section/category-section-link"; import { resetCustomTagSectionLinkPrefixIcons } from "discourse/lib/sidebar/user/tags-section/base-tag-section-link"; -import { UNREAD_LIST_DESTINATION } from "discourse/controllers/preferences/navigation-menu"; import { bind } from "discourse-common/utils/decorators"; acceptance("Sidebar - Plugin API", function (needs) { @@ -713,7 +712,10 @@ acceptance("Sidebar - Plugin API", function (needs) { ); updateCurrentUser({ - sidebar_list_destination: UNREAD_LIST_DESTINATION, + user_option: { + sidebar_link_to_filtered_list: true, + sidebar_show_count_of_new_items: true, + }, }); assert.strictEqual( diff --git a/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-categories-section-test.js b/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-categories-section-test.js index 146aa2a970e..407a681cfd0 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-categories-section-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-categories-section-test.js @@ -480,9 +480,11 @@ acceptance("Sidebar - Logged on user - Categories Section", function (needs) { ); }); - test("clicking section links - sidebar_list_destination set to unread/new and no unread or new topics", async function (assert) { + test("clicking section links - sidebar_link_to_filtered_list set to true and no unread or new topics", async function (assert) { updateCurrentUser({ - sidebar_list_destination: "unread_new", + user_option: { + sidebar_link_to_filtered_list: true, + }, }); const { category1 } = setupUserSidebarCategories(); @@ -514,7 +516,7 @@ acceptance("Sidebar - Logged on user - Categories Section", function (needs) { ); }); - test("clicking section links - sidebar_list_destination set to unread/new with new topics", async function (assert) { + test("clicking section links - sidebar_link_to_filtered_list set to true with new topics", async function (assert) { const { category1 } = setupUserSidebarCategories(); const topicTrackingState = this.container.lookup( "service:topic-tracking-state" @@ -527,7 +529,9 @@ acceptance("Sidebar - Logged on user - Categories Section", function (needs) { created_in_new_period: true, }); updateCurrentUser({ - sidebar_list_destination: "unread_new", + user_option: { + sidebar_link_to_filtered_list: true, + }, }); await visit("/"); @@ -558,7 +562,7 @@ acceptance("Sidebar - Logged on user - Categories Section", function (needs) { ); }); - test("clicking section links - sidebar_list_destination set to unread/new with new and unread topics", async function (assert) { + test("clicking section links - sidebar_link_to_filtered_list set to true with new and unread topics", async function (assert) { const { category1 } = setupUserSidebarCategories(); const topicTrackingState = this.container.lookup( "service:topic-tracking-state" @@ -579,7 +583,9 @@ acceptance("Sidebar - Logged on user - Categories Section", function (needs) { created_in_new_period: true, }); updateCurrentUser({ - sidebar_list_destination: "unread_new", + user_option: { + sidebar_link_to_filtered_list: true, + }, }); await visit("/"); @@ -754,7 +760,9 @@ acceptance("Sidebar - Logged on user - Categories Section", function (needs) { const { category1 } = setupUserSidebarCategories(); updateCurrentUser({ - sidebar_list_destination: "default", + user_option: { + sidebar_show_count_of_new_items: false, + }, }); this.container.lookup("service:topic-tracking-state").loadStates([ @@ -826,7 +834,9 @@ acceptance("Sidebar - Logged on user - Categories Section", function (needs) { const { category1, category2 } = setupUserSidebarCategories(); updateCurrentUser({ - sidebar_list_destination: "unread_new", + user_option: { + sidebar_show_count_of_new_items: true, + }, }); this.container.lookup("service:topic-tracking-state").loadStates([ @@ -995,7 +1005,7 @@ acceptance( needs.user({ new_new_view_enabled: true }); - test("count shown next to category link", async function (assert) { + test("count shown next to category link when sidebar_show_count_of_new_items is true", async function (assert) { const categories = Site.current().categories; const category1 = categories[0]; const category2 = categories[1]; @@ -1003,6 +1013,9 @@ acceptance( updateCurrentUser({ sidebar_category_ids: [category1.id, category2.id, category3.id], + user_option: { + sidebar_show_count_of_new_items: true, + }, }); this.container.lookup("service:topic-tracking-state").loadStates([ @@ -1085,7 +1098,7 @@ acceptance( ); }); - test("category link href", async function (assert) { + test("dot shown next to category link when sidebar_show_count_of_new_items is false", async function (assert) { const categories = Site.current().categories; const category1 = categories[0]; const category2 = categories[1]; @@ -1093,6 +1106,66 @@ acceptance( updateCurrentUser({ sidebar_category_ids: [category1.id, category2.id, category3.id], + user_option: { + sidebar_show_count_of_new_items: false, + }, + }); + + this.container.lookup("service:topic-tracking-state").loadStates([ + { + topic_id: 1, + highest_post_number: 1, + last_read_post_number: null, + created_at: "2022-05-11T03:09:31.959Z", + category_id: category1.id, + notification_level: null, + created_in_new_period: true, + treat_as_new_topic_start_date: "2022-05-09T03:17:34.286Z", + }, + { + topic_id: 2, + highest_post_number: 12, + last_read_post_number: 11, + created_at: "2020-02-09T09:40:02.672Z", + category_id: category2.id, + notification_level: 2, + created_in_new_period: false, + treat_as_new_topic_start_date: "2022-05-09T03:17:34.286Z", + }, + ]); + + await visit("/"); + + assert + .dom( + `.sidebar-section-link-wrapper[data-category-id="${category1.id}"] .sidebar-section-link-suffix.icon.unread` + ) + .exists("category1 has a dot because it has a new topic"); + assert + .dom( + `.sidebar-section-link-wrapper[data-category-id="${category2.id}"] .sidebar-section-link-suffix.icon.unread` + ) + .exists("category2 has a dot because it has an unread topic"); + assert + .dom( + `.sidebar-section-link-wrapper[data-category-id="${category3.id}"] .sidebar-section-link-suffix.icon.unread` + ) + .doesNotExist( + "category3 doesn't have a dot because it has no new or unread topics" + ); + }); + + test("category link href is the new topics list of the category when sidebar_link_to_filtered_list is true and there are unread/new topics in the category", async function (assert) { + const categories = Site.current().categories; + const category1 = categories[0]; + const category2 = categories[1]; + const category3 = categories[2]; + + updateCurrentUser({ + sidebar_category_ids: [category1.id, category2.id, category3.id], + user_option: { + sidebar_link_to_filtered_list: true, + }, }); this.container.lookup("service:topic-tracking-state").loadStates([ @@ -1151,5 +1224,74 @@ acceptance( "links to the latest topics list for the category because there are no unread or new topics" ); }); + + test("category link href is always the latest topics list when sidebar_link_to_filtered_list is false", async function (assert) { + const categories = Site.current().categories; + const category1 = categories[0]; + const category2 = categories[1]; + const category3 = categories[2]; + + updateCurrentUser({ + sidebar_category_ids: [category1.id, category2.id, category3.id], + user_option: { + sidebar_link_to_filtered_list: false, + }, + }); + + this.container.lookup("service:topic-tracking-state").loadStates([ + { + topic_id: 1, + highest_post_number: 1, + last_read_post_number: null, + created_at: "2022-05-11T03:09:31.959Z", + category_id: category1.id, + notification_level: null, + created_in_new_period: true, + treat_as_new_topic_start_date: "2022-05-09T03:17:34.286Z", + }, + { + topic_id: 2, + highest_post_number: 12, + last_read_post_number: 11, + created_at: "2020-02-09T09:40:02.672Z", + category_id: category2.id, + notification_level: 2, + created_in_new_period: false, + treat_as_new_topic_start_date: "2022-05-09T03:17:34.286Z", + }, + ]); + + await visit("/"); + + assert + .dom( + `.sidebar-section-link-wrapper[data-category-id="${category1.id}"] a` + ) + .hasAttribute( + "href", + "/c/meta/3", + "category1 links to the latest topics list for the category" + ); + + assert + .dom( + `.sidebar-section-link-wrapper[data-category-id="${category2.id}"] a` + ) + .hasAttribute( + "href", + "/c/howto/10", + "category2 links to the latest topics list for the category" + ); + + assert + .dom( + `.sidebar-section-link-wrapper[data-category-id="${category3.id}"] a` + ) + .hasAttribute( + "href", + "/c/feature/spec/26", + "category3 links to the latest topics list for the category" + ); + }); } ); diff --git a/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-community-section-test.js b/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-community-section-test.js index 17734586c44..6c34905b864 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-community-section-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-community-section-test.js @@ -179,9 +179,11 @@ acceptance("Sidebar - Logged on user - Community Section", function (needs) { ); }); - test("clicking on everything link - sidebar_list_destination set to unread/new and no unread or new topics", async function (assert) { + test("clicking on everything link - sidebar_link_to_filtered_list set to true and no unread or new topics", async function (assert) { updateCurrentUser({ - sidebar_list_destination: "unread_new", + user_option: { + sidebar_link_to_filtered_list: true, + }, }); await visit("/t/280"); @@ -210,7 +212,7 @@ acceptance("Sidebar - Logged on user - Community Section", function (needs) { ); }); - test("clicking on everything link - sidebar_list_destination set to unread/new with new topics", async function (assert) { + test("clicking on everything link - sidebar_link_to_filtered_list set to true with new topics", async function (assert) { const topicTrackingState = this.container.lookup( "service:topic-tracking-state" ); @@ -222,7 +224,9 @@ acceptance("Sidebar - Logged on user - Community Section", function (needs) { created_in_new_period: true, }); updateCurrentUser({ - sidebar_list_destination: "unread_new", + user_option: { + sidebar_link_to_filtered_list: true, + }, }); await visit("/t/280"); await click( @@ -251,7 +255,7 @@ acceptance("Sidebar - Logged on user - Community Section", function (needs) { ); }); - test("clicking on everything link - sidebar_list_destination set to unread/new with new and unread topics", async function (assert) { + test("clicking on everything link - sidebar_link_to_filtered_list set to true with new and unread topics", async function (assert) { const topicTrackingState = this.container.lookup( "service:topic-tracking-state" ); @@ -271,7 +275,9 @@ acceptance("Sidebar - Logged on user - Community Section", function (needs) { created_in_new_period: true, }); updateCurrentUser({ - sidebar_list_destination: "unread_new", + user_option: { + sidebar_link_to_filtered_list: true, + }, }); await visit("/t/280"); await click( @@ -666,7 +672,9 @@ acceptance("Sidebar - Logged on user - Community Section", function (needs) { test("my posts changes its text when drafts are present and new new view experiment is enabled", async function (assert) { updateCurrentUser({ - sidebar_list_destination: "unread_new", + user_option: { + sidebar_show_count_of_new_items: true, + }, new_new_view_enabled: true, }); await visit("/"); @@ -758,7 +766,9 @@ acceptance("Sidebar - Logged on user - Community Section", function (needs) { test("show suffix indicator for unread and new content on everything link", async function (assert) { updateCurrentUser({ - sidebar_list_destination: "default", + user_option: { + sidebar_show_count_of_new_items: false, + }, }); this.container.lookup("service:topic-tracking-state").loadStates([ @@ -846,7 +856,9 @@ acceptance("Sidebar - Logged on user - Community Section", function (needs) { test("new and unread count for everything link", async function (assert) { updateCurrentUser({ - sidebar_list_destination: "unread_new", + user_option: { + sidebar_show_count_of_new_items: true, + }, }); this.container.lookup("service:topic-tracking-state").loadStates([ @@ -1187,7 +1199,12 @@ acceptance( navigation_menu: "sidebar", }); - test("count shown next to the everything link", async function (assert) { + test("count is shown next to the everything link when sidebar_show_count_of_new_items is true", async function (assert) { + updateCurrentUser({ + user_option: { + sidebar_show_count_of_new_items: true, + }, + }); this.container.lookup("service:topic-tracking-state").loadStates([ { topic_id: 1, @@ -1225,14 +1242,19 @@ acceptance( assert.strictEqual( query( - ".sidebar-section[data-section-name='community'] .sidebar-section-link[data-link-name='everything'] .sidebar-section-link-content-badge" + ".sidebar-section-link[data-link-name='everything'] .sidebar-section-link-content-badge" ).textContent.trim(), "2", "count is 2 because there's 1 unread topic and 1 new topic" ); }); - test("everything link href", async function (assert) { + test("dot is shown next to the everything link when sidebar_show_count_of_new_items is false", async function (assert) { + updateCurrentUser({ + user_option: { + sidebar_show_count_of_new_items: false, + }, + }); this.container.lookup("service:topic-tracking-state").loadStates([ { topic_id: 1, @@ -1258,28 +1280,30 @@ acceptance( await visit("/"); - assert.true( - query( - ".sidebar-section[data-section-name='community'] .sidebar-section-link[data-link-name='everything']" - ).href.endsWith("/new"), - "links to /new because there are 1 new and 1 unread topics" - ); + assert + .dom( + ".sidebar-section-link[data-link-name='everything'] .sidebar-section-link-suffix.icon.unread" + ) + .exists( + "everything link has a dot because there are unread or new topics" + ); await publishToMessageBus("/unread", { topic_id: 1, message_type: "read", payload: { - last_read_post_number: 3, - highest_post_number: 3, + last_read_post_number: 1, + highest_post_number: 1, }, }); - assert.true( - query( - ".sidebar-section[data-section-name='community'] .sidebar-section-link[data-link-name='everything']" - ).href.endsWith("/new"), - "links to /new because there is 1 unread topic" - ); + assert + .dom( + ".sidebar-section-link[data-link-name='everything'] .sidebar-section-link-suffix.icon.unread" + ) + .exists( + "everything link has a dot because there are unread or new topics" + ); await publishToMessageBus("/unread", { topic_id: 2, @@ -1290,12 +1314,88 @@ acceptance( }, }); - assert.true( - query( - ".sidebar-section[data-section-name='community'] .sidebar-section-link[data-link-name='everything']" - ).href.endsWith("/latest"), - "links to /latest because there are no unread or new topics" - ); + assert + .dom( + ".sidebar-section-link[data-link-name='everything'] .sidebar-section-link-suffix.icon.unread" + ) + .doesNotExist( + "everything link no longer has a dot because there are no more unread or new topics" + ); + }); + + test("everything link's href is the new topics list when sidebar_link_to_filtered_list is true", async function (assert) { + updateCurrentUser({ + user_option: { + sidebar_link_to_filtered_list: true, + }, + }); + this.container.lookup("service:topic-tracking-state").loadStates([ + { + topic_id: 1, + highest_post_number: 1, + last_read_post_number: null, + created_at: "2022-05-11T03:09:31.959Z", + category_id: 1, + notification_level: null, + created_in_new_period: true, + treat_as_new_topic_start_date: "2022-05-09T03:17:34.286Z", + }, + { + topic_id: 2, + highest_post_number: 12, + last_read_post_number: 11, + created_at: "2020-02-09T09:40:02.672Z", + category_id: 2, + notification_level: 2, + created_in_new_period: false, + treat_as_new_topic_start_date: "2022-05-09T03:17:34.286Z", + }, + ]); + + await visit("/"); + + assert + .dom(".sidebar-section-link[data-link-name='everything']") + .hasAttribute( + "href", + "/new", + + "links to /new because there are 1 new and 1 unread topics" + ); + + await publishToMessageBus("/unread", { + topic_id: 1, + message_type: "read", + payload: { + last_read_post_number: 3, + highest_post_number: 3, + }, + }); + + assert + .dom(".sidebar-section-link[data-link-name='everything']") + .hasAttribute( + "href", + "/new", + "links to /new because there is 1 unread topic" + ); + + await publishToMessageBus("/unread", { + topic_id: 2, + message_type: "read", + payload: { + last_read_post_number: 12, + highest_post_number: 12, + }, + }); + + assert + .dom(".sidebar-section-link[data-link-name='everything']") + .hasAttribute( + "href", + "/latest", + "links to /latest because there are no unread or new topics" + ); await publishToMessageBus("/unread", { topic_id: 1, @@ -1306,12 +1406,39 @@ acceptance( }, }); - assert.true( - query( - ".sidebar-section[data-section-name='community'] .sidebar-section-link[data-link-name='everything']" - ).href.endsWith("/new"), - "links to /new because there is 1 new topic" - ); + assert + .dom(".sidebar-section-link[data-link-name='everything']") + .hasAttribute( + "href", + "/new", + "links to /new because there is 1 new topic" + ); + }); + + test("everything link's href is always the latest topics list when sidebar_link_to_filtered_list is false", async function (assert) { + updateCurrentUser({ + user_option: { + sidebar_link_to_filtered_list: false, + }, + }); + this.container.lookup("service:topic-tracking-state").loadStates([ + { + topic_id: 1, + highest_post_number: 1, + last_read_post_number: null, + created_at: "2022-05-11T03:09:31.959Z", + category_id: 1, + notification_level: null, + created_in_new_period: true, + treat_as_new_topic_start_date: "2022-05-09T03:17:34.286Z", + }, + ]); + + await visit("/"); + + assert + .dom(".sidebar-section-link[data-link-name='everything']") + .hasAttribute("href", "/latest", "everything link href is /latest"); }); } ); diff --git a/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-tags-section-test.js b/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-tags-section-test.js index 8a78344f836..b943d4c9b61 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-tags-section-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/sidebar-user-tags-section-test.js @@ -250,9 +250,11 @@ acceptance("Sidebar - Logged on user - Tags section", function (needs) { ); }); - test("clicking tag section links - sidebar_list_destination set to unread/new and no unread or new topics", async function (assert) { + test("clicking tag section links - sidebar_link_to_filtered_list set to true and no unread or new topics", async function (assert) { updateCurrentUser({ - sidebar_list_destination: "unread_new", + user_option: { + sidebar_link_to_filtered_list: true, + }, }); await visit("/"); @@ -278,9 +280,11 @@ acceptance("Sidebar - Logged on user - Tags section", function (needs) { ); }); - test("clicking tag section links - sidebar_list_destination set to unread/new with new topics", async function (assert) { + test("clicking tag section links - sidebar_link_to_filtered_list set to true with new topics", async function (assert) { updateCurrentUser({ - sidebar_list_destination: "unread_new", + user_option: { + sidebar_link_to_filtered_list: true, + }, }); this.container.lookup("service:topic-tracking-state").loadStates([ @@ -320,9 +324,11 @@ acceptance("Sidebar - Logged on user - Tags section", function (needs) { ); }); - test("clicking tag section links - sidebar_list_destination set to unread/new with unread topics", async function (assert) { + test("clicking tag section links - sidebar_link_to_filtered_list set to true with unread topics", async function (assert) { updateCurrentUser({ - sidebar_list_destination: "unread_new", + user_option: { + sidebar_link_to_filtered_list: true, + }, }); this.container.lookup("service:topic-tracking-state").loadStates([ @@ -440,7 +446,9 @@ acceptance("Sidebar - Logged on user - Tags section", function (needs) { test("show suffix indicator for new content on tag section links", async function (assert) { updateCurrentUser({ - sidebar_list_destination: "default", + user_option: { + sidebar_show_count_of_new_items: false, + }, }); this.container.lookup("service:topic-tracking-state").loadStates([ @@ -537,7 +545,9 @@ acceptance("Sidebar - Logged on user - Tags section", function (needs) { test("new and unread count for tag section links", async function (assert) { updateCurrentUser({ - sidebar_list_destination: "unread_new", + user_option: { + sidebar_show_count_of_new_items: true, + }, }); this.container.lookup("service:topic-tracking-state").loadStates([ @@ -711,7 +721,13 @@ acceptance( ], }); - test("count shown next to tag link", async function (assert) { + test("count shown next to tag link when sidebar_show_count_of_new_items is true", async function (assert) { + updateCurrentUser({ + user_option: { + sidebar_show_count_of_new_items: true, + }, + }); + this.container.lookup("service:topic-tracking-state").loadStates([ { topic_id: 1, @@ -775,7 +791,66 @@ acceptance( ); }); - test("tag link href", async function (assert) { + test("dot shown next to tag link when sidebar_show_count_of_new_items is false", async function (assert) { + updateCurrentUser({ + user_option: { + sidebar_show_count_of_new_items: false, + }, + }); + + this.container.lookup("service:topic-tracking-state").loadStates([ + { + topic_id: 1, + highest_post_number: 1, + last_read_post_number: null, + created_at: "2022-05-11T03:09:31.959Z", + category_id: 1, + notification_level: null, + created_in_new_period: true, + treat_as_new_topic_start_date: "2022-05-09T03:17:34.286Z", + tags: ["tag1"], + }, + { + topic_id: 2, + highest_post_number: 12, + last_read_post_number: 11, + created_at: "2020-02-09T09:40:02.672Z", + category_id: 2, + notification_level: 2, + created_in_new_period: false, + treat_as_new_topic_start_date: "2022-05-09T03:17:34.286Z", + tags: ["tag2"], + }, + ]); + + await visit("/"); + + assert + .dom( + '.sidebar-section-link-wrapper[data-tag-name="tag1"] .sidebar-section-link-suffix.icon.unread' + ) + .exists("tag1 has a dot because it has a new topic"); + assert + .dom( + '.sidebar-section-link-wrapper[data-tag-name="tag2"] .sidebar-section-link-suffix.icon.unread' + ) + .exists("tag2 has a dot because it has an unread topic"); + assert + .dom( + '.sidebar-section-link-wrapper[data-tag-name="tag3"] .sidebar-section-link-suffix.icon.unread' + ) + .doesNotExist( + "tag3 doesn't have a dot because it has no new or unread topics" + ); + }); + + test("tag link href is to the new topics list when sidebar_link_to_filtered_list is true and there are unread/new topics with the tag", async function (assert) { + updateCurrentUser({ + user_option: { + sidebar_link_to_filtered_list: true, + }, + }); + this.container.lookup("service:topic-tracking-state").loadStates([ { topic_id: 1, @@ -835,5 +910,64 @@ acceptance( "links to the latest topics list for the tag because there are no unread or new topics" ); }); + + test("tag link href is always to the latest topics list when sidebar_link_to_filtered_list is false", async function (assert) { + updateCurrentUser({ + user_option: { + sidebar_link_to_filtered_list: false, + }, + }); + + this.container.lookup("service:topic-tracking-state").loadStates([ + { + topic_id: 1, + highest_post_number: 1, + last_read_post_number: null, + created_at: "2022-05-11T03:09:31.959Z", + category_id: 1, + notification_level: null, + created_in_new_period: true, + treat_as_new_topic_start_date: "2022-05-09T03:17:34.286Z", + tags: ["tag1"], + }, + { + topic_id: 2, + highest_post_number: 12, + last_read_post_number: 11, + created_at: "2020-02-09T09:40:02.672Z", + category_id: 2, + notification_level: 2, + created_in_new_period: false, + treat_as_new_topic_start_date: "2022-05-09T03:17:34.286Z", + tags: ["tag2"], + }, + ]); + + await visit("/"); + + assert + .dom('.sidebar-section-link-wrapper[data-tag-name="tag1"] a') + .hasAttribute( + "href", + "/tag/tag1", + "tag1 links to the latest topics list for the tag" + ); + + assert + .dom('.sidebar-section-link-wrapper[data-tag-name="tag2"] a') + .hasAttribute( + "href", + "/tag/tag2", + "tag2 links to the latest topics list for the tag" + ); + + assert + .dom('.sidebar-section-link-wrapper[data-tag-name="tag3"] a') + .hasAttribute( + "href", + "/tag/tag3", + "tag3 links to the latest topics list for the tag" + ); + }); } ); diff --git a/app/assets/javascripts/discourse/tests/acceptance/user-preferences-navigation-menu-test.js b/app/assets/javascripts/discourse/tests/acceptance/user-preferences-navigation-menu-test.js index 2ac3354aa16..c158ff983cb 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/user-preferences-navigation-menu-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/user-preferences-navigation-menu-test.js @@ -8,6 +8,8 @@ import { updateCurrentUser, } from "discourse/tests/helpers/qunit-helpers"; import selectKit from "discourse/tests/helpers/select-kit-helper"; +import Site from "discourse/models/site"; +import I18n from "I18n"; acceptance("User Preferences - Navigation Menu", function (needs) { needs.user({ @@ -45,7 +47,6 @@ acceptance("User Preferences - Navigation Menu", function (needs) { { name: "monkey", pm_only: false }, { name: "gazelle", pm_only: false }, ], - sidebar_list_destination: "unread_new", }, }); } @@ -278,4 +279,154 @@ acceptance("User Preferences - Navigation Menu", function (needs) { "contains the right request body to update user's sidebar tag links" ); }); + + test("user enabling sidebar_show_count_of_new_items preference", async function (assert) { + const categories = Site.current().categories; + const category1 = categories[0]; + + updateCurrentUser({ + sidebar_category_ids: [category1.id], + }); + + this.container.lookup("service:topic-tracking-state").loadStates([ + { + topic_id: 1, + highest_post_number: 1, + last_read_post_number: null, + created_at: "2022-05-11T03:09:31.959Z", + category_id: category1.id, + notification_level: null, + created_in_new_period: true, + treat_as_new_topic_start_date: "2022-05-09T03:17:34.286Z", + }, + ]); + + await visit("/u/eviltrout/preferences/navigation-menu"); + + assert + .dom( + '.sidebar-section-link[data-link-name="everything"] .sidebar-section-link-suffix.icon.unread' + ) + .exists("everything link has a dot before the preference is enabled"); + assert + .dom( + `.sidebar-section-link[data-link-name="everything"] .sidebar-section-link-content-badge` + ) + .doesNotExist( + "everything link doesn't have badge text before the preference is enabled" + ); + + assert + .dom( + `.sidebar-section-link-wrapper[data-category-id="${category1.id}"] .sidebar-section-link-suffix.icon.unread` + ) + .exists("category1 has a dot before the preference is enabled"); + assert + .dom( + `.sidebar-section-link-wrapper[data-category-id="${category1.id}"] .sidebar-section-link-content-badge` + ) + .doesNotExist( + "category1 doesn't have badge text before the preference is enabled" + ); + + await click( + ".preferences-navigation-menu-navigation .pref-show-count-new-items input" + ); + await click(".save-changes"); + + assert + .dom( + '.sidebar-section-link[data-link-name="everything"] .sidebar-section-link-suffix.icon.unread' + ) + .doesNotExist( + "everything link no longer has a dot after the preference is enabled" + ); + assert + .dom( + `.sidebar-section-link[data-link-name="everything"] .sidebar-section-link-content-badge` + ) + .hasText( + I18n.t("sidebar.new_count", { count: 1 }), + "everything link now has badge text after the preference is enabled" + ); + + assert + .dom( + `.sidebar-section-link-wrapper[data-category-id="${category1.id}"] .sidebar-section-link-suffix.icon.unread` + ) + .doesNotExist( + "category1 doesn't have a dot anymore after the preference is enabled" + ); + assert + .dom( + `.sidebar-section-link-wrapper[data-category-id="${category1.id}"] .sidebar-section-link-content-badge` + ) + .hasText( + I18n.t("sidebar.new_count", { count: 1 }), + "category1 now has badge text after the preference is enabled" + ); + }); + + test("user enabling sidebar_link_to_filtered_list preference", async function (assert) { + const categories = Site.current().categories; + const category1 = categories[0]; + + updateCurrentUser({ + sidebar_category_ids: [category1.id], + }); + + this.container.lookup("service:topic-tracking-state").loadStates([ + { + topic_id: 1, + highest_post_number: 1, + last_read_post_number: null, + created_at: "2022-05-11T03:09:31.959Z", + category_id: category1.id, + notification_level: null, + created_in_new_period: true, + treat_as_new_topic_start_date: "2022-05-09T03:17:34.286Z", + }, + ]); + + await visit("/u/eviltrout/preferences/navigation-menu"); + + assert + .dom('.sidebar-section-link[data-link-name="everything"]') + .hasAttribute( + "href", + "/latest", + "everything link's href is the latest topics list before the preference is enabled" + ); + assert + .dom( + `.sidebar-section-link-wrapper[data-category-id="${category1.id}"] .sidebar-section-link` + ) + .hasAttribute( + "href", + "/c/meta/3", + "category1's link href is the latest topics list of the category before the preference is enabled" + ); + + await click( + ".preferences-navigation-menu-navigation .pref-link-to-filtered-list input" + ); + await click(".save-changes"); + + assert + .dom('.sidebar-section-link[data-link-name="everything"]') + .hasAttribute( + "href", + "/new", + "everything link's href is the new topics list after the preference is enabled" + ); + assert + .dom( + `.sidebar-section-link-wrapper[data-category-id="${category1.id}"] .sidebar-section-link` + ) + .hasAttribute( + "href", + "/c/meta/3/l/new", + "category1's link href is the new topics list of the category after the preference is enabled" + ); + }); }); diff --git a/app/models/user_option.rb b/app/models/user_option.rb index 06eebd364f7..7b76591237a 100644 --- a/app/models/user_option.rb +++ b/app/models/user_option.rb @@ -3,6 +3,7 @@ class UserOption < ActiveRecord::Base self.ignored_columns = [ "disable_jump_reply", # Remove once 20210706091905 is promoted from post_deploy to regular migration + "sidebar_list_destination", # TODO(osama): Remove in January 2024 ] self.primary_key = :user_id @@ -14,12 +15,6 @@ class UserOption < ActiveRecord::Base scope :human_users, -> { where("user_id > 0") } enum default_calendar: { none_selected: 0, ics: 1, google: 2 }, _scopes: false - enum sidebar_list_destination: { - none_selected: 0, - default: 0, - unread_new: 1, - }, - _prefix: "sidebar_list" def self.ensure_consistency! sql = <<~SQL @@ -291,8 +286,9 @@ end # chat_email_frequency :integer default(1), not null # enable_experimental_sidebar :boolean default(FALSE) # seen_popups :integer is an Array -# sidebar_list_destination :integer default("none_selected"), not null # chat_header_indicator_preference :integer default(0), not null +# sidebar_link_to_filtered_list :boolean default(FALSE), not null +# sidebar_show_count_of_new_items :boolean default(FALSE), not null # # Indexes # diff --git a/app/serializers/concerns/user_sidebar_mixin.rb b/app/serializers/concerns/user_sidebar_mixin.rb index 8266a2f1f0f..a606de5ff59 100644 --- a/app/serializers/concerns/user_sidebar_mixin.rb +++ b/app/serializers/concerns/user_sidebar_mixin.rb @@ -32,18 +32,6 @@ module UserSidebarMixin sidebar_navigation_menu? end - def sidebar_list_destination - if object.user_option.sidebar_list_none_selected? - SiteSetting.default_sidebar_list_destination - else - object.user_option.sidebar_list_destination - end - end - - def include_sidebar_list_destination? - sidebar_navigation_menu? - end - def sidebar_sections object .sidebar_sections diff --git a/app/serializers/current_user_option_serializer.rb b/app/serializers/current_user_option_serializer.rb index 93c57a49049..09810ff33f7 100644 --- a/app/serializers/current_user_option_serializer.rb +++ b/app/serializers/current_user_option_serializer.rb @@ -17,7 +17,9 @@ class CurrentUserOptionSerializer < ApplicationSerializer :seen_popups, :should_be_redirected_to_top, :redirected_to_top, - :treat_as_new_topic_start_date + :treat_as_new_topic_start_date, + :sidebar_link_to_filtered_list, + :sidebar_show_count_of_new_items def likes_notifications_disabled object.likes_notifications_disabled? diff --git a/app/serializers/current_user_serializer.rb b/app/serializers/current_user_serializer.rb index a4333679c52..7290c5c5f38 100644 --- a/app/serializers/current_user_serializer.rb +++ b/app/serializers/current_user_serializer.rb @@ -66,7 +66,6 @@ class CurrentUserSerializer < BasicUserSerializer :display_sidebar_tags, :sidebar_tags, :sidebar_category_ids, - :sidebar_list_destination, :sidebar_sections, :new_new_view_enabled?, :new_edit_sidebar_categories_tags_interface_groups_enabled?, diff --git a/app/serializers/user_option_serializer.rb b/app/serializers/user_option_serializer.rb index d78dad82ebd..1eba9b30951 100644 --- a/app/serializers/user_option_serializer.rb +++ b/app/serializers/user_option_serializer.rb @@ -36,7 +36,9 @@ class UserOptionSerializer < ApplicationSerializer :skip_new_user_tips, :default_calendar, :oldest_search_log_date, - :seen_popups + :seen_popups, + :sidebar_link_to_filtered_list, + :sidebar_show_count_of_new_items def auto_track_topics_after_msecs object.auto_track_topics_after_msecs || SiteSetting.default_other_auto_track_topics_after_msecs diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb index 91c267d9ad6..2da59c7e787 100644 --- a/app/serializers/user_serializer.rb +++ b/app/serializers/user_serializer.rb @@ -64,7 +64,6 @@ class UserSerializer < UserCardSerializer :use_logo_small_as_avatar, :sidebar_tags, :sidebar_category_ids, - :sidebar_list_destination, :display_sidebar_tags untrusted_attributes :bio_raw, :bio_cooked, :profile_background_upload_url diff --git a/app/services/user_updater.rb b/app/services/user_updater.rb index 8c740f4c0e7..b660728ef5d 100644 --- a/app/services/user_updater.rb +++ b/app/services/user_updater.rb @@ -48,8 +48,9 @@ class UserUpdater skip_new_user_tips seen_popups default_calendar - sidebar_list_destination bookmark_auto_delete_preference + sidebar_link_to_filtered_list + sidebar_show_count_of_new_items ] NOTIFICATION_SCHEDULE_ATTRS = -> do diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 7279ae28ad4..acd76ec69a0 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1211,9 +1211,9 @@ en: tags_section: "Tags Section" tags_section_instruction: "Selected tags will be displayed under Navigation Menu's tags section. If no tags are selected, the site's top tags will be displayed." navigation_section: "Navigation" - list_destination_instruction: "When there's new content in the navigation menu..." - list_destination_default: "use the default link and show a badge for new items" - list_destination_unread_new: "link to unread/new and show a count of new items" + navigation_section_instruction: "When a topic list in the navigation menu has new or unread items…" + link_to_filtered_list_checkbox_description: "Link to the filtered list" + show_count_new_items_checkbox_description: "Show a count of the new items" change: "change" featured_topic: "Featured Topic" moderator: "%{user} is a moderator" diff --git a/config/site_settings.yml b/config/site_settings.yml index 9244d50286c..55f8be4bf8a 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -2139,13 +2139,6 @@ navigation: type: tag_list default: "" client: true - default_sidebar_list_destination: - hidden: true - default: "default" - type: "list" - choices: - - "default" - - "unread_new" embedding: embed_by_username: diff --git a/db/migrate/20230618041001_add_sidebar_link_to_filtered_list_to_user_option.rb b/db/migrate/20230618041001_add_sidebar_link_to_filtered_list_to_user_option.rb new file mode 100644 index 00000000000..25bae7a2ebb --- /dev/null +++ b/db/migrate/20230618041001_add_sidebar_link_to_filtered_list_to_user_option.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class AddSidebarLinkToFilteredListToUserOption < ActiveRecord::Migration[7.0] + def change + add_column :user_options, :sidebar_link_to_filtered_list, :boolean, default: false, null: false + + execute <<~SQL + UPDATE user_options + SET sidebar_link_to_filtered_list = true + WHERE sidebar_list_destination = 1 + SQL + end +end diff --git a/db/migrate/20230618041123_add_sidebar_show_count_of_new_items_to_user_option.rb b/db/migrate/20230618041123_add_sidebar_show_count_of_new_items_to_user_option.rb new file mode 100644 index 00000000000..4ec3f496a61 --- /dev/null +++ b/db/migrate/20230618041123_add_sidebar_show_count_of_new_items_to_user_option.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddSidebarShowCountOfNewItemsToUserOption < ActiveRecord::Migration[7.0] + def change + add_column :user_options, + :sidebar_show_count_of_new_items, + :boolean, + default: false, + null: false + + execute <<~SQL + UPDATE user_options + SET sidebar_show_count_of_new_items = true + WHERE sidebar_list_destination = 1 + SQL + end +end diff --git a/db/migrate/20230620050614_remove_default_sidebar_list_destination_setting.rb b/db/migrate/20230620050614_remove_default_sidebar_list_destination_setting.rb new file mode 100644 index 00000000000..ea42a186124 --- /dev/null +++ b/db/migrate/20230620050614_remove_default_sidebar_list_destination_setting.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class RemoveDefaultSidebarListDestinationSetting < ActiveRecord::Migration[7.0] + def up + execute("DELETE FROM site_settings WHERE name = 'default_sidebar_list_destination'") + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/spec/requests/api/schemas/json/user_get_response.json b/spec/requests/api/schemas/json/user_get_response.json index a5e43be2be4..01cb1a18b35 100644 --- a/spec/requests/api/schemas/json/user_get_response.json +++ b/spec/requests/api/schemas/json/user_get_response.json @@ -771,8 +771,11 @@ "oldest_search_log_date": { "type": ["string", "null"] }, - "sidebar_list_destination": { - "type": "string" + "sidebar_link_to_filtered_list": { + "type": "boolean" + }, + "sidebar_show_count_of_new_items": { + "type": "boolean" }, "seen_popups": { "type": ["array", "null"] diff --git a/spec/serializers/user_serializer_spec.rb b/spec/serializers/user_serializer_spec.rb index f33b71431bb..bfa4ebde243 100644 --- a/spec/serializers/user_serializer_spec.rb +++ b/spec/serializers/user_serializer_spec.rb @@ -449,7 +449,6 @@ RSpec.describe UserSerializer do expect(serializer.as_json[:sidebar_category_ids]).to eq(nil) expect(serializer.as_json[:sidebar_tags]).to eq(nil) - expect(serializer.as_json[:sidebar_list_destination]).to eq(nil) expect(serializer.as_json[:display_sidebar_tags]).to eq(nil) end end diff --git a/spec/support/user_sidebar_serializer_attributes.rb b/spec/support/user_sidebar_serializer_attributes.rb index 9bf6eaa5d5c..5e8f908e3ea 100644 --- a/spec/support/user_sidebar_serializer_attributes.rb +++ b/spec/support/user_sidebar_serializer_attributes.rb @@ -7,24 +7,6 @@ RSpec.shared_examples "User Sidebar Serializer Attributes" do |serializer_klass| before { SiteSetting.navigation_menu = "sidebar" } - describe "#sidebar_list_destination" do - it "is not included when navigation menu is legacy" do - SiteSetting.navigation_menu = "legacy" - - expect(serializer.as_json[:sidebar_list_destination]).to eq(nil) - end - - it "returns choosen value or default" do - expect(serializer.as_json[:sidebar_list_destination]).to eq( - SiteSetting.default_sidebar_list_destination, - ) - - user.user_option.update!(sidebar_list_destination: "unread_new") - - expect(serializer.as_json[:sidebar_list_destination]).to eq("unread_new") - end - end - describe "#sidebar_category_ids" do fab!(:group) { Fabricate(:group) } fab!(:category) { Fabricate(:category) } diff --git a/spec/system/page_objects/pages/user_preferences_navigation_menu.rb b/spec/system/page_objects/pages/user_preferences_navigation_menu.rb index 5cc9224325e..6ea0522abcf 100644 --- a/spec/system/page_objects/pages/user_preferences_navigation_menu.rb +++ b/spec/system/page_objects/pages/user_preferences_navigation_menu.rb @@ -18,14 +18,8 @@ module PageObjects tag_selector_header.has_content?(tags.map(&:name).join(", ")) end - def has_navigation_menu_list_destination_preference?(type) - list_selector_header = - page.find( - ".preferences-navigation-menu-navigation__list-destination-selector .select-kit-header-wrapper", - ) - list_selector_header.has_content?( - I18n.t("js.user.experimental_sidebar.list_destination_#{type}"), - ) + def has_navigation_menu_preference_checked?(preference) + page.find(".#{preference} input").checked? end end end diff --git a/spec/system/viewing_navigation_menu_preferences_spec.rb b/spec/system/viewing_navigation_menu_preferences_spec.rb index 0acae658f15..0fe2220c16a 100644 --- a/spec/system/viewing_navigation_menu_preferences_spec.rb +++ b/spec/system/viewing_navigation_menu_preferences_spec.rb @@ -30,7 +30,10 @@ describe "Viewing sidebar preferences", type: :system do before { sign_in(admin) } it "should be able to view navigation menu preferences of another user" do - user.user_option.update!(sidebar_list_destination: "unread_new") + user.user_option.update!( + sidebar_link_to_filtered_list: true, + sidebar_show_count_of_new_items: true, + ) user_preferences_navigation_menu_page.visit(user) @@ -42,9 +45,12 @@ describe "Viewing sidebar preferences", type: :system do tag, tag2, ) - expect( - user_preferences_navigation_menu_page, - ).to have_navigation_menu_list_destination_preference("unread_new") + expect(user_preferences_navigation_menu_page).to have_navigation_menu_preference_checked( + "pref-show-count-new-items", + ) + expect(user_preferences_navigation_menu_page).to have_navigation_menu_preference_checked( + "pref-link-to-filtered-list", + ) end end end