From f573fd8f5e11f7df144e4485b71751fa0cd07ff8 Mon Sep 17 00:00:00 2001 From: Ted Johansson Date: Fri, 8 Nov 2024 15:59:12 +0800 Subject: [PATCH] FEATURE: Add more bulk dismiss buttons with confirmation (#29331) When performing bulk dismissal in Unread and New views, the dismiss button stays at the top of the UI. Because of this we want to provide the dismiss action also in the "sticky" menu that's always in view, even when scrolling a long list of topics. --- .../bulk-select-topics-dropdown.gjs | 37 +++++++++++++++ app/assets/stylesheets/common/base/modal.scss | 4 ++ config/locales/client.en.yml | 2 + .../page_objects/modals/topic_bulk_actions.rb | 4 ++ spec/system/topic_bulk_select_spec.rb | 45 +++++++++++++++++++ 5 files changed, 92 insertions(+) diff --git a/app/assets/javascripts/discourse/app/components/bulk-select-topics-dropdown.gjs b/app/assets/javascripts/discourse/app/components/bulk-select-topics-dropdown.gjs index 0594e444ff9..b1504147501 100644 --- a/app/assets/javascripts/discourse/app/components/bulk-select-topics-dropdown.gjs +++ b/app/assets/javascripts/discourse/app/components/bulk-select-topics-dropdown.gjs @@ -7,6 +7,8 @@ import DropdownMenu from "discourse/components/dropdown-menu"; import BulkTopicActions, { addBulkDropdownAction, } from "discourse/components/modal/bulk-topic-actions"; +import DismissNew from "discourse/components/modal/dismiss-new"; +import DismissReadModal from "discourse/components/modal/dismiss-read"; import concatClass from "discourse/helpers/concat-class"; import icon from "discourse-common/helpers/d-icon"; import i18n from "discourse-common/helpers/i18n"; @@ -35,12 +37,25 @@ export function addBulkDropdownButton(opts) { } export default class BulkSelectTopicsDropdown extends Component { + @service router; @service modal; @service currentUser; @service siteSettings; get buttons() { let options = [ + { + id: "dismiss-unread", + icon: "check", + name: i18n("topic_bulk_actions.dismiss.name"), + visible: ({ router }) => router.currentRouteName === "discovery.unread", + }, + { + id: "dismiss-new", + icon: "check", + name: i18n("topic_bulk_actions.dismiss.name"), + visible: ({ router }) => router.currentRouteName === "discovery.new", + }, { id: "update-category", icon: "pencil", @@ -139,6 +154,7 @@ export default class BulkSelectTopicsDropdown extends Component { topics: this.args.bulkSelectHelper.selected, currentUser: this.currentUser, siteSettings: this.siteSettings, + router: this.router, }); } else { return true; @@ -186,6 +202,23 @@ export default class BulkSelectTopicsDropdown extends Component { await this.dMenu.close(); switch (actionId) { + case "dismiss-unread": + this.modal.show(DismissReadModal, { + model: { + title: "topics.bulk.dismiss_read_with_selected", + count: this.args.bulkSelectHelper.selected.length, + dismissRead: (dismissTopics) => this.dismissRead(dismissTopics), + }, + }); + break; + case "dismiss-new": + this.modal.show(DismissNew, { + model: { + selectedTopics: this.args.bulkSelectHelper.selected, + dismissCallback: (dismissTopics) => this.dismissRead(dismissTopics), + }, + }); + break; case "update-category": this.showBulkTopicActionsModal(actionId, "change_category", { description: i18n(`topic_bulk_actions.update_category.description`), @@ -257,6 +290,10 @@ export default class BulkSelectTopicsDropdown extends Component { } } + dismissRead(stopTracking) { + this.args.bulkSelectHelper.dismissRead(stopTracking ? "topics" : "posts"); + } + @action onRegisterApi(api) { this.dMenu = api; diff --git a/app/assets/stylesheets/common/base/modal.scss b/app/assets/stylesheets/common/base/modal.scss index a57a5ffe986..e1860380856 100644 --- a/app/assets/stylesheets/common/base/modal.scss +++ b/app/assets/stylesheets/common/base/modal.scss @@ -70,6 +70,10 @@ padding: 1rem 1.5rem; box-sizing: border-box; + &.empty { + display: none; + } + input { width: auto; diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index db90f6b253d..3a62d47deb7 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -3218,6 +3218,8 @@ en: filter: "There are no more topics." topic_bulk_actions: + dismiss: + name: "Dismiss" close_topics: name: "Close" note: "Note" diff --git a/spec/system/page_objects/modals/topic_bulk_actions.rb b/spec/system/page_objects/modals/topic_bulk_actions.rb index f0b541d81c0..1a02eb8cad0 100644 --- a/spec/system/page_objects/modals/topic_bulk_actions.rb +++ b/spec/system/page_objects/modals/topic_bulk_actions.rb @@ -12,6 +12,10 @@ module PageObjects find("#bulk-topics-confirm").click end + def click_dismiss_confirm + find("#dismiss-read-confirm").click + end + def click_silent find("#topic-bulk-action-options__silent").click end diff --git a/spec/system/topic_bulk_select_spec.rb b/spec/system/topic_bulk_select_spec.rb index 585126ed444..be7735e53bb 100644 --- a/spec/system/topic_bulk_select_spec.rb +++ b/spec/system/topic_bulk_select_spec.rb @@ -24,6 +24,51 @@ describe "Topic bulk select", type: :system do expect(topic_bulk_actions_modal).to be_open end + context "when dismissing unread topics" do + fab!(:topic) { Fabricate(:topic, user: admin) } + fab!(:post1) { create_post(user: admin, topic: topic) } + fab!(:post2) { create_post(topic: topic) } + + it "removes the topics from the list" do + sign_in(admin) + visit("/unread") + + topic_list_header.click_bulk_select_button + expect(topic_list).to have_topic_checkbox(topic) + + topic_list.click_topic_checkbox(topic) + + topic_list_header.click_bulk_select_topics_dropdown + topic_list_header.click_bulk_button("dismiss-unread") + + topic_bulk_actions_modal.click_dismiss_confirm + + expect(page).to have_text(I18n.t("js.topics.none.unread")) + end + end + + context "when dismissing new topics" do + fab!(:topic) { Fabricate(:topic, user: user) } + fab!(:post1) { create_post(user: user, topic: topic) } + + it "removes the topics from the list" do + sign_in(admin) + visit("/new") + + topic_list_header.click_bulk_select_button + expect(topic_list).to have_topic_checkbox(topic) + + topic_list.click_topic_checkbox(topic) + + topic_list_header.click_bulk_select_topics_dropdown + topic_list_header.click_bulk_button("dismiss-new") + + topic_bulk_actions_modal.click_dismiss_confirm + + expect(page).to have_text(I18n.t("js.topics.none.new")) + end + end + context "when appending tags" do fab!(:tag1) { Fabricate(:tag) } fab!(:tag2) { Fabricate(:tag) }