diff --git a/assets/javascripts/discourse/components/user-menu/assigns-list.js b/assets/javascripts/discourse/components/user-menu/assigns-list.js index f652cbeb..10bff99b 100644 --- a/assets/javascripts/discourse/components/user-menu/assigns-list.js +++ b/assets/javascripts/discourse/components/user-menu/assigns-list.js @@ -1,3 +1,5 @@ +import { set } from "@ember/object"; +import { sort } from "@ember/object/computed"; import UserMenuNotificationsList from "discourse/components/user-menu/notifications-list"; import I18n from "I18n"; import UserMenuAssignsListEmptyState from "./assigns-list-empty-state"; @@ -51,10 +53,20 @@ export default class UserMenuAssignNotificationsList extends UserMenuNotificatio } async fetchItems() { - // sorting by `data.message` length to group single user assignments and - // group assignments, then by `created_at` to keep chronological order. - return (await super.fetchItems()) - .sortBy("notification.data.message", "notification.created_at") - .reverse(); + return new SortedItems(await super.fetchItems()).sortedItems; + } +} + +class SortedItems { + itemsSorting = [ + "notification.read", + "notification.data.message:desc", + "notification.created_at:desc", + ]; + + @sort("items", "itemsSorting") sortedItems; + + constructor(items) { + set(this, "items", items); } } diff --git a/spec/fabricators/notification_fabricator.rb b/spec/fabricators/notification_fabricator.rb new file mode 100644 index 00000000..0ac16a59 --- /dev/null +++ b/spec/fabricators/notification_fabricator.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +Fabricator(:assignment_notification, from: :notification) do + transient :group + notification_type Notification.types[:assigned] + post_number 1 + data do |attrs| + { + message: + ( + if attrs[:group] + "discourse_assign.assign_group_notification" + else + "discourse_assign.assign_notification" + end + ), + display_username: attrs[:group] ? "group" : "user", + assignment_id: rand(1..100), + }.to_json + end +end diff --git a/spec/system/page_objects/pages/user_menu.rb b/spec/system/page_objects/pages/user_menu.rb new file mode 100644 index 00000000..e75f5d5d --- /dev/null +++ b/spec/system/page_objects/pages/user_menu.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module PageObjects + module Components + class UserMenu < PageObjects::Components::Base + def click_assignments_tab + click_link("user-menu-button-assign-list") + has_css?("#quick-access-assign-list") + self + end + + def has_assignments_in_order?(assignments) + expect(all(".notification.assigned .item-description").map(&:text)).to eq(assignments) + end + end + end +end diff --git a/spec/system/user_menu_spec.rb b/spec/system/user_menu_spec.rb new file mode 100644 index 00000000..73f22b35 --- /dev/null +++ b/spec/system/user_menu_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +RSpec.describe "Assign | User Menu", type: :system, js: true do + fab!(:admin) { Fabricate(:admin) } + + let(:user_menu) { PageObjects::Components::UserMenu.new } + + before do + SiteSetting.assign_enabled = true + sign_in(admin) + end + + describe "Assign tab ordering" do + let!(:unread_user_assign) { Fabricate(:assignment_notification, user: admin) } + let!(:unread_user_assign_2) { Fabricate(:assignment_notification, user: admin) } + let!(:read_user_assign) { Fabricate(:assignment_notification, user: admin, read: true) } + let!(:read_user_assign_2) { Fabricate(:assignment_notification, user: admin, read: true) } + let!(:unread_group_assign) { Fabricate(:assignment_notification, user: admin, group: true) } + let!(:read_group_assign) do + Fabricate(:assignment_notification, user: admin, read: true, group: true) + end + let(:expected_order) do + [ + unread_user_assign_2, + unread_user_assign, + unread_group_assign, + read_user_assign_2, + read_user_assign, + read_group_assign, + ].map { _1.topic.fancy_title } + end + + it "orders the items properly" do + visit "/" + user_menu.open + user_menu.click_assignments_tab + expect(user_menu).to have_assignments_in_order(expected_order) + end + end +end