FEATURE: new "notification level when assigned" user preference (#626)
This adds a new user preference allowed users to control how the notification level of the topic they're assigned to changes. Internal ref - t/141162
This commit is contained in:
parent
654f197003
commit
8c52b9a31c
|
|
@ -1,3 +1,4 @@
|
|||
< 3.4.0.beta4-dev: 654f197003f9cdf1926b07137fc2214b21c91a79
|
||||
< 3.4.0.beta3-dev: 6472f4593e1a4abbb457288db012ddb10f0b16f5
|
||||
< 3.4.0.beta1-dev: fe725251c1b248c349c38c96432e892c668822c6
|
||||
< 3.3.0.beta2-dev: b796ae3fcc89b48cf777de5ee3a4c21aada9271e
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
import Component from "@glimmer/component";
|
||||
import { service } from "@ember/service";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import ComboBox from "select-kit/components/combo-box";
|
||||
|
||||
export default class NotificationLevelWhenAssigned extends Component {
|
||||
@service siteSettings;
|
||||
|
||||
constructor(owner, args) {
|
||||
super(...arguments);
|
||||
if (this.siteSettings.assign_enabled) {
|
||||
args.outletArgs.customAttrNames.push("notification_level_when_assigned");
|
||||
}
|
||||
}
|
||||
|
||||
get notificationLevelsWhenAssigned() {
|
||||
// The order matches the "notification level when replying" user preference
|
||||
return [
|
||||
{
|
||||
name: i18n("user.notification_level_when_assigned.watch_topic"),
|
||||
value: "watch_topic",
|
||||
},
|
||||
{
|
||||
name: i18n("user.notification_level_when_assigned.track_topic"),
|
||||
value: "track_topic",
|
||||
},
|
||||
{
|
||||
name: i18n("user.notification_level_when_assigned.do_nothing"),
|
||||
value: "do_nothing",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
<template>
|
||||
{{#if this.siteSettings.assign_enabled}}
|
||||
<div
|
||||
class="controls controls-dropdown"
|
||||
data-setting-name="user-notification-level-when-assigned"
|
||||
>
|
||||
<label>{{i18n "user.notification_level_when_assigned.label"}}</label>
|
||||
<ComboBox
|
||||
@content={{this.notificationLevelsWhenAssigned}}
|
||||
@value={{@outletArgs.model.user_option.notification_level_when_assigned}}
|
||||
@valueProperty="value"
|
||||
@onChange={{action
|
||||
(mut @outletArgs.model.user_option.notification_level_when_assigned)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{{/if}}
|
||||
</template>
|
||||
}
|
||||
|
|
@ -860,6 +860,8 @@ export default {
|
|||
|
||||
api.addUserSearchOption("assignableGroups");
|
||||
|
||||
api.addSaveableUserOptionField("notification_level_when_assigned");
|
||||
|
||||
api.addBulkActionButton({
|
||||
id: "assign-topics",
|
||||
label: "topics.bulk.assign",
|
||||
|
|
|
|||
|
|
@ -100,6 +100,11 @@ en:
|
|||
assignable_levels:
|
||||
title: "Who can assign this group"
|
||||
user:
|
||||
notification_level_when_assigned:
|
||||
label: "When assigned"
|
||||
watch_topic: "Watch topic"
|
||||
track_topic: "Track topic"
|
||||
do_nothing: "Do nothing"
|
||||
messages:
|
||||
assigned_title: "Assigned (%{count})"
|
||||
assigned: "Assigned"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
class AddNotificationLevelWhenAssignedUserOption < ActiveRecord::Migration[7.2]
|
||||
def change
|
||||
add_column :user_options, :notification_level_when_assigned, :integer, null: false, default: 3 # watch topic
|
||||
end
|
||||
end
|
||||
|
|
@ -329,17 +329,19 @@ class ::Assigner
|
|||
publish_assignment(assignment, assign_to, note, status)
|
||||
|
||||
if assignment.assigned_to_user?
|
||||
if !TopicUser.exists?(
|
||||
user_id: assign_to.id,
|
||||
topic_id: topic.id,
|
||||
notification_level: TopicUser.notification_levels[:watching],
|
||||
)
|
||||
TopicUser.change(
|
||||
assign_to.id,
|
||||
topic.id,
|
||||
notification_level: TopicUser.notification_levels[:watching],
|
||||
notifications_reason_id: TopicUser.notification_reasons[:plugin_changed],
|
||||
)
|
||||
if !assign_to.user_option.do_nothing_when_assigned?
|
||||
notification_level =
|
||||
if assign_to.user_option.track_topic_when_assigned?
|
||||
TopicUser.notification_levels[:tracking]
|
||||
else
|
||||
TopicUser.notification_levels[:watching]
|
||||
end
|
||||
|
||||
topic_user = TopicUser.find_by(user_id: assign_to.id, topic:)
|
||||
if !topic_user || topic_user.notification_level < notification_level
|
||||
notifications_reason_id = TopicUser.notification_reasons[:plugin_changed]
|
||||
TopicUser.change(assign_to.id, topic.id, notification_level:, notifications_reason_id:)
|
||||
end
|
||||
end
|
||||
|
||||
if SiteSetting.assign_mailer == AssignMailer.levels[:always] ||
|
||||
|
|
@ -506,6 +508,7 @@ class ::Assigner
|
|||
@assigned_by,
|
||||
text,
|
||||
bump: false,
|
||||
auto_track: false,
|
||||
post_type: SiteSetting.assigns_public ? Post.types[:small_action] : Post.types[:whisper],
|
||||
action_code: action_code,
|
||||
custom_fields: custom_fields,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module DiscourseAssign
|
||||
module UserOptionExtension
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
prepended do
|
||||
enum :notification_level_when_assigned,
|
||||
{ do_nothing: 1, track_topic: 2, watch_topic: 3 },
|
||||
suffix: "when_assigned"
|
||||
end
|
||||
end
|
||||
end
|
||||
11
plugin.rb
11
plugin.rb
|
|
@ -22,6 +22,8 @@ require_relative "lib/discourse_assign/engine"
|
|||
require_relative "lib/validators/assign_statuses_validator"
|
||||
|
||||
after_initialize do
|
||||
UserUpdater::OPTION_ATTR.push(:notification_level_when_assigned)
|
||||
|
||||
reloadable_patch do |plugin|
|
||||
Group.prepend(DiscourseAssign::GroupExtension)
|
||||
ListController.prepend(DiscourseAssign::ListControllerExtension)
|
||||
|
|
@ -29,6 +31,15 @@ after_initialize do
|
|||
Topic.prepend(DiscourseAssign::TopicExtension)
|
||||
WebHook.prepend(DiscourseAssign::WebHookExtension)
|
||||
Notification.prepend(DiscourseAssign::NotificationExtension)
|
||||
UserOption.prepend(DiscourseAssign::UserOptionExtension)
|
||||
end
|
||||
|
||||
add_to_serializer(:user_option, :notification_level_when_assigned) do
|
||||
object.notification_level_when_assigned
|
||||
end
|
||||
|
||||
add_to_serializer(:current_user_option, :notification_level_when_assigned) do
|
||||
object.notification_level_when_assigned
|
||||
end
|
||||
|
||||
register_group_param(:assignable_level)
|
||||
|
|
|
|||
|
|
@ -43,6 +43,46 @@ RSpec.describe Assigner do
|
|||
)
|
||||
end
|
||||
|
||||
describe "when user watchs topic when assigned" do
|
||||
before { moderator.user_option.watch_topic_when_assigned! }
|
||||
|
||||
it "respects 'when assigned' user preference" do
|
||||
expect(TopicUser.find_by(user: moderator)).to be(nil)
|
||||
|
||||
assigner.assign(moderator)
|
||||
|
||||
expect(TopicUser.find_by(user: moderator).notification_level).to eq(
|
||||
TopicUser.notification_levels[:watching],
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when user tracks topic when assigned" do
|
||||
before { moderator.user_option.track_topic_when_assigned! }
|
||||
|
||||
it "respects 'when assigned' user preference" do
|
||||
expect(TopicUser.find_by(user: moderator)).to be(nil)
|
||||
|
||||
assigner.assign(moderator)
|
||||
|
||||
expect(TopicUser.find_by(user: moderator).notification_level).to eq(
|
||||
TopicUser.notification_levels[:tracking],
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when user wants to do nothing when assigned" do
|
||||
before { moderator.user_option.do_nothing_when_assigned! }
|
||||
|
||||
it "respects 'when assigned' user preference" do
|
||||
expect(TopicUser.find_by(user: moderator)).to be(nil)
|
||||
|
||||
assigner.assign(moderator)
|
||||
|
||||
expect(TopicUser.find_by(user: moderator)).to be(nil)
|
||||
end
|
||||
end
|
||||
|
||||
it "deletes notification for original assignee when reassigning" do
|
||||
Jobs.run_immediately!
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe "Assign | User Preferences", type: :system, js: true do
|
||||
fab!(:user)
|
||||
|
||||
let(:selector) { "[data-setting-name='user-notification-level-when-assigned'] .combobox" }
|
||||
|
||||
before { sign_in(user) }
|
||||
|
||||
describe "when discourse-assign is disabled" do
|
||||
before { SiteSetting.assign_enabled = false }
|
||||
|
||||
it "does not show the 'when assigned' tracking user preference" do
|
||||
visit "/my/preferences/tracking"
|
||||
|
||||
expect(page).not_to have_css(selector)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when discourse-assign is enabled" do
|
||||
before { SiteSetting.assign_enabled = true }
|
||||
|
||||
let(:when_assigned) { PageObjects::Components::SelectKit.new(selector) }
|
||||
|
||||
it "shows the 'when assigned' tracking user preference" do
|
||||
visit "/my/preferences/tracking"
|
||||
|
||||
expect(when_assigned).to have_selected_value("watch_topic")
|
||||
end
|
||||
|
||||
it "supports changing the 'when assigned' tracking user preference" do
|
||||
visit "/my/preferences/tracking"
|
||||
|
||||
when_assigned.expand
|
||||
when_assigned.select_row_by_value("track_topic")
|
||||
|
||||
page.find("button.save-changes").click
|
||||
page.refresh
|
||||
|
||||
expect(when_assigned).to have_selected_value("track_topic")
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue