Skip to content

Commit

Permalink
WIP: use notifications for user menu
Browse files Browse the repository at this point in the history
  • Loading branch information
Flink committed Sep 14, 2023
1 parent bc44425 commit 59b8ead
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 343 deletions.
41 changes: 0 additions & 41 deletions app/controllers/discourse_assign/assign_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -159,43 +159,6 @@ def group_members
}
end

def user_menu_assigns
assign_notifications =
Notification.unread_type(current_user, Notification.types[:assigned], user_menu_limit)

if assign_notifications.size < user_menu_limit
opts = {}
ignored_assignment_ids =
assign_notifications.filter_map { |notification| notification.data_hash[:assignment_id] }
opts[:ignored_assignment_ids] = ignored_assignment_ids if ignored_assignment_ids.present?

assigns_list =
TopicQuery.new(
current_user,
per_page: user_menu_limit - assign_notifications.size,
).list_messages_assigned(current_user, ignored_assignment_ids)
end

if assign_notifications.present?
serialized_notifications =
ActiveModel::ArraySerializer.new(
assign_notifications,
each_serializer: NotificationSerializer,
scope: guardian,
)
end

if assigns_list
serialized_assigns =
serialize_data(assigns_list, TopicListSerializer, scope: guardian, root: false)[:topics]
end

render json: {
notifications: serialized_notifications || [],
topics: serialized_assigns || [],
}
end

private

def translate_failure(reason, assign_to)
Expand Down Expand Up @@ -261,10 +224,6 @@ def ensure_assign_allowed
raise Discourse::InvalidAccess.new unless current_user.can_assign?
end

def user_menu_limit
UsersController::USER_MENU_LIST_LIMIT
end

def recent_assignees
User
.where("users.id <> ?", current_user.id)
Expand Down
76 changes: 35 additions & 41 deletions app/jobs/regular/assign_notification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,49 @@
module Jobs
class AssignNotification < ::Jobs::Base
def execute(args)
raise Discourse::InvalidParameters.new(:topic_id) if args[:topic_id].nil?
raise Discourse::InvalidParameters.new(:post_id) if args[:post_id].nil?
raise Discourse::InvalidParameters.new(:assigned_to_id) if args[:assigned_to_id].nil?
raise Discourse::InvalidParameters.new(:assigned_to_type) if args[:assigned_to_type].nil?
raise Discourse::InvalidParameters.new(:assigned_by_id) if args[:assigned_by_id].nil?
raise Discourse::InvalidParameters.new(:assignment_id) if args[:assignment_id].nil?

if args[:skip_small_action_post].nil?
raise Discourse::InvalidParameters.new(:skip_small_action_post)
%i[
topic_id
post_id
assigned_to_id
assigned_to_type
assigned_by_id
assignment_id
skip_small_action_post
].each do |argument|
raise Discourse::InvalidParameters.new(argument) if args[argument].blank?
end

topic = Topic.find(args[:topic_id])
post = Post.find(args[:post_id])
assigned_by = User.find(args[:assigned_by_id])
assigned_to =
(
if args[:assigned_to_type] == "User"
User.find(args[:assigned_to_id])
else
Group.find(args[:assigned_to_id])
end
)
assigned_to_users = args[:assigned_to_type] == "User" ? [assigned_to] : assigned_to.users
assigned_to = args[:assigned_to_type].constantize.find(args[:assigned_to_id])
assigned_users = Array.wrap(assigned_to.try(:users).presence || assigned_to)
assigned_to_user = args[:assigned_to_type] == "User"

assigned_to_users.each do |user|
assigned_users.each do |user|
Assigner.publish_topic_tracking_state(topic, user.id)

next if assigned_by == user

assigned_to_user = args[:assigned_to_type] == "User"

PostAlerter.new(post).create_notification_alert(
user: user,
post: post,
username: assigned_by.username,
notification_type: Notification.types[:assigned] || Notification.types[:custom],
excerpt:
I18n.t(
(
if assigned_to_user
"discourse_assign.topic_assigned_excerpt"
else
"discourse_assign.topic_group_assigned_excerpt"
end
unless assigned_by == user
PostAlerter.new(post).create_notification_alert(
user: user,
post: post,
username: assigned_by.username,
notification_type: Notification.types[:assigned] || Notification.types[:custom],
excerpt:
I18n.t(
(
if assigned_to_user
"discourse_assign.topic_assigned_excerpt"
else
"discourse_assign.topic_group_assigned_excerpt"
end
),
title: topic.title,
group: assigned_to.name,
locale: user.effective_locale,
),
title: topic.title,
group: assigned_to.name,
locale: user.effective_locale,
),
)
)
end

next if args[:skip_small_action_post]
Notification.create!(
Expand All @@ -61,6 +54,7 @@ def execute(args)
topic_id: topic.id,
post_number: post.post_number,
high_priority: true,
read: assigned_by == user,
data: {
message:
(
Expand Down
39 changes: 14 additions & 25 deletions app/jobs/regular/unassign_notification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,23 @@
module Jobs
class UnassignNotification < ::Jobs::Base
def execute(args)
raise Discourse::InvalidParameters.new(:topic_id) if args[:topic_id].nil?
raise Discourse::InvalidParameters.new(:assigned_to_id) if args[:assigned_to_id].nil?
raise Discourse::InvalidParameters.new(:assigned_to_type) if args[:assigned_to_type].nil?
%i[topic_id assigned_to_id assigned_to_type assignment_id].each do |argument|
raise Discourse::InvalidParameters.new(argument) if args[argument].blank?
end

topic = Topic.find(args[:topic_id])
assigned_to_users =
(
if args[:assigned_to_type] == "User"
[User.find(args[:assigned_to_id])]
else
Group.find(args[:assigned_to_id]).users
end
)

assigned_to_users.each do |user|
Assigner.publish_topic_tracking_state(topic, user.id)
assigned_to = args[:assigned_to_type].constantize.find(args[:assigned_to_id])
assigned_to_users = Array.wrap(assigned_to.try(:users).presence || assigned_to)

Notification
.where(
notification_type: Notification.types[:assigned] || Notification.types[:custom],
user_id: user.id,
topic_id: topic.id,
)
.where(
"data like '%discourse_assign.assign_notification%' OR data like '%discourse_assign.assign_group_notification%'",
)
.destroy_all
end
assigned_to_users.each { |user| Assigner.publish_topic_tracking_state(topic, user.id) }
Notification
.where(
notification_type: Notification.types[:assigned] || Notification.types[:custom],
user: assigned_to_users,
topic: topic,
)
.where("data like '%assignment_id\":?%'", args[:assignment_id])
.destroy_all
end
end
end
28 changes: 3 additions & 25 deletions assets/javascripts/discourse/components/user-menu/assigns-list.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import UserMenuNotificationsList from "discourse/components/user-menu/notifications-list";
import { ajax } from "discourse/lib/ajax";
import UserMenuNotificationItem from "discourse/lib/user-menu/notification-item";
import UserMenuAssignItem from "../../lib/user-menu/assign-item";
import Notification from "discourse/models/notification";
import I18n from "I18n";
import Topic from "discourse/models/topic";
import UserMenuAssignsListEmptyState from "./assigns-list-empty-state";

export default class UserMenuAssignNotificationsList extends UserMenuNotificationsList {
Expand Down Expand Up @@ -56,25 +51,8 @@ export default class UserMenuAssignNotificationsList extends UserMenuNotificatio
}

async fetchItems() {
const data = await ajax("/assign/user-menu-assigns.json");
const content = [];

const notifications = data.notifications.map((n) => Notification.create(n));
await Notification.applyTransformations(notifications);
notifications.forEach((notification) => {
content.push(
new UserMenuNotificationItem({
notification,
currentUser: this.currentUser,
siteSettings: this.siteSettings,
site: this.site,
})
);
});

const topics = data.topics.map((t) => Topic.create(t));
await Topic.applyTransformations(topics);
content.push(...topics.map((assign) => new UserMenuAssignItem({ assign })));
return content;
return (await super.fetchItems()).sort((a, b) =>
a.notification.data.message > b.notification.data.message ? -1 : 1
);
}
}
70 changes: 61 additions & 9 deletions assets/javascripts/discourse/initializers/assign-user-menu.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,73 @@
import { withPluginApi } from "discourse/lib/plugin-api";
import UserMenuAssignNotificationsList from "../components/user-menu/assigns-list";
import I18n from "I18n";

export default {
name: "assign-user-menu",

initialize(container) {
withPluginApi("1.2.0", (api) => {
const siteSettings = container.lookup("service:site-settings");
if (!siteSettings.assign_enabled) {
return;
}

const currentUser = api.getCurrentUser();
if (!currentUser?.can_assign) {
return;
}

if (api.registerNotificationTypeRenderer) {
api.registerNotificationTypeRenderer(
"assigned",
(NotificationItemBase) => {
return class extends NotificationItemBase {
get linkTitle() {
if (this.isGroup()) {
return I18n.t(
`user.assigned_to_group.${this.postOrTopic()}`,
{
group_name: this.notification.data.display_username,
}
);
}
return I18n.t(`user.assigned_to_you.${this.postOrTopic()}`);
}

get icon() {
return this.isGroup() ? "group-plus" : "user-plus";
}

get label() {
return "";
}

get description() {
return I18n.t(
`user.assignment_description.${this.postOrTopic()}`,
{
topic_title: this.notification.data.topic_title,
post_number: this.notification.post_number,
}
);
}

isGroup() {
return (
this.notification.data.message ===
"discourse_assign.assign_group_notification"
);
}

postOrTopic() {
return this.notification.post_number === 1 ? "topic" : "post";
}
};
}
);
}

if (api.registerUserMenuTab) {
const siteSettings = container.lookup("service:site-settings");
if (!siteSettings.assign_enabled) {
return;
}

const currentUser = api.getCurrentUser();
if (!currentUser?.can_assign) {
return;
}
api.registerUserMenuTab((UserMenuTab) => {
return class extends UserMenuTab {
id = "assign-list";
Expand Down
65 changes: 0 additions & 65 deletions assets/javascripts/discourse/lib/user-menu/assign-item.js

This file was deleted.

Loading

0 comments on commit 59b8ead

Please sign in to comment.