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.beta3-dev: 6472f4593e1a4abbb457288db012ddb10f0b16f5
|
||||||
< 3.4.0.beta1-dev: fe725251c1b248c349c38c96432e892c668822c6
|
< 3.4.0.beta1-dev: fe725251c1b248c349c38c96432e892c668822c6
|
||||||
< 3.3.0.beta2-dev: b796ae3fcc89b48cf777de5ee3a4c21aada9271e
|
< 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.addUserSearchOption("assignableGroups");
|
||||||
|
|
||||||
|
api.addSaveableUserOptionField("notification_level_when_assigned");
|
||||||
|
|
||||||
api.addBulkActionButton({
|
api.addBulkActionButton({
|
||||||
id: "assign-topics",
|
id: "assign-topics",
|
||||||
label: "topics.bulk.assign",
|
label: "topics.bulk.assign",
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,11 @@ en:
|
||||||
assignable_levels:
|
assignable_levels:
|
||||||
title: "Who can assign this group"
|
title: "Who can assign this group"
|
||||||
user:
|
user:
|
||||||
|
notification_level_when_assigned:
|
||||||
|
label: "When assigned"
|
||||||
|
watch_topic: "Watch topic"
|
||||||
|
track_topic: "Track topic"
|
||||||
|
do_nothing: "Do nothing"
|
||||||
messages:
|
messages:
|
||||||
assigned_title: "Assigned (%{count})"
|
assigned_title: "Assigned (%{count})"
|
||||||
assigned: "Assigned"
|
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)
|
publish_assignment(assignment, assign_to, note, status)
|
||||||
|
|
||||||
if assignment.assigned_to_user?
|
if assignment.assigned_to_user?
|
||||||
if !TopicUser.exists?(
|
if !assign_to.user_option.do_nothing_when_assigned?
|
||||||
user_id: assign_to.id,
|
notification_level =
|
||||||
topic_id: topic.id,
|
if assign_to.user_option.track_topic_when_assigned?
|
||||||
notification_level: TopicUser.notification_levels[:watching],
|
TopicUser.notification_levels[:tracking]
|
||||||
)
|
else
|
||||||
TopicUser.change(
|
TopicUser.notification_levels[:watching]
|
||||||
assign_to.id,
|
end
|
||||||
topic.id,
|
|
||||||
notification_level: TopicUser.notification_levels[:watching],
|
topic_user = TopicUser.find_by(user_id: assign_to.id, topic:)
|
||||||
notifications_reason_id: TopicUser.notification_reasons[:plugin_changed],
|
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
|
end
|
||||||
|
|
||||||
if SiteSetting.assign_mailer == AssignMailer.levels[:always] ||
|
if SiteSetting.assign_mailer == AssignMailer.levels[:always] ||
|
||||||
|
|
@ -506,6 +508,7 @@ class ::Assigner
|
||||||
@assigned_by,
|
@assigned_by,
|
||||||
text,
|
text,
|
||||||
bump: false,
|
bump: false,
|
||||||
|
auto_track: false,
|
||||||
post_type: SiteSetting.assigns_public ? Post.types[:small_action] : Post.types[:whisper],
|
post_type: SiteSetting.assigns_public ? Post.types[:small_action] : Post.types[:whisper],
|
||||||
action_code: action_code,
|
action_code: action_code,
|
||||||
custom_fields: custom_fields,
|
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"
|
require_relative "lib/validators/assign_statuses_validator"
|
||||||
|
|
||||||
after_initialize do
|
after_initialize do
|
||||||
|
UserUpdater::OPTION_ATTR.push(:notification_level_when_assigned)
|
||||||
|
|
||||||
reloadable_patch do |plugin|
|
reloadable_patch do |plugin|
|
||||||
Group.prepend(DiscourseAssign::GroupExtension)
|
Group.prepend(DiscourseAssign::GroupExtension)
|
||||||
ListController.prepend(DiscourseAssign::ListControllerExtension)
|
ListController.prepend(DiscourseAssign::ListControllerExtension)
|
||||||
|
|
@ -29,6 +31,15 @@ after_initialize do
|
||||||
Topic.prepend(DiscourseAssign::TopicExtension)
|
Topic.prepend(DiscourseAssign::TopicExtension)
|
||||||
WebHook.prepend(DiscourseAssign::WebHookExtension)
|
WebHook.prepend(DiscourseAssign::WebHookExtension)
|
||||||
Notification.prepend(DiscourseAssign::NotificationExtension)
|
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
|
end
|
||||||
|
|
||||||
register_group_param(:assignable_level)
|
register_group_param(:assignable_level)
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,46 @@ RSpec.describe Assigner do
|
||||||
)
|
)
|
||||||
end
|
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
|
it "deletes notification for original assignee when reassigning" do
|
||||||
Jobs.run_immediately!
|
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