DEV: Simplify new user page nav messages dropdown. (#19289)

With the refactoring of the user messages routes in
4da2e3fef4, we can now depend on the top
level routes like `userPrivateMessages.user`, `userPrivateMessages.group` and `userPrivateMessages.tags`
to determine what the active value for the dropdown should be which
greatly simplifies the logic.
This commit is contained in:
Alan Guo Xiang Tan 2022-12-02 10:02:04 +08:00 committed by GitHub
parent 7212a2ad51
commit 9b5bc60325
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 156 additions and 118 deletions

View File

@ -0,0 +1,11 @@
import ComboBoxComponent from "select-kit/components/combo-box";
export default ComboBoxComponent.extend({
pluginApiIdentifiers: ["user-nav-messages-dropdown"],
classNames: ["user-nav-messages-dropdown"],
selectKitOptions: {
caretDownIcon: "caret-right",
caretUpIcon: "caret-down",
},
});

View File

@ -1,53 +0,0 @@
import { gte, reads } from "@ember/object/computed";
import ComboBoxComponent from "select-kit/components/combo-box";
import DiscourseURL from "discourse/lib/url";
import I18n from "I18n";
import { computed } from "@ember/object";
export default ComboBoxComponent.extend({
pluginApiIdentifiers: ["messages-dropdown"],
classNames: ["message-dropdown"],
content: reads("groupsWithMessages"),
valueProperty: "name",
hasManyGroups: gte("content.length", 10),
selectKitOptions: {
caretDownIcon: "caret-right",
caretUpIcon: "caret-down",
filterable: "hasManyGroups",
},
groupsWithMessages: computed(function () {
const groups = [
{
name: I18n.t("user.messages.inbox"),
},
];
this.user.groupsWithMessages.forEach((group) => {
groups.push({ name: group.name, icon: "inbox" });
});
if (this.pmTaggingEnabled) {
groups.push({ name: I18n.t("user.messages.tags") });
}
return groups;
}),
actions: {
onChange(item) {
let url;
if (this.user.groups.some((g) => g.name === item)) {
url = `/u/${this.user.username}/messages/group/${item}`;
} else if (item === I18n.t("user.messages.tags")) {
url = `/u/${this.user.username}/messages/tags`;
} else {
url = `/u/${this.user.username}/messages`;
}
DiscourseURL.routeToUrl(url);
},
},
});

View File

@ -1,23 +0,0 @@
<div class="user-navigation user-navigation-secondary">
{{#if (gt @user.groupsWithMessages.length 0)}}
<ol class="category-breadcrumb">
<li>
<UserNav::MessagesGroupsDropdown @user={{@user}} @pmTaggingEnabled={{@pmTaggingEnabled}} @value={{this.messagesDropdownvalue}} />
</li>
</ol>
{{/if}}
<HorizontalOverflowNav @className="messages-nav" id="user-navigation-secondary__horizontal-nav" />
{{#if this.site.desktopView}}
<div class="navigation-controls">
{{#if @isGroup}}
<GroupNotificationsButton @value={{@group.group_user.notification_level}} @onChange={{action @changeGroupNotificationLevel}} />
{{/if}}
{{#if @showNewPM}}
<DButton @class="btn-primary new-private-message" @action={{route-action "composePrivateMessage"}} @icon="envelope" @label="user.new_private_message" />
{{/if}}
</div>
{{/if}}
</div>

View File

@ -1,25 +0,0 @@
import Component from "@glimmer/component";
import { inject as service } from "@ember/service";
export default class UserNavMessagesNav extends Component {
@service site;
get messagesDropdownvalue() {
switch (this.args.currentRouteName) {
case "userPrivateMessages.tags":
case "userPrivateMessages.tags.index":
case "userPrivateMessages.tags.show":
return "tags";
default:
if (this.args.groupFilter) {
return this.args.groupFilter;
} else {
return "inbox";
}
}
}
get displayTags() {
return this.args.pmTaggingEnabled && this.messagesDropdownvalue === "tags";
}
}

View File

@ -4,6 +4,7 @@ import { inject as service } from "@ember/service";
import { alias, and, equal, readOnly } from "@ember/object/computed";
import { tracked } from "@glimmer/tracking";
import I18n from "I18n";
import DiscourseURL from "discourse/lib/url";
export const PERSONAL_INBOX = "__personal_inbox__";
@ -23,6 +24,51 @@ export default class extends Controller {
@readOnly("router.currentRoute.parent.name") currentParentRouteName;
@readOnly("site.can_tag_pms") pmTaggingEnabled;
get messagesDropdownValue() {
const parentRoute = this.router.currentRoute.parent;
if (Object.keys(parentRoute.params).length > 0) {
return this.router.urlFor(
parentRoute.name,
this.model.username,
parentRoute.params
);
} else {
return this.router.urlFor(parentRoute.name, this.model.username);
}
}
get messagesDropdownContent() {
const content = [
{
id: this.router.urlFor("userPrivateMessages.user", this.model.username),
name: I18n.t("user.messages.inbox"),
},
];
this.model.groupsWithMessages.forEach((group) => {
content.push({
id: this.router.urlFor(
"userPrivateMessages.group",
this.model.username,
group.name
),
name: group.name,
icon: "inbox",
});
});
if (this.pmTaggingEnabled) {
content.push({
id: this.router.urlFor("userPrivateMessages.tags", this.model.username),
name: I18n.t("user.messages.tags"),
icon: "tags",
});
}
return content;
}
@computed(
"pmTopicTrackingState.newIncoming.[]",
"pmTopicTrackingState.statesModificationCounter",
@ -55,4 +101,9 @@ export default class extends Controller {
changeGroupNotificationLevel(notificationLevel) {
this.group.setNotification(notificationLevel, this.get("user.model.id"));
}
@action
onMessagesDropdownChange(item) {
return DiscourseURL.routeTo(item);
}
}

View File

@ -1,22 +1,30 @@
{{#if this.currentUser.redesigned_user_page_nav_enabled}}
<DSection @pageClass="user-messages" />
<UserNav::MessagesNav
@user={{this.model}}
@isPersonal={{this.isPersonal}}
@viewingSelf={{this.viewingSelf}}
@isGroup={{this.isGroup}}
@groupFilter={{this.groupFilter}}
@newLinkText={{this.newLinkText}}
@unreadLinkText={{this.unreadLinkText}}
@archiveLinkText={{this.archiveLinkText}}
@pmTaggingEnabled={{this.pmTaggingEnabled}}
@tagId={{this.tagId}}
@showNewPM={{this.showNewPM}}
@group={{this.group}}
@changeGroupNotificationLevel={{action "changeGroupNotificationLevel"}}
@currentRouteName={{this.currentRouteName}}
/>
<div class="user-navigation user-navigation-secondary">
<ol class="category-breadcrumb">
<li>
<UserNav::MessagesDropdown
@content={{this.messagesDropdownContent}}
@value={{this.messagesDropdownValue}}
@onChange={{this.onMessagesDropdownChange}}/>
</li>
</ol>
<HorizontalOverflowNav @className="messages-nav" id="user-navigation-secondary__horizontal-nav" />
{{#if this.site.desktopView}}
<div class="navigation-controls">
{{#if this.isGroup}}
<GroupNotificationsButton @value={{this.group.group_user.notification_level}} @onChange={{this.changeGroupNotificationLevel}} />
{{/if}}
{{#if this.showNewPM}}
<DButton @class="btn-primary new-private-message" @action={{route-action "composePrivateMessage"}} @icon="envelope" @label="user.new_private_message" />
{{/if}}
</div>
{{/if}}
</div>
{{else}}
<DSection @class="user-secondary-navigation" @pageClass="user-messages">
<MobileNav @class="messages-nav" @desktopClass="nav-stacked action-list">

View File

@ -84,7 +84,7 @@ function testUserPrivateMessagesWithGroupMessages(needs, customUserProps) {
needs.pretender((server, helper) => {
server.get("/tags/personal_messages/:username.json", () => {
return helper.response({ tags: [] });
return helper.response({ tags: [{ id: "tag1" }] });
});
server.get("/t/13.json", () => {
@ -125,6 +125,7 @@ function testUserPrivateMessagesWithGroupMessages(needs, customUserProps) {
"/topics/private-messages-group/:username/:group_name/new.json",
"/topics/private-messages-group/:username/:group_name/unread.json",
"/topics/private-messages-group/:username/:group_name/archive.json",
"/topics/private-messages-tags/:username/:tag_name",
].forEach((url) => {
server.get(url, () => {
let topics;
@ -685,6 +686,74 @@ function testUserPrivateMessagesWithGroupMessages(needs, customUserProps) {
"displays the right browse more message"
);
});
if (customUserProps?.redesigned_user_page_nav_enabled) {
test("navigating between user messages route with dropdown", async function (assert) {
await visit("/u/charlie/messages");
const messagesDropdown = selectKit(".user-nav-messages-dropdown");
assert.strictEqual(
messagesDropdown.header().name(),
I18n.t("user.messages.inbox"),
"User personal inbox is selected in dropdown"
);
await click(".messages-sent");
assert.strictEqual(
messagesDropdown.header().name(),
I18n.t("user.messages.inbox"),
"User personal inbox is still selected when viewing sent messages"
);
await messagesDropdown.expand();
await messagesDropdown.selectRowByName("awesome_group");
assert.strictEqual(
currentURL(),
"/u/charlie/messages/group/awesome_group",
"routes to the right URL when selecting awesome_group in the dropdown"
);
assert.strictEqual(
messagesDropdown.header().name(),
"awesome_group",
"Group inbox is selected in dropdown"
);
await click(".messages-group-new");
assert.strictEqual(
messagesDropdown.header().name(),
"awesome_group",
"Group inbox is still selected in dropdown"
);
await messagesDropdown.expand();
await messagesDropdown.selectRowByName(I18n.t("user.messages.tags"));
assert.strictEqual(
currentURL(),
"/u/charlie/messages/tags",
"routes to the right URL when selecting tags in the dropdown"
);
assert.strictEqual(
messagesDropdown.header().name(),
I18n.t("user.messages.tags"),
"All tags is selected in dropdown"
);
await click(".discourse-tag[data-tag-name='tag1']");
assert.strictEqual(
messagesDropdown.header().name(),
I18n.t("user.messages.tags"),
"All tags is still selected in dropdown"
);
});
}
}
acceptance(