DEV: Route PM only tags to PM tags show route (#17870)

Previously, PM only tags were being routed to the public topic list with
the tag added as a filter. However, the public topic list does not fetch
PMs and hence PM only tags did not provide any value when added to the
Sidebar. This commit changes that by allowing the client to
differentiate PM only tag and thus routes the link to the PM tags show
route.

Counts for PM only tags section links are not supported as of this
commit and will be added in a follow up commit.
This commit is contained in:
Alan Guo Xiang Tan
2022-08-12 11:26:56 +08:00
committed by GitHub
parent e4fbb3be21
commit 3deabb00d4
16 changed files with 244 additions and 81 deletions

View File

@@ -1,15 +1,17 @@
import I18n from "I18n";
import { cached } from "@glimmer/tracking";
import Component from "@glimmer/component";
import { inject as service } from "@ember/service";
import { action } from "@ember/object";
import Component from "@glimmer/component";
import TagSectionLink from "discourse/lib/sidebar/tags-section/tag-section-link";
import PMTagSectionLink from "discourse/lib/sidebar/tags-section/pm-tag-section-link";
export default class SidebarTagsSection extends Component {
@service router;
@service topicTrackingState;
@service pmTopicTrackingState;
@service currentUser;
constructor() {
@@ -17,7 +19,9 @@ export default class SidebarTagsSection extends Component {
this.callbackId = this.topicTrackingState.onStateChange(() => {
this.sectionLinks.forEach((sectionLink) => {
sectionLink.refreshCounts();
if (sectionLink.refreshCounts) {
sectionLink.refreshCounts();
}
});
});
}
@@ -30,13 +34,22 @@ export default class SidebarTagsSection extends Component {
get sectionLinks() {
const links = [];
for (const tagName of this.currentUser.sidebarTagNames) {
links.push(
new TagSectionLink({
tagName,
topicTrackingState: this.topicTrackingState,
})
);
for (const tag of this.currentUser.sidebarTags) {
if (tag.pm_only) {
links.push(
new PMTagSectionLink({
tag,
currentUser: this.currentUser,
})
);
} else {
links.push(
new TagSectionLink({
tag,
topicTrackingState: this.topicTrackingState,
})
);
}
}
return links;

View File

@@ -12,24 +12,29 @@ export default class extends Controller {
@action
save() {
const initialSidebarCategoryIds = this.model.sidebarCategoryIds;
const initialSidebarTagNames = this.model.sidebarTagNames;
this.model.set("sidebar_tag_names", this.selectedSidebarTagNames);
this.model.set(
"sidebarCategoryIds",
this.selectedSidebarCategories.mapBy("id")
);
this.model.set("sidebar_tag_names", this.selectedSidebarTagNames);
this.model
.save()
.then(() => {
.then((result) => {
if (result.user.sidebar_tags) {
this.model.set("sidebar_tags", result.user.sidebar_tags);
}
this.saved = true;
})
.catch((error) => {
this.model.set("sidebarCategoryIds", initialSidebarCategoryIds);
this.model.set("sidebar_tag_names", initialSidebarTagNames);
popupAjaxError(error);
})
.finally(() => {
this.model.set("sidebar_tag_names", []);
});
}
}

View File

@@ -0,0 +1,22 @@
export default class PMTagSectionLink {
constructor({ tag, currentUser }) {
this.tag = tag;
this.currentUser = currentUser;
}
get name() {
return this.tag.name;
}
get models() {
return [this.currentUser, this.tag.name];
}
get route() {
return "userPrivateMessages.tagsShow";
}
get text() {
return this.tag.name;
}
}

View File

@@ -8,8 +8,8 @@ export default class TagSectionLink {
@tracked totalUnread = 0;
@tracked totalNew = 0;
constructor({ tagName, topicTrackingState }) {
this.tagName = tagName;
constructor({ tag, topicTrackingState }) {
this.tagName = tag.name;
this.topicTrackingState = topicTrackingState;
this.refreshCounts();
}
@@ -31,18 +31,24 @@ export default class TagSectionLink {
return this.tagName;
}
get model() {
return this.tagName;
get models() {
return [this.tagName];
}
get route() {
if (this.totalUnread > 0) {
return "tag.showUnread";
} else if (this.totalNew > 0) {
return "tag.showNew";
} else {
return "tag.show";
}
}
get currentWhen() {
return "tag.show tag.showNew tag.showUnread tag.showTop";
}
get route() {
return "tag.show";
}
get text() {
return this.tagName;
}
@@ -58,14 +64,4 @@ export default class TagSectionLink {
});
}
}
get route() {
if (this.totalUnread > 0) {
return "tag.showUnread";
} else if (this.totalNew > 0) {
return "tag.showNew";
} else {
return "tag.show";
}
}
}

View File

@@ -1,7 +1,7 @@
import EmberObject, { computed, get, getProperties } from "@ember/object";
import cookie, { removeCookie } from "discourse/lib/cookie";
import { defaultHomepage, escapeExpression } from "discourse/lib/utilities";
import { alias, equal, filterBy, gt, or } 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";
@@ -314,15 +314,23 @@ const User = RestModel.extend({
sidebarCategoryIds: alias("sidebar_category_ids"),
@discourseComputed("sidebar_tag_names.[]")
sidebarTagNames(sidebarTagNames) {
if (!sidebarTagNames || sidebarTagNames.length === 0) {
@discourseComputed("sidebar_tags.[]")
sidebarTags(sidebarTags) {
if (!sidebarTags || sidebarTags.length === 0) {
return [];
}
return sidebarTagNames;
if (this.siteSettings.tags_sort_alphabetically) {
return sidebarTags.sort((a, b) => {
return a.name.localeCompare(b);
});
} else {
return sidebarTags;
}
},
sidebarTagNames: mapBy("sidebarTags", "name"),
@discourseComputed("sidebar_category_ids.[]")
sidebarCategories(sidebarCategoryIds) {
if (!sidebarCategoryIds || sidebarCategoryIds.length === 0) {
@@ -446,6 +454,7 @@ const User = RestModel.extend({
);
User.current().setProperties(userProps);
this.setProperties(updatedState);
return result;
})
.finally(() => {
this.set("isSaving", false);

View File

@@ -16,7 +16,7 @@
@content={{sectionLink.text}}
@currentWhen={{sectionLink.currentWhen}}
@badgeText={{sectionLink.badgeText}}
@model={{sectionLink.model}}>
@models={{sectionLink.models}} >
</Sidebar::SectionLink>
{{/each}}
{{else}}

View File

@@ -57,7 +57,7 @@ acceptance(
acceptance("Sidebar - Categories Section", function (needs) {
needs.user({
sidebar_category_ids: [],
sidebar_tag_names: [],
sidebar_tags: [],
});
needs.settings({

View File

@@ -42,7 +42,18 @@ acceptance("Sidebar - Tags section", function (needs) {
tracked_tags: ["tag1"],
watched_tags: ["tag2", "tag3"],
watching_first_post_tags: [],
sidebar_tag_names: ["tag1", "tag2", "tag3"],
sidebar_tags: [
{ name: "tag1", pm_only: false },
{ name: "tag2", pm_only: false },
{
name: "tag3",
pm_only: false,
},
{
name: "tag4",
pm_only: true,
},
],
});
needs.pretender((server, helper) => {
@@ -52,6 +63,20 @@ acceptance("Sidebar - Tags section", function (needs) {
});
});
server.get("/topics/private-messages-tags/:username/:tagId", () => {
const topics = [
{ id: 1, posters: [] },
{ id: 2, posters: [] },
{ id: 3, posters: [] },
];
return helper.response({
topic_list: {
topics,
},
});
});
["latest", "top", "new", "unread"].forEach((type) => {
server.get(`/tag/:tagId/l/${type}.json`, () => {
return helper.response(
@@ -85,7 +110,7 @@ acceptance("Sidebar - Tags section", function (needs) {
test("section content when user has not added any tags", async function (assert) {
updateCurrentUser({
sidebar_tag_names: [],
sidebar_tags: [],
});
await visit("/");
@@ -106,8 +131,8 @@ acceptance("Sidebar - Tags section", function (needs) {
assert.strictEqual(
count(".sidebar-section-tags .sidebar-section-link"),
3,
"3 section links under the section"
4,
"4 section links under the section"
);
assert.strictEqual(
@@ -167,6 +192,29 @@ acceptance("Sidebar - Tags section", function (needs) {
);
});
test("private message tag section links for user", async function (assert) {
await visit("/");
await click(".sidebar-section-link-tag4");
assert.strictEqual(
currentURL(),
"/u/eviltrout/messages/tags/tag4",
"it should transition to user's private message tag4 tag page"
);
assert.strictEqual(
count(".sidebar-section-tags .sidebar-section-link.active"),
1,
"only one link is marked as active"
);
assert.ok(
exists(`.sidebar-section-link-tag4.active`),
"the tag4 section link is marked as active"
);
});
test("visiting tag discovery top route", async function (assert) {
await visit(`/tag/tag1/l/top`);

View File

@@ -12,7 +12,7 @@ import selectKit from "discourse/tests/helpers/select-kit-helper";
acceptance("User Preferences - Sidebar", function (needs) {
needs.user({
sidebar_category_ids: [],
sidebar_tag_names: [],
sidebar_tags: [],
});
needs.settings({
@@ -39,7 +39,14 @@ acceptance("User Preferences - Sidebar", function (needs) {
// This request format will cause an error
return helper.response(400, {});
} else {
return helper.response({ user: {} });
return helper.response({
user: {
sidebar_tags: [
{ name: "monkey", pm_only: false },
{ name: "gazelle", pm_only: false },
],
},
});
}
});
});
@@ -121,7 +128,7 @@ acceptance("User Preferences - Sidebar", function (needs) {
});
test("user encountering error when adding tags to sidebar", async function (assert) {
updateCurrentUser({ sidebar_tag_names: ["monkey"] });
updateCurrentUser({ sidebar_tags: [{ name: "monkey", pm_only: false }] });
await visit("/");