Merge branch 'discourse:main' into patch-1
This commit is contained in:
commit
eeea2875ea
|
@ -1,4 +1,5 @@
|
||||||
3.1.999: 0cbf10b8055370445bd36536e51986bf48bdc57e
|
< 3.2.0.beta2-dev: ac930c509e2a5b0c37b84bcea28d332e686add95
|
||||||
|
3.1.999: a304cd2028ccf1f5b00f5137633aa7027a1fd334
|
||||||
3.1.0.beta3: 9c270cac9abc1c2b30574d8c655fb3a90546236b
|
3.1.0.beta3: 9c270cac9abc1c2b30574d8c655fb3a90546236b
|
||||||
2.9.0.beta8: 28bc8ab78a09551548c87f511ade3d64e1b04bc3
|
2.9.0.beta8: 28bc8ab78a09551548c87f511ade3d64e1b04bc3
|
||||||
2.9.0.beta3: 46f200935dc9e5750c3f2740abd993e27a9b3f6c
|
2.9.0.beta3: 46f200935dc9e5750c3f2740abd993e27a9b3f6c
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
module.exports = require("@discourse/lint-configs/eslint");
|
|
@ -1,4 +1,3 @@
|
||||||
.bundle/
|
node_modules
|
||||||
auto_generated
|
/gems
|
||||||
.DS_Store
|
/auto_generated
|
||||||
node_modules/
|
|
|
@ -1 +0,0 @@
|
||||||
{}
|
|
|
@ -0,0 +1 @@
|
||||||
|
module.exports = require("@discourse/lint-configs/prettier");
|
|
@ -0,0 +1 @@
|
||||||
|
module.exports = require("@discourse/lint-configs/template-lint");
|
|
@ -1,4 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
plugins: ["ember-template-lint-plugin-discourse"],
|
|
||||||
extends: "discourse:recommended",
|
|
||||||
};
|
|
44
Gemfile.lock
44
Gemfile.lock
|
@ -2,43 +2,45 @@ GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
ast (2.4.2)
|
ast (2.4.2)
|
||||||
json (2.6.3)
|
json (2.7.1)
|
||||||
parallel (1.23.0)
|
language_server-protocol (3.17.0.3)
|
||||||
parser (3.2.2.3)
|
parallel (1.24.0)
|
||||||
|
parser (3.3.0.3)
|
||||||
ast (~> 2.4.1)
|
ast (~> 2.4.1)
|
||||||
racc
|
racc
|
||||||
prettier_print (1.2.1)
|
prettier_print (1.2.1)
|
||||||
racc (1.7.1)
|
racc (1.7.3)
|
||||||
rainbow (3.1.1)
|
rainbow (3.1.1)
|
||||||
regexp_parser (2.8.1)
|
regexp_parser (2.9.0)
|
||||||
rexml (3.2.5)
|
rexml (3.2.6)
|
||||||
rubocop (1.52.1)
|
rubocop (1.59.0)
|
||||||
json (~> 2.3)
|
json (~> 2.3)
|
||||||
|
language_server-protocol (>= 3.17.0)
|
||||||
parallel (~> 1.10)
|
parallel (~> 1.10)
|
||||||
parser (>= 3.2.2.3)
|
parser (>= 3.2.2.4)
|
||||||
rainbow (>= 2.2.2, < 4.0)
|
rainbow (>= 2.2.2, < 4.0)
|
||||||
regexp_parser (>= 1.8, < 3.0)
|
regexp_parser (>= 1.8, < 3.0)
|
||||||
rexml (>= 3.2.5, < 4.0)
|
rexml (>= 3.2.5, < 4.0)
|
||||||
rubocop-ast (>= 1.28.0, < 2.0)
|
rubocop-ast (>= 1.30.0, < 2.0)
|
||||||
ruby-progressbar (~> 1.7)
|
ruby-progressbar (~> 1.7)
|
||||||
unicode-display_width (>= 2.4.0, < 3.0)
|
unicode-display_width (>= 2.4.0, < 3.0)
|
||||||
rubocop-ast (1.29.0)
|
rubocop-ast (1.30.0)
|
||||||
parser (>= 3.2.1.0)
|
parser (>= 3.2.1.0)
|
||||||
rubocop-capybara (2.18.0)
|
rubocop-capybara (2.20.0)
|
||||||
rubocop (~> 1.41)
|
rubocop (~> 1.41)
|
||||||
rubocop-discourse (3.2.0)
|
rubocop-discourse (3.6.0)
|
||||||
rubocop (>= 1.1.0)
|
rubocop (>= 1.59.0)
|
||||||
rubocop-rspec (>= 2.0.0)
|
rubocop-rspec (>= 2.25.0)
|
||||||
rubocop-factory_bot (2.23.1)
|
rubocop-factory_bot (2.25.1)
|
||||||
rubocop (~> 1.33)
|
rubocop (~> 1.41)
|
||||||
rubocop-rspec (2.22.0)
|
rubocop-rspec (2.26.1)
|
||||||
rubocop (~> 1.33)
|
rubocop (~> 1.40)
|
||||||
rubocop-capybara (~> 2.17)
|
rubocop-capybara (~> 2.17)
|
||||||
rubocop-factory_bot (~> 2.22)
|
rubocop-factory_bot (~> 2.22)
|
||||||
ruby-progressbar (1.13.0)
|
ruby-progressbar (1.13.0)
|
||||||
syntax_tree (6.1.1)
|
syntax_tree (6.2.0)
|
||||||
prettier_print (>= 1.2.0)
|
prettier_print (>= 1.2.0)
|
||||||
unicode-display_width (2.4.2)
|
unicode-display_width (2.5.0)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
@ -48,4 +50,4 @@ DEPENDENCIES
|
||||||
syntax_tree
|
syntax_tree
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.3.4
|
2.5.4
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) Civilized Discourse Construction Kit
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
|
@ -159,43 +159,6 @@ module DiscourseAssign
|
||||||
}
|
}
|
||||||
end
|
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
|
private
|
||||||
|
|
||||||
def translate_failure(reason, assign_to)
|
def translate_failure(reason, assign_to)
|
||||||
|
@ -261,10 +224,6 @@ module DiscourseAssign
|
||||||
raise Discourse::InvalidAccess.new unless current_user.can_assign?
|
raise Discourse::InvalidAccess.new unless current_user.can_assign?
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_menu_limit
|
|
||||||
UsersController::USER_MENU_LIST_LIMIT
|
|
||||||
end
|
|
||||||
|
|
||||||
def recent_assignees
|
def recent_assignees
|
||||||
User
|
User
|
||||||
.where("users.id <> ?", current_user.id)
|
.where("users.id <> ?", current_user.id)
|
||||||
|
|
|
@ -3,79 +3,8 @@
|
||||||
module Jobs
|
module Jobs
|
||||||
class AssignNotification < ::Jobs::Base
|
class AssignNotification < ::Jobs::Base
|
||||||
def execute(args)
|
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?
|
raise Discourse::InvalidParameters.new(:assignment_id) if args[:assignment_id].nil?
|
||||||
|
Assignment.find(args[:assignment_id]).create_missing_notifications!
|
||||||
if args[:skip_small_action_post].nil?
|
|
||||||
raise Discourse::InvalidParameters.new(:skip_small_action_post)
|
|
||||||
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_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
|
|
||||||
),
|
|
||||||
title: topic.title,
|
|
||||||
group: assigned_to.name,
|
|
||||||
locale: user.effective_locale,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
next if args[:skip_small_action_post]
|
|
||||||
Notification.create!(
|
|
||||||
notification_type: Notification.types[:assigned] || Notification.types[:custom],
|
|
||||||
user_id: user.id,
|
|
||||||
topic_id: topic.id,
|
|
||||||
post_number: post.post_number,
|
|
||||||
high_priority: true,
|
|
||||||
data: {
|
|
||||||
message:
|
|
||||||
(
|
|
||||||
if assigned_to_user
|
|
||||||
"discourse_assign.assign_notification"
|
|
||||||
else
|
|
||||||
"discourse_assign.assign_group_notification"
|
|
||||||
end
|
|
||||||
),
|
|
||||||
display_username: assigned_to_user ? assigned_by.username : assigned_to.name,
|
|
||||||
topic_title: topic.title,
|
|
||||||
assignment_id: args[:assignment_id],
|
|
||||||
}.to_json,
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,34 +3,18 @@
|
||||||
module Jobs
|
module Jobs
|
||||||
class UnassignNotification < ::Jobs::Base
|
class UnassignNotification < ::Jobs::Base
|
||||||
def execute(args)
|
def execute(args)
|
||||||
raise Discourse::InvalidParameters.new(:topic_id) if args[:topic_id].nil?
|
%i[topic_id assigned_to_id assigned_to_type assignment_id].each do |argument|
|
||||||
raise Discourse::InvalidParameters.new(:assigned_to_id) if args[:assigned_to_id].nil?
|
raise Discourse::InvalidParameters.new(argument) if args[argument].nil?
|
||||||
raise Discourse::InvalidParameters.new(:assigned_to_type) if args[:assigned_to_type].nil?
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
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
|
end
|
||||||
|
|
||||||
|
assignment = Assignment.new(args.slice(:topic_id, :assigned_to_id, :assigned_to_type))
|
||||||
|
assignment.assigned_users.each do |user|
|
||||||
|
Assigner.publish_topic_tracking_state(assignment.topic, user.id)
|
||||||
|
end
|
||||||
|
Notification
|
||||||
|
.for_assignment(args[:assignment_id])
|
||||||
|
.where(user: assignment.assigned_users, topic: assignment.topic)
|
||||||
|
.destroy_all
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,13 +9,15 @@ class Assignment < ActiveRecord::Base
|
||||||
belongs_to :target, polymorphic: true
|
belongs_to :target, polymorphic: true
|
||||||
|
|
||||||
scope :joins_with_topics,
|
scope :joins_with_topics,
|
||||||
-> {
|
-> do
|
||||||
joins(
|
joins(
|
||||||
"INNER JOIN topics ON topics.id = assignments.target_id AND assignments.target_type = 'Topic' AND topics.deleted_at IS NULL",
|
"INNER JOIN topics ON topics.id = assignments.target_id AND assignments.target_type = 'Topic' AND topics.deleted_at IS NULL",
|
||||||
)
|
)
|
||||||
}
|
end
|
||||||
|
|
||||||
scope :active_for_group, ->(group) { where(assigned_to: group, active: true) }
|
scope :active_for_group, ->(group) { active.where(assigned_to: group) }
|
||||||
|
scope :active, -> { where(active: true) }
|
||||||
|
scope :inactive, -> { where(active: false) }
|
||||||
|
|
||||||
before_validation :default_status
|
before_validation :default_status
|
||||||
|
|
||||||
|
@ -38,11 +40,31 @@ class Assignment < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def assigned_to_user?
|
def assigned_to_user?
|
||||||
assigned_to_type == "User"
|
assigned_to.is_a?(User)
|
||||||
end
|
end
|
||||||
|
|
||||||
def assigned_to_group?
|
def assigned_to_group?
|
||||||
assigned_to_type == "Group"
|
assigned_to.is_a?(Group)
|
||||||
|
end
|
||||||
|
|
||||||
|
def assigned_users
|
||||||
|
Array.wrap(assigned_to.try(:users) || assigned_to)
|
||||||
|
end
|
||||||
|
|
||||||
|
def post
|
||||||
|
return target.posts.find_by(post_number: 1) if target.is_a?(Topic)
|
||||||
|
target
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_missing_notifications!
|
||||||
|
assigned_users.each do |user|
|
||||||
|
next if user.notifications.for_assignment(self).exists?
|
||||||
|
DiscourseAssign::CreateNotification.call(
|
||||||
|
assignment: self,
|
||||||
|
user: user,
|
||||||
|
mark_as_read: assigned_by_user == user,
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -2,7 +2,7 @@ export default {
|
||||||
resource: "user.userPrivateMessages",
|
resource: "user.userPrivateMessages",
|
||||||
|
|
||||||
map() {
|
map() {
|
||||||
this.route("assigned", { path: "/assigned" }, function () {
|
this.route("assigned", function () {
|
||||||
this.route("index", { path: "/" });
|
this.route("index", { path: "/" });
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
import { action } from "@ember/object";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box";
|
import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box";
|
||||||
import { action } from "@ember/object";
|
|
||||||
|
|
||||||
export default DropdownSelectBoxComponent.extend({
|
export default DropdownSelectBoxComponent.extend({
|
||||||
classNames: ["assign-actions-dropdown"],
|
classNames: ["assign-actions-dropdown"],
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
@id="assign-status"
|
@id="assign-status"
|
||||||
@content={{this.availableStatuses}}
|
@content={{this.availableStatuses}}
|
||||||
@value={{this.status}}
|
@value={{this.status}}
|
||||||
@onChange={{action (mut @model.status)}}
|
@onChange={{fn (mut @model.status)}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -51,7 +51,6 @@
|
||||||
<Textarea
|
<Textarea
|
||||||
id="assign-modal-note"
|
id="assign-modal-note"
|
||||||
@value={{@model.note}}
|
@value={{@model.note}}
|
||||||
{{! template-lint-disable no-down-event-binding }}
|
|
||||||
{{on "keydown" this.handleTextAreaKeydown}}
|
{{on "keydown" this.handleTextAreaKeydown}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
|
@ -9,8 +9,8 @@ export default class AssignUserForm extends Component {
|
||||||
@service capabilities;
|
@service capabilities;
|
||||||
|
|
||||||
@tracked assigneeError = false;
|
@tracked assigneeError = false;
|
||||||
@tracked assigneeName =
|
@tracked
|
||||||
this.args.model.username || this.args.model.group_name;
|
assigneeName = this.args.model.username || this.args.model.group_name;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(...arguments);
|
super(...arguments);
|
||||||
|
@ -26,9 +26,7 @@ export default class AssignUserForm extends Component {
|
||||||
|
|
||||||
get status() {
|
get status() {
|
||||||
return (
|
return (
|
||||||
this.args.model.status ||
|
this.args.model.status || this.siteSettings.assign_statuses.split("|")[0]
|
||||||
this.args.model.target.assignment_status ||
|
|
||||||
this.siteSettings.assign_statuses.split("|")[0]
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
import Component from "@glimmer/component";
|
||||||
|
import { action } from "@ember/object";
|
||||||
|
import { inject as service } from "@ember/service";
|
||||||
|
import AssignActionsDropdown from "./assign-actions-dropdown";
|
||||||
|
|
||||||
|
export default class AssignedTopicListColumn extends Component {
|
||||||
|
@service taskActions;
|
||||||
|
@service router;
|
||||||
|
|
||||||
|
@action
|
||||||
|
async unassign(targetId, targetType = "Topic") {
|
||||||
|
await this.taskActions.unassign(targetId, targetType);
|
||||||
|
this.router.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
reassign(topic) {
|
||||||
|
this.taskActions.showAssignModal(topic, {
|
||||||
|
onSuccess: () => this.router.refresh(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
<template>
|
||||||
|
{{#if @topic.assigned_to_user}}
|
||||||
|
<AssignActionsDropdown
|
||||||
|
@topic={{@topic}}
|
||||||
|
@assignee={{@topic.assigned_to_user.username}}
|
||||||
|
@unassign={{this.unassign}}
|
||||||
|
@reassign={{this.reassign}}
|
||||||
|
/>
|
||||||
|
{{else if @topic.assigned_to_group}}
|
||||||
|
<AssignActionsDropdown
|
||||||
|
@topic={{@topic}}
|
||||||
|
@assignee={{@topic.assigned_to_group.name}}
|
||||||
|
@group={{true}}
|
||||||
|
@unassign={{this.unassign}}
|
||||||
|
@reassign={{this.reassign}}
|
||||||
|
/>
|
||||||
|
{{else}}
|
||||||
|
<AssignActionsDropdown @topic={{@topic}} @unassign={{this.unassign}} />
|
||||||
|
{{/if}}
|
||||||
|
</template>
|
||||||
|
}
|
|
@ -1,86 +0,0 @@
|
||||||
{{!
|
|
||||||
The `~` syntax strip spaces between the elements, making it produce
|
|
||||||
`<a class=topic-post-badges>Some text</a><span class=topic-post-badges>`,
|
|
||||||
with no space between them.
|
|
||||||
This causes the topic-post-badge to be considered the same word as "text"
|
|
||||||
at the end of the link, preventing it from line wrapping onto its own line.
|
|
||||||
}}
|
|
||||||
{{#if this.bulkSelectEnabled}}
|
|
||||||
<td class="bulk-select topic-list-data">
|
|
||||||
<input type="checkbox" class="bulk-select" />
|
|
||||||
</td>
|
|
||||||
{{/if}}
|
|
||||||
<td class="main-link clearfix topic-list-data" colspan="1">
|
|
||||||
<span class="link-top-line">
|
|
||||||
{{~raw "topic-status" topic=this.topic}}
|
|
||||||
{{~#if this.isPrivateMessage}}
|
|
||||||
{{~d-icon "envelope" class="private-message-icon"}}
|
|
||||||
{{~/if}}
|
|
||||||
{{~topic-link this.topic class="raw-link raw-topic-link"}}
|
|
||||||
{{~#if this.topic.featured_link}}
|
|
||||||
{{~topic-featured-link this.topic}}
|
|
||||||
{{~/if}}
|
|
||||||
{{~#if this.showTopicPostBadges}}
|
|
||||||
{{~raw
|
|
||||||
"topic-post-badges"
|
|
||||||
unread=this.topic.unread
|
|
||||||
unseen=this.topic.unseen
|
|
||||||
url=this.topic.lastUnreadUrl
|
|
||||||
newDotText=this.newDotText
|
|
||||||
}}
|
|
||||||
{{~/if}}
|
|
||||||
</span>
|
|
||||||
<div class="link-bottom-line">
|
|
||||||
{{#if (or (not this.hideCategory) (not this.topic.isPinnedUncategorized))}}
|
|
||||||
{{category-link this.topic.category}}
|
|
||||||
{{/if}}
|
|
||||||
{{discourse-tags this.topic mode="list" tagsForUser=this.tagsForUser}}
|
|
||||||
{{raw
|
|
||||||
"list/action-list"
|
|
||||||
topic=this.topic
|
|
||||||
postNumbers=this.topic.liked_post_numbers
|
|
||||||
className="likes"
|
|
||||||
icon="heart"
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
{{#if this.expandPinned}}
|
|
||||||
{{raw "list/topic-excerpt" topic=this.topic}}
|
|
||||||
{{/if}}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
{{#if this.showPosters}}
|
|
||||||
{{raw "list/posters-column" posters=this.topic.featuredUsers}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{raw "list/posts-count-column" topic=this.topic}}
|
|
||||||
|
|
||||||
<td class="num views {{this.topic.viewsHeat}} topic-list-data">{{number
|
|
||||||
this.topic.views
|
|
||||||
numberKey="views_long"
|
|
||||||
}}</td>
|
|
||||||
{{raw
|
|
||||||
"list/activity-column"
|
|
||||||
topic=this.topic
|
|
||||||
class="num topic-list-data"
|
|
||||||
tagName="td"
|
|
||||||
}}
|
|
||||||
<td class="topic-list-data">
|
|
||||||
{{#if this.topic.assigned_to_user}}
|
|
||||||
<AssignActionsDropdown
|
|
||||||
@topic={{this.topic}}
|
|
||||||
@assignee={{this.topic.assigned_to_user.username}}
|
|
||||||
@unassign={{this.unassign}}
|
|
||||||
@reassign={{this.reassign}}
|
|
||||||
/>
|
|
||||||
{{else if this.topic.assigned_to_group}}
|
|
||||||
<AssignActionsDropdown
|
|
||||||
@topic={{this.topic}}
|
|
||||||
@assignee={{this.topic.assigned_to_group.name}}
|
|
||||||
@group={{true}}
|
|
||||||
@unassign={{this.unassign}}
|
|
||||||
@reassign={{this.reassign}}
|
|
||||||
/>
|
|
||||||
{{else}}
|
|
||||||
<AssignActionsDropdown @topic={{this.topic}} @unassign={{this.unassign}} />
|
|
||||||
{{/if}}
|
|
||||||
</td>
|
|
|
@ -1,8 +0,0 @@
|
||||||
import TopicListItem from "discourse/components/topic-list-item";
|
|
||||||
import { equal } from "@ember/object/computed";
|
|
||||||
|
|
||||||
export default class AssignedTopicListItem extends TopicListItem {
|
|
||||||
classNames = ["assigned-topic-list-item"];
|
|
||||||
|
|
||||||
@equal("topic.archetype", "private_message") isPrivateMessage;
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
{{#unless this.skipHeader}}
|
|
||||||
<thead class="topic-list-header assigned-topic-list-header">
|
|
||||||
{{raw
|
|
||||||
"topic-list-header"
|
|
||||||
canBulkSelect=this.canBulkSelect
|
|
||||||
canDoBulkActions=this.canDoBulkActions
|
|
||||||
toggleInTitle=this.toggleInTitle
|
|
||||||
hideCategory=this.hideCategory
|
|
||||||
showPosters=true
|
|
||||||
showLikes=this.showLikes
|
|
||||||
showOpLikes=this.showOpLikes
|
|
||||||
order=this.order
|
|
||||||
ascending=this.ascending
|
|
||||||
sortable=this.sortable
|
|
||||||
listTitle=this.listTitle
|
|
||||||
bulkSelectEnabled=this.bulkSelectEnabled
|
|
||||||
}}
|
|
||||||
</thead>
|
|
||||||
{{/unless}}
|
|
||||||
|
|
||||||
<tbody class="topic-list-body assigned-topic-list-body">
|
|
||||||
{{#each this.filteredTopics as |topic|}}
|
|
||||||
<AssignedTopicListItem
|
|
||||||
@topic={{topic}}
|
|
||||||
@bulkSelectEnabled={{this.bulkSelectEnabled}}
|
|
||||||
@showTopicPostBadges={{this.showTopicPostBadges}}
|
|
||||||
@hideCategory={{this.hideCategory}}
|
|
||||||
@showPosters={{true}}
|
|
||||||
@showLikes={{this.showLikes}}
|
|
||||||
@showOpLikes={{this.showOpLikes}}
|
|
||||||
@expandGloballyPinned={{this.expandGloballyPinned}}
|
|
||||||
@expandAllPinned={{this.expandAllPinned}}
|
|
||||||
@lastVisitedTopic={{this.lastVisitedTopic}}
|
|
||||||
@selected={{this.selected}}
|
|
||||||
@tagsForUser={{this.tagsForUser}}
|
|
||||||
@unassign={{this.unassign}}
|
|
||||||
@reassign={{this.reassign}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{{raw
|
|
||||||
"list/visited-line"
|
|
||||||
lastVisitedTopic=this.lastVisitedTopic
|
|
||||||
topic=topic
|
|
||||||
}}
|
|
||||||
{{/each}}
|
|
||||||
</tbody>
|
|
|
@ -1,3 +0,0 @@
|
||||||
import TopicList from "discourse/components/topic-list";
|
|
||||||
|
|
||||||
export default class AssignedTopicList extends TopicList {}
|
|
|
@ -1,40 +0,0 @@
|
||||||
<ConditionalLoadingSpinner @condition={{this.loading}}>
|
|
||||||
{{#if this.hasIncoming}}
|
|
||||||
<div class="show-mores">
|
|
||||||
<a href class="alert alert-info clickable" {{action this.showInserted}}>
|
|
||||||
<CountI18n
|
|
||||||
@key="topic_count_"
|
|
||||||
@suffix="latest"
|
|
||||||
@count={{this.incomingCount}}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if this.topics}}
|
|
||||||
<AssignedTopicList
|
|
||||||
@showPosters={{this.showPosters}}
|
|
||||||
@hideCategory={{this.hideCategory}}
|
|
||||||
@topics={{this.topics}}
|
|
||||||
@expandExcerpts={{this.expandExcerpts}}
|
|
||||||
@bulkSelectEnabled={{this.bulkSelectEnabled}}
|
|
||||||
@canBulkSelect={{this.canBulkSelect}}
|
|
||||||
@bulkSelectAction={{this.bulkSelectAction}}
|
|
||||||
@selected={{this.selected}}
|
|
||||||
@skipHeader={{this.skipHeader}}
|
|
||||||
@tagsForUser={{this.tagsForUser}}
|
|
||||||
@changeSort={{this.changeSort}}
|
|
||||||
@toggleBulkSelect={{this.toggleBulkSelect}}
|
|
||||||
@unassign={{this.unassign}}
|
|
||||||
@reassign={{this.reassign}}
|
|
||||||
@onScroll={{this.onScroll}}
|
|
||||||
@scrollOnLoad={{this.scrollOnLoad}}
|
|
||||||
/>
|
|
||||||
{{else}}
|
|
||||||
{{#unless this.loadingMore}}
|
|
||||||
<div class="alert alert-info">
|
|
||||||
{{i18n "choose_topic.none_found"}}
|
|
||||||
</div>
|
|
||||||
{{/unless}}
|
|
||||||
{{/if}}
|
|
||||||
</ConditionalLoadingSpinner>
|
|
|
@ -1,3 +0,0 @@
|
||||||
import BasicTopicList from "discourse/components/basic-topic-list";
|
|
||||||
|
|
||||||
export default class BasicAssignedTopicList extends BasicTopicList {}
|
|
|
@ -1,8 +1,9 @@
|
||||||
import Component from "@glimmer/component";
|
import Component from "@glimmer/component";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
|
import { TrackedObject } from "@ember-compat/tracked-built-ins";
|
||||||
|
|
||||||
export default class AssignUser extends Component {
|
export default class AssignUser extends Component {
|
||||||
model = {};
|
model = new TrackedObject({});
|
||||||
|
|
||||||
// `submit` property will be mutated by the `AssignUserForm` component
|
// `submit` property will be mutated by the `AssignUserForm` component
|
||||||
formApi = {
|
formApi = {
|
||||||
|
@ -14,6 +15,7 @@ export default class AssignUser extends Component {
|
||||||
return this.args.performAndRefresh({
|
return this.args.performAndRefresh({
|
||||||
type: "assign",
|
type: "assign",
|
||||||
username: this.model.username,
|
username: this.model.username,
|
||||||
|
status: this.model.status,
|
||||||
note: this.model.note,
|
note: this.model.note,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<DModal class="assign" @title={{this.title}} @closeModal={{@closeModal}}>
|
<DModal class="assign" @title={{this.title}} @closeModal={{@closeModal}}>
|
||||||
<:body>
|
<:body>
|
||||||
<AssignUserForm
|
<AssignUserForm
|
||||||
@model={{@model}}
|
@model={{this.model}}
|
||||||
@onSubmit={{this.onSubmit}}
|
@onSubmit={{this.onSubmit}}
|
||||||
@formApi={{this.formApi}}
|
@formApi={{this.formApi}}
|
||||||
/>
|
/>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
@action={{this.formApi.submit}}
|
@action={{this.formApi.submit}}
|
||||||
@label={{if
|
@label={{if
|
||||||
@model.reassign
|
this.model.reassign
|
||||||
"discourse_assign.reassign.title"
|
"discourse_assign.reassign.title"
|
||||||
"discourse_assign.assign_modal.assign"
|
"discourse_assign.assign_modal.assign"
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
import Component from "@glimmer/component";
|
import Component from "@glimmer/component";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import { TrackedObject } from "@ember-compat/tracked-built-ins";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
|
|
||||||
export default class AssignUser extends Component {
|
export default class AssignUser extends Component {
|
||||||
@service taskActions;
|
@service taskActions;
|
||||||
|
|
||||||
|
model = new TrackedObject(this.args.model);
|
||||||
|
|
||||||
// `submit` property will be mutated by the `AssignUserForm` component
|
// `submit` property will be mutated by the `AssignUserForm` component
|
||||||
formApi = {
|
formApi = {
|
||||||
submit() {},
|
submit() {},
|
||||||
|
@ -14,7 +17,7 @@ export default class AssignUser extends Component {
|
||||||
get title() {
|
get title() {
|
||||||
let i18nSuffix;
|
let i18nSuffix;
|
||||||
|
|
||||||
switch (this.args.model.targetType) {
|
switch (this.model.targetType) {
|
||||||
case "Post":
|
case "Post":
|
||||||
i18nSuffix = "_post_modal";
|
i18nSuffix = "_post_modal";
|
||||||
break;
|
break;
|
||||||
|
@ -25,7 +28,7 @@ export default class AssignUser extends Component {
|
||||||
|
|
||||||
return I18n.t(
|
return I18n.t(
|
||||||
`discourse_assign.assign${i18nSuffix}.${
|
`discourse_assign.assign${i18nSuffix}.${
|
||||||
this.args.model.reassign ? "reassign_title" : "title"
|
this.model.reassign ? "reassign_title" : "title"
|
||||||
}`
|
}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -33,6 +36,6 @@ export default class AssignUser extends Component {
|
||||||
@action
|
@action
|
||||||
async onSubmit() {
|
async onSubmit() {
|
||||||
this.args.closeModal();
|
this.args.closeModal();
|
||||||
await this.taskActions.assign(this.args.model);
|
await this.taskActions.assign(this.model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import I18n from "I18n";
|
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
import I18n from "I18n";
|
||||||
|
|
||||||
export default class RemindAssignsFrequency extends Component {
|
export default class RemindAssignsFrequency extends Component {
|
||||||
@discourseComputed(
|
@discourseComputed(
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
|
import { set } from "@ember/object";
|
||||||
|
import { sort } from "@ember/object/computed";
|
||||||
import UserMenuNotificationsList from "discourse/components/user-menu/notifications-list";
|
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 I18n from "I18n";
|
||||||
import Topic from "discourse/models/topic";
|
|
||||||
import UserMenuAssignsListEmptyState from "./assigns-list-empty-state";
|
import UserMenuAssignsListEmptyState from "./assigns-list-empty-state";
|
||||||
|
|
||||||
export default class UserMenuAssignNotificationsList extends UserMenuNotificationsList {
|
export default class UserMenuAssignNotificationsList extends UserMenuNotificationsList {
|
||||||
|
@ -56,25 +53,20 @@ export default class UserMenuAssignNotificationsList extends UserMenuNotificatio
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchItems() {
|
async fetchItems() {
|
||||||
const data = await ajax("/assign/user-menu-assigns.json");
|
return new SortedItems(await super.fetchItems()).sortedItems;
|
||||||
const content = [];
|
}
|
||||||
|
}
|
||||||
const notifications = data.notifications.map((n) => Notification.create(n));
|
|
||||||
await Notification.applyTransformations(notifications);
|
class SortedItems {
|
||||||
notifications.forEach((notification) => {
|
itemsSorting = [
|
||||||
content.push(
|
"notification.read",
|
||||||
new UserMenuNotificationItem({
|
"notification.data.message:desc",
|
||||||
notification,
|
"notification.created_at:desc",
|
||||||
currentUser: this.currentUser,
|
];
|
||||||
siteSettings: this.siteSettings,
|
|
||||||
site: this.site,
|
@sort("items", "itemsSorting") sortedItems;
|
||||||
})
|
|
||||||
);
|
constructor(items) {
|
||||||
});
|
set(this, "items", items);
|
||||||
|
|
||||||
const topics = data.topics.map((t) => Topic.create(t));
|
|
||||||
await Topic.applyTransformations(topics);
|
|
||||||
content.push(...topics.map((assign) => new UserMenuAssignItem({ assign })));
|
|
||||||
return content;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
{{i18n "discourse_assign.admin.groups.manage.interaction.assign"}}
|
{{i18n "discourse_assign.admin.groups.manage.interaction.assign"}}
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="visiblity">
|
<label for="visibility">
|
||||||
{{i18n
|
{{i18n
|
||||||
"discourse_assign.admin.groups.manage.interaction.assignable_levels.title"
|
"discourse_assign.admin.groups.manage.interaction.assignable_levels.title"
|
||||||
}}
|
}}
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
@valueProperty="value"
|
@valueProperty="value"
|
||||||
@value={{this.assignableLevel}}
|
@value={{this.assignableLevel}}
|
||||||
@content={{this.assignableLevelOptions}}
|
@content={{this.assignableLevelOptions}}
|
||||||
@class="groups-form-assignable-level"
|
|
||||||
@onChange={{action (mut @outletArgs.model.assignable_level)}}
|
@onChange={{action (mut @outletArgs.model.assignable_level)}}
|
||||||
|
class="groups-form-assignable-level"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
|
@ -0,0 +1 @@
|
||||||
|
{{raw "assign-topic-buttons" topic=context.topic}}
|
|
@ -1,13 +1,14 @@
|
||||||
import UserTopicsList from "discourse/controllers/user-topics-list";
|
|
||||||
import { alias } from "@ember/object/computed";
|
|
||||||
import discourseDebounce from "discourse-common/lib/debounce";
|
|
||||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
|
||||||
import { inject as controller } from "@ember/controller";
|
import { inject as controller } from "@ember/controller";
|
||||||
import { inject as service } from "@ember/service";
|
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
|
import { alias } from "@ember/object/computed";
|
||||||
|
import { inject as service } from "@ember/service";
|
||||||
|
import UserTopicsList from "discourse/controllers/user-topics-list";
|
||||||
|
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||||
|
import discourseDebounce from "discourse-common/lib/debounce";
|
||||||
|
|
||||||
export default class GroupAssignedShow extends UserTopicsList {
|
export default class GroupAssignedShow extends UserTopicsList {
|
||||||
@service taskActions;
|
@service taskActions;
|
||||||
|
@service router;
|
||||||
@controller user;
|
@controller user;
|
||||||
|
|
||||||
queryParams = ["order", "ascending", "search"];
|
queryParams = ["order", "ascending", "search"];
|
||||||
|
@ -45,13 +46,13 @@ export default class GroupAssignedShow extends UserTopicsList {
|
||||||
@action
|
@action
|
||||||
async unassign(targetId, targetType = "Topic") {
|
async unassign(targetId, targetType = "Topic") {
|
||||||
await this.taskActions.unassign(targetId, targetType);
|
await this.taskActions.unassign(targetId, targetType);
|
||||||
this.send("changeAssigned");
|
this.router.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
reassign(topic) {
|
reassign(topic) {
|
||||||
this.taskActions.showAssignModal(topic, {
|
this.taskActions.showAssignModal(topic, {
|
||||||
onSuccess: () => this.send("changeAssigned"),
|
onSuccess: () => this.router.refresh(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { inject as service } from "@ember/service";
|
|
||||||
import Controller, { inject as controller } from "@ember/controller";
|
import Controller, { inject as controller } from "@ember/controller";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
|
import { inject as service } from "@ember/service";
|
||||||
import { ajax } from "discourse/lib/ajax";
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
import discourseDebounce from "discourse-common/lib/debounce";
|
|
||||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||||
|
import discourseDebounce from "discourse-common/lib/debounce";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
export default class GroupAssigned extends Controller {
|
export default class GroupAssigned extends Controller {
|
||||||
@service router;
|
@service router;
|
||||||
|
@ -47,7 +47,11 @@ export default class GroupAssigned extends Controller {
|
||||||
})
|
})
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
if (this.router.currentRoute.params.filter !== "everyone") {
|
if (this.router.currentRoute.params.filter !== "everyone") {
|
||||||
this.transitionToRoute("group.assigned.show", groupName, "everyone");
|
this.router.transitionTo(
|
||||||
|
"group.assigned.show",
|
||||||
|
groupName,
|
||||||
|
"everyone"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
this.set("members", result.members);
|
this.set("members", result.members);
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import UserTopicsList from "discourse/controllers/user-topics-list";
|
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
import discourseDebounce from "discourse-common/lib/debounce";
|
|
||||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
|
||||||
import { inject as controller } from "@ember/controller";
|
import { inject as controller } from "@ember/controller";
|
||||||
import { inject as service } from "@ember/service";
|
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
|
import { inject as service } from "@ember/service";
|
||||||
|
import { htmlSafe } from "@ember/template";
|
||||||
|
import UserTopicsList from "discourse/controllers/user-topics-list";
|
||||||
|
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||||
|
import discourseDebounce from "discourse-common/lib/debounce";
|
||||||
import getURL from "discourse-common/lib/get-url";
|
import getURL from "discourse-common/lib/get-url";
|
||||||
import { iconHTML } from "discourse-common/lib/icon-library";
|
import { iconHTML } from "discourse-common/lib/icon-library";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import { htmlSafe } from "@ember/template";
|
|
||||||
|
|
||||||
export default class UserActivityAssigned extends UserTopicsList {
|
export default class UserActivityAssigned extends UserTopicsList {
|
||||||
@service taskActions;
|
@service taskActions;
|
||||||
|
@ -56,19 +56,6 @@ export default class UserActivityAssigned extends UserTopicsList {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
|
||||||
async unassign(targetId, targetType = "Topic") {
|
|
||||||
await this.taskActions.unassign(targetId, targetType);
|
|
||||||
this.send("changeAssigned");
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
|
||||||
reassign(topic) {
|
|
||||||
this.taskActions.showAssignModal(topic, {
|
|
||||||
onSuccess: () => this.send("changeAssigned"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
changeSort(sortBy) {
|
changeSort(sortBy) {
|
||||||
if (sortBy === this.order) {
|
if (sortBy === this.order) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import I18n from "I18n";
|
|
||||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||||
|
import I18n from "I18n";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "assign-extend-user-messages",
|
name: "assign-extend-user-messages",
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
import { htmlSafe } from "@ember/template";
|
||||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||||
|
import { emojiUnescape } from "discourse/lib/text";
|
||||||
|
import I18n from "I18n";
|
||||||
import UserMenuAssignNotificationsList from "../components/user-menu/assigns-list";
|
import UserMenuAssignNotificationsList from "../components/user-menu/assigns-list";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -6,16 +9,74 @@ export default {
|
||||||
|
|
||||||
initialize(container) {
|
initialize(container) {
|
||||||
withPluginApi("1.2.0", (api) => {
|
withPluginApi("1.2.0", (api) => {
|
||||||
if (api.registerUserMenuTab) {
|
const siteSettings = container.lookup("service:site-settings");
|
||||||
const siteSettings = container.lookup("service:site-settings");
|
if (!siteSettings.assign_enabled) {
|
||||||
if (!siteSettings.assign_enabled) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const currentUser = api.getCurrentUser();
|
const currentUser = api.getCurrentUser();
|
||||||
if (!currentUser?.can_assign) {
|
if (!currentUser?.can_assign) {
|
||||||
return;
|
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() {
|
||||||
|
if (!this.isGroup()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return this.notification.data.display_username;
|
||||||
|
}
|
||||||
|
|
||||||
|
get description() {
|
||||||
|
return htmlSafe(
|
||||||
|
emojiUnescape(
|
||||||
|
I18n.t(
|
||||||
|
`user.assignment_description.${this.postOrTopic()}`,
|
||||||
|
{
|
||||||
|
topic_title: this.notification.fancy_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) {
|
||||||
api.registerUserMenuTab((UserMenuTab) => {
|
api.registerUserMenuTab((UserMenuTab) => {
|
||||||
return class extends UserMenuTab {
|
return class extends UserMenuTab {
|
||||||
id = "assign-list";
|
id = "assign-list";
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
|
import { getOwner } from "@ember/application";
|
||||||
|
import { htmlSafe } from "@ember/template";
|
||||||
|
import { isEmpty } from "@ember/utils";
|
||||||
|
import { h } from "virtual-dom";
|
||||||
|
import SearchAdvancedOptions from "discourse/components/search-advanced-options";
|
||||||
import { renderAvatar } from "discourse/helpers/user-avatar";
|
import { renderAvatar } from "discourse/helpers/user-avatar";
|
||||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
|
||||||
import { iconHTML, iconNode } from "discourse-common/lib/icon-library";
|
|
||||||
import { escapeExpression } from "discourse/lib/utilities";
|
|
||||||
import { h } from "virtual-dom";
|
|
||||||
import { getOwner } from "discourse-common/lib/get-owner";
|
|
||||||
import { htmlSafe } from "@ember/template";
|
|
||||||
import getURL from "discourse-common/lib/get-url";
|
|
||||||
import SearchAdvancedOptions from "discourse/components/search-advanced-options";
|
|
||||||
import I18n from "I18n";
|
|
||||||
import { isEmpty } from "@ember/utils";
|
|
||||||
import { registerTopicFooterDropdown } from "discourse/lib/register-topic-footer-dropdown";
|
import { registerTopicFooterDropdown } from "discourse/lib/register-topic-footer-dropdown";
|
||||||
|
import { escapeExpression } from "discourse/lib/utilities";
|
||||||
import RawHtml from "discourse/widgets/raw-html";
|
import RawHtml from "discourse/widgets/raw-html";
|
||||||
|
import getURL from "discourse-common/lib/get-url";
|
||||||
|
import { iconHTML, iconNode } from "discourse-common/lib/icon-library";
|
||||||
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
import I18n from "I18n";
|
||||||
import BulkAssign from "../components/bulk-actions/assign-user";
|
import BulkAssign from "../components/bulk-actions/assign-user";
|
||||||
|
|
||||||
const PLUGIN_ID = "discourse-assign";
|
const PLUGIN_ID = "discourse-assign";
|
||||||
|
@ -409,7 +409,7 @@ function registerTopicFooterButtons(api) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function initialize(api) {
|
function initialize(api) {
|
||||||
const siteSettings = api.container.lookup("site-settings:main");
|
const siteSettings = api.container.lookup("service:site-settings");
|
||||||
const currentUser = api.getCurrentUser();
|
const currentUser = api.getCurrentUser();
|
||||||
|
|
||||||
if (siteSettings.assigns_public || currentUser?.can_assign) {
|
if (siteSettings.assigns_public || currentUser?.can_assign) {
|
||||||
|
@ -616,7 +616,6 @@ function initialize(api) {
|
||||||
topicAssignee,
|
topicAssignee,
|
||||||
assignedToIndirectly.map((assigned) => ({
|
assignedToIndirectly.map((assigned) => ({
|
||||||
assignee: assigned.assigned_to,
|
assignee: assigned.assigned_to,
|
||||||
status: assigned.assignment_status,
|
|
||||||
note: assigned.assignment_note,
|
note: assigned.assignment_note,
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
|
@ -879,12 +878,12 @@ export default {
|
||||||
name: "extend-for-assign",
|
name: "extend-for-assign",
|
||||||
|
|
||||||
initialize(container) {
|
initialize(container) {
|
||||||
const siteSettings = container.lookup("site-settings:main");
|
const siteSettings = container.lookup("service:site-settings");
|
||||||
if (!siteSettings.assign_enabled) {
|
if (!siteSettings.assign_enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentUser = container.lookup("current-user:main");
|
const currentUser = container.lookup("service:current-user");
|
||||||
if (currentUser?.can_assign) {
|
if (currentUser?.can_assign) {
|
||||||
SearchAdvancedOptions.reopen({
|
SearchAdvancedOptions.reopen({
|
||||||
updateSearchTermForAssignedUsername() {
|
updateSearchTermForAssignedUsername() {
|
||||||
|
@ -928,57 +927,23 @@ export default {
|
||||||
|
|
||||||
api.addUserSearchOption("assignableGroups");
|
api.addUserSearchOption("assignableGroups");
|
||||||
|
|
||||||
if (api.addBulkActionButton) {
|
api.addBulkActionButton({
|
||||||
api.addBulkActionButton({
|
label: "topics.bulk.assign",
|
||||||
label: "topics.bulk.assign",
|
icon: "user-plus",
|
||||||
icon: "user-plus",
|
class: "btn-default assign-topics",
|
||||||
class: "btn-default assign-topics",
|
action({ setComponent }) {
|
||||||
action({ setComponent }) {
|
setComponent(BulkAssign);
|
||||||
setComponent(BulkAssign);
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
|
||||||
api.addBulkActionButton({
|
api.addBulkActionButton({
|
||||||
label: "topics.bulk.unassign",
|
label: "topics.bulk.unassign",
|
||||||
icon: "user-times",
|
icon: "user-times",
|
||||||
class: "btn-default unassign-topics",
|
class: "btn-default unassign-topics",
|
||||||
action({ performAndRefresh }) {
|
action({ performAndRefresh }) {
|
||||||
performAndRefresh({ type: "unassign" });
|
performAndRefresh({ type: "unassign" });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
// TODO: Remove this path after core 3.1.0.beta7 is released
|
|
||||||
const {
|
|
||||||
default: TopicButtonAction,
|
|
||||||
addBulkButton,
|
|
||||||
} = require("discourse/controllers/topic-bulk-actions");
|
|
||||||
|
|
||||||
TopicButtonAction.reopen({
|
|
||||||
actions: {
|
|
||||||
showReAssign() {
|
|
||||||
const controller = getOwner(this).lookup(
|
|
||||||
"controller:bulk-assign"
|
|
||||||
);
|
|
||||||
controller.set("model", { username: "", note: "" });
|
|
||||||
this.send("changeBulkTemplate", "modal/bulk-assign");
|
|
||||||
},
|
|
||||||
|
|
||||||
unassignTopics() {
|
|
||||||
this.performAndRefresh({ type: "unassign" });
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
addBulkButton("showReAssign", "assign", {
|
|
||||||
icon: "user-plus",
|
|
||||||
class: "btn-default assign-topics",
|
|
||||||
});
|
|
||||||
|
|
||||||
addBulkButton("unassignTopics", "unassign", {
|
|
||||||
icon: "user-times",
|
|
||||||
class: "btn-default unassign-topics",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
import UserMenuBaseItem from "discourse/lib/user-menu/base-item";
|
|
||||||
import { postUrl } from "discourse/lib/utilities";
|
|
||||||
import { htmlSafe } from "@ember/template";
|
|
||||||
import { emojiUnescape } from "discourse/lib/text";
|
|
||||||
import I18n from "I18n";
|
|
||||||
|
|
||||||
const ICON = "user-plus";
|
|
||||||
const GROUP_ICON = "group-plus";
|
|
||||||
|
|
||||||
export default class UserMenuAssignItem extends UserMenuBaseItem {
|
|
||||||
constructor({ assign }) {
|
|
||||||
super(...arguments);
|
|
||||||
this.assign = assign;
|
|
||||||
}
|
|
||||||
|
|
||||||
get className() {
|
|
||||||
return "assign";
|
|
||||||
}
|
|
||||||
|
|
||||||
get linkHref() {
|
|
||||||
return postUrl(
|
|
||||||
this.assign.slug,
|
|
||||||
this.assign.id,
|
|
||||||
(this.assign.last_read_post_number || 0) + 1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get linkTitle() {
|
|
||||||
if (this.assign.assigned_to_group) {
|
|
||||||
return I18n.t("user.assigned_to_group", {
|
|
||||||
group_name:
|
|
||||||
this.assign.assigned_to_group.full_name ||
|
|
||||||
this.assign.assigned_to_group.name,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return I18n.t("user.assigned_to_you");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get icon() {
|
|
||||||
if (this.assign.assigned_to_group) {
|
|
||||||
return GROUP_ICON;
|
|
||||||
} else {
|
|
||||||
return ICON;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get label() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
get description() {
|
|
||||||
return htmlSafe(emojiUnescape(this.assign.fancy_title));
|
|
||||||
}
|
|
||||||
|
|
||||||
get topicId() {
|
|
||||||
return this.assign.id;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
import Category from "discourse/models/category";
|
|
||||||
import { computed } from "@ember/object";
|
import { computed } from "@ember/object";
|
||||||
|
import Category from "discourse/models/category";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "extend-category-for-assign",
|
name: "extend-category-for-assign",
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
{{{view.html}}}
|
|
@ -0,0 +1,21 @@
|
||||||
|
import EmberObject from "@ember/object";
|
||||||
|
import { inject as service } from "@ember/service";
|
||||||
|
import rawRenderGlimmer from "discourse/lib/raw-render-glimmer";
|
||||||
|
import AssignedTopicListColumn from "../components/assigned-topic-list-column";
|
||||||
|
|
||||||
|
const ASSIGN_LIST_ROUTES = ["userActivity.assigned", "group.assigned.show"];
|
||||||
|
|
||||||
|
export default class extends EmberObject {
|
||||||
|
@service router;
|
||||||
|
|
||||||
|
get html() {
|
||||||
|
if (ASSIGN_LIST_ROUTES.includes(this.router.currentRouteName)) {
|
||||||
|
return rawRenderGlimmer(
|
||||||
|
this,
|
||||||
|
"td.assign-topic-buttons",
|
||||||
|
<template><AssignedTopicListColumn @topic={{@data.topic}} /></template>,
|
||||||
|
{ topic: this.topic }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +1,7 @@
|
||||||
import DiscourseRoute from "discourse/routes/discourse";
|
|
||||||
import { findOrResetCachedTopicList } from "discourse/lib/cached-topic-list";
|
import { findOrResetCachedTopicList } from "discourse/lib/cached-topic-list";
|
||||||
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
|
|
||||||
export default class GroupAssignedShow extends DiscourseRoute {
|
export default class GroupAssignedShow extends DiscourseRoute {
|
||||||
beforeModel(transition) {
|
|
||||||
if (transition.from?.localName === "show") {
|
|
||||||
this.session.set("topicListScrollPosition", 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
model(params) {
|
model(params) {
|
||||||
let filter;
|
let filter;
|
||||||
if (["everyone", this.modelFor("group").name].includes(params.filter)) {
|
if (["everyone", this.modelFor("group").name].includes(params.filter)) {
|
||||||
|
@ -36,8 +30,4 @@ export default class GroupAssignedShow extends DiscourseRoute {
|
||||||
search: this.currentModel.params.search,
|
search: this.currentModel.params.search,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTemplate() {
|
|
||||||
this.render("group-topics-list");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import { inject as service } from "@ember/service";
|
||||||
import { ajax } from "discourse/lib/ajax";
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import { action } from "@ember/object";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
|
|
||||||
export default class GroupAssigned extends DiscourseRoute {
|
export default class GroupAssigned extends DiscourseRoute {
|
||||||
|
@service router;
|
||||||
|
|
||||||
model() {
|
model() {
|
||||||
return ajax(`/assign/members/${this.modelFor("group").name}`);
|
return ajax(`/assign/members/${this.modelFor("group").name}`);
|
||||||
}
|
}
|
||||||
|
@ -22,15 +24,8 @@ export default class GroupAssigned extends DiscourseRoute {
|
||||||
}
|
}
|
||||||
|
|
||||||
redirect(model, transition) {
|
redirect(model, transition) {
|
||||||
if (transition.to.params.hasOwnProperty("filter")) {
|
if (!transition.to.params.hasOwnProperty("filter")) {
|
||||||
this.transitionTo("group.assigned.show", transition.to.params.filter);
|
this.router.transitionTo("group.assigned.show", "everyone");
|
||||||
} else {
|
|
||||||
this.transitionTo("group.assigned.show", "everyone");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
|
||||||
changeAssigned() {
|
|
||||||
this.refresh();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import I18n from "I18n";
|
import { inject as service } from "@ember/service";
|
||||||
import UserTopicListRoute from "discourse/routes/user-topic-list";
|
|
||||||
import cookie from "discourse/lib/cookie";
|
import cookie from "discourse/lib/cookie";
|
||||||
import { action } from "@ember/object";
|
import UserTopicListRoute from "discourse/routes/user-topic-list";
|
||||||
|
import I18n from "I18n";
|
||||||
|
|
||||||
export default class UserActivityAssigned extends UserTopicListRoute {
|
export default class UserActivityAssigned extends UserTopicListRoute {
|
||||||
|
@service router;
|
||||||
templateName = "user-activity-assigned";
|
templateName = "user-activity-assigned";
|
||||||
controllerName = "user-activity-assigned";
|
controllerName = "user-activity-assigned";
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ export default class UserActivityAssigned extends UserTopicListRoute {
|
||||||
beforeModel() {
|
beforeModel() {
|
||||||
if (!this.currentUser) {
|
if (!this.currentUser) {
|
||||||
cookie("destination_url", window.location.href);
|
cookie("destination_url", window.location.href);
|
||||||
this.transitionTo("login");
|
this.router.transitionTo("login");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,9 +35,4 @@ export default class UserActivityAssigned extends UserTopicListRoute {
|
||||||
titleToken() {
|
titleToken() {
|
||||||
return I18n.t("discourse_assign.assigned");
|
return I18n.t("discourse_assign.assigned");
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
|
||||||
changeAssigned() {
|
|
||||||
this.refresh();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import Service, { inject as service } from "@ember/service";
|
|
||||||
import { ajax } from "discourse/lib/ajax";
|
|
||||||
import AssignUser from "../components/modal/assign-user";
|
|
||||||
import { tracked } from "@glimmer/tracking";
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
import Service, { inject as service } from "@ember/service";
|
||||||
import { isEmpty } from "@ember/utils";
|
import { isEmpty } from "@ember/utils";
|
||||||
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
|
import AssignUser from "../components/modal/assign-user";
|
||||||
|
|
||||||
export default class TaskActions extends Service {
|
export default class TaskActions extends Service {
|
||||||
@service modal;
|
@service modal;
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
<div class="topic-search-div">
|
<div class="topic-search-div">
|
||||||
<div class="inline-form full-width">
|
<div class="inline-form full-width">
|
||||||
<Input
|
<Input
|
||||||
class="no-blur"
|
{{on "input" (action "onChangeFilter" value="target.value")}}
|
||||||
@value={{readonly this.search}}
|
@value={{readonly this.search}}
|
||||||
|
@type="search"
|
||||||
placeholder={{i18n "discourse_assign.topic_search_placeholder"}}
|
placeholder={{i18n "discourse_assign.topic_search_placeholder"}}
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
@type="search"
|
class="no-blur"
|
||||||
{{on "input" (action "onChangeFilter" value="target.value")}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<LoadMore
|
<LoadMore
|
||||||
@class="paginated-topics-list"
|
|
||||||
@selector=".paginated-topics-list .topic-list tr"
|
@selector=".paginated-topics-list .topic-list tr"
|
||||||
@action={{action "loadMore"}}
|
@action={{action "loadMore"}}
|
||||||
|
class="paginated-topics-list"
|
||||||
>
|
>
|
||||||
<BasicAssignedTopicList
|
<BasicTopicList
|
||||||
@topicList={{this.model}}
|
@topicList={{this.model}}
|
||||||
@hideCategory={{this.hideCategory}}
|
@hideCategory={{this.hideCategory}}
|
||||||
@showPosters={{this.showPosters}}
|
@showPosters={{this.showPosters}}
|
|
@ -1,18 +1,18 @@
|
||||||
<section class="user-secondary-navigation group-assignments">
|
<section class="user-secondary-navigation group-assignments">
|
||||||
<MobileNav
|
<MobileNav
|
||||||
@class="activity-nav"
|
|
||||||
@desktopClass="action-list activity-list nav-stacked"
|
@desktopClass="action-list activity-list nav-stacked"
|
||||||
|
class="activity-nav"
|
||||||
>
|
>
|
||||||
{{#if this.isDesktop}}
|
{{#if this.isDesktop}}
|
||||||
<div class="search-div">
|
<div class="search-div">
|
||||||
<Input
|
<Input
|
||||||
|
{{on "input" (action this.onChangeFilterName value="target.value")}}
|
||||||
@type="text"
|
@type="text"
|
||||||
|
@value={{readonly this.filterName}}
|
||||||
placeholder={{i18n
|
placeholder={{i18n
|
||||||
"discourse_assign.sidebar_name_filter_placeholder"
|
"discourse_assign.sidebar_name_filter_placeholder"
|
||||||
}}
|
}}
|
||||||
@value={{readonly this.filterName}}
|
|
||||||
class="search"
|
class="search"
|
||||||
{{on "input" (action this.onChangeFilterName value="target.value")}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -7,22 +7,22 @@
|
||||||
<div class="topic-search-div">
|
<div class="topic-search-div">
|
||||||
<div class="inline-form full-width">
|
<div class="inline-form full-width">
|
||||||
<Input
|
<Input
|
||||||
|
{{on "input" (action "onChangeFilter" value="target.value")}}
|
||||||
@value={{readonly this.search}}
|
@value={{readonly this.search}}
|
||||||
@type="search"
|
@type="search"
|
||||||
{{on "input" (action "onChangeFilter" value="target.value")}}
|
|
||||||
class="no-blur"
|
|
||||||
placeholder={{i18n "discourse_assign.topic_search_placeholder"}}
|
placeholder={{i18n "discourse_assign.topic_search_placeholder"}}
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
|
class="no-blur"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<LoadMore
|
<LoadMore
|
||||||
@class="paginated-topics-list"
|
|
||||||
@selector=".paginated-topics-list .topic-list tr"
|
@selector=".paginated-topics-list .topic-list tr"
|
||||||
@action={{action "loadMore"}}
|
@action={{action "loadMore"}}
|
||||||
|
class="paginated-topics-list"
|
||||||
>
|
>
|
||||||
<BasicAssignedTopicList
|
<BasicTopicList
|
||||||
@topicList={{this.model}}
|
@topicList={{this.model}}
|
||||||
@hideCategory={{this.hideCategory}}
|
@hideCategory={{this.hideCategory}}
|
||||||
@showPosters={{true}}
|
@showPosters={{true}}
|
||||||
|
|
|
@ -66,12 +66,8 @@
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal.assign {
|
.d-modal.assign {
|
||||||
.modal-inner-container {
|
.d-modal__body {
|
||||||
width: 400px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-body {
|
|
||||||
overflow-y: unset;
|
overflow-y: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
# https://translate.discourse.org/
|
# https://translate.discourse.org/
|
||||||
|
|
||||||
ar:
|
ar:
|
||||||
|
admin_js:
|
||||||
|
admin:
|
||||||
|
site_settings:
|
||||||
|
categories:
|
||||||
|
discourse_assign: "تعيين Discourse"
|
||||||
js:
|
js:
|
||||||
filters:
|
filters:
|
||||||
unassigned:
|
unassigned:
|
||||||
|
@ -35,9 +40,8 @@ ar:
|
||||||
assigned_to: "معيَّنة إلى"
|
assigned_to: "معيَّنة إلى"
|
||||||
assigned_topic_to: "تم تعيين الموضوع إلى المستخدم <a href='%{path}'>%{username}</a>"
|
assigned_topic_to: "تم تعيين الموضوع إلى المستخدم <a href='%{path}'>%{username}</a>"
|
||||||
assign_post_to: "تم تعيين المنشور #%{post_number} إلى المستخدم %{username}"
|
assign_post_to: "تم تعيين المنشور #%{post_number} إلى المستخدم %{username}"
|
||||||
|
assign_post_to_multiple: "#%{post_number} إلى %{username}"
|
||||||
assigned_to_w_ellipsis: "معيَّنة إلى..."
|
assigned_to_w_ellipsis: "معيَّنة إلى..."
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "إلغاء التعيين"
|
title: "إلغاء التعيين"
|
||||||
title_w_ellipsis: "إلغاء تعيين..."
|
title_w_ellipsis: "إلغاء تعيين..."
|
||||||
|
@ -99,13 +103,21 @@ ar:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
سيتم إدراج الموضوعات والرسائل المعيَّنة إليك هنا. ستتلقى أيضًا إشعار تذكير دوريًا بتعييناتك، والذي يمكنك تعديله في <a href='%{preferencesUrl}'>تفضيلات المستخدم</a>. <br><br> لتعيين موضوع أو رسالة إلى نفسك أو إلى شخص آخر، ابحث عن %{icon} في الأسفل.
|
سيتم إدراج الموضوعات والرسائل المعيَّنة إليك هنا. ستتلقى أيضًا إشعار تذكير دوريًا بتعييناتك، والذي يمكنك تعديله في <a href='%{preferencesUrl}'>تفضيلات المستخدم</a>. <br><br> لتعيين موضوع أو رسالة إلى نفسك أو إلى شخص آخر، ابحث عن %{icon} في الأسفل.
|
||||||
dismiss_assigned_tooltip: "وضع علامة مقروءة على كل إشعارات التعيين"
|
dismiss_assigned_tooltip: "وضع علامة مقروءة على كل إشعارات التعيين"
|
||||||
assigned_to_group: "معيَّن إلى %{group_name}"
|
assigned_to_group:
|
||||||
assigned_to_you: "معيَّنة إليك"
|
post: "تم تعيين المنشور إلى %{group_name}"
|
||||||
|
topic: "تم تعيين الموضوع إلى %{group_name}"
|
||||||
|
assigned_to_you:
|
||||||
|
post: "تم تعيين المنشور إليك"
|
||||||
|
topic: "تم تعيين الموضوع إليك"
|
||||||
|
assignment_description:
|
||||||
|
post: "%{topic_title} (#%{post_number})"
|
||||||
|
topic: "%{topic_title}"
|
||||||
admin:
|
admin:
|
||||||
web_hooks:
|
web_hooks:
|
||||||
assign_event:
|
assign_event:
|
||||||
name: "تعيين الحدث"
|
group_name: "أحداث التعيين"
|
||||||
details: "عندما يعيِّن مستخدم موضوعًا أو يلغي تعيينه."
|
assigned: "عندما يقوم المستخدم بتعيين موضوع"
|
||||||
|
unassigned: "عندما يلغي المستخدم تعيين موضوع"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -23,6 +23,8 @@ be:
|
||||||
user:
|
user:
|
||||||
messages:
|
messages:
|
||||||
assigned: "прызначаны"
|
assigned: "прызначаны"
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
notifications:
|
notifications:
|
||||||
titles:
|
titles:
|
||||||
assigned: "прызначаны"
|
assigned: "прызначаны"
|
||||||
|
|
|
@ -22,8 +22,6 @@ ca:
|
||||||
group_everyone: "Tothom"
|
group_everyone: "Tothom"
|
||||||
assigned_to: "Assignat a"
|
assigned_to: "Assignat a"
|
||||||
assigned_to_w_ellipsis: "Assignat a..."
|
assigned_to_w_ellipsis: "Assignat a..."
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Desassigna"
|
title: "Desassigna"
|
||||||
title_w_ellipsis: "Desassigna..."
|
title_w_ellipsis: "Desassigna..."
|
||||||
|
@ -60,6 +58,8 @@ ca:
|
||||||
messages:
|
messages:
|
||||||
assigned_title: "Assignats (%{count})"
|
assigned_title: "Assignats (%{count})"
|
||||||
assigned: "Assignats"
|
assigned: "Assignats"
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
assigned:
|
assigned:
|
||||||
|
|
|
@ -5,13 +5,40 @@
|
||||||
# https://translate.discourse.org/
|
# https://translate.discourse.org/
|
||||||
|
|
||||||
cs:
|
cs:
|
||||||
|
admin_js:
|
||||||
|
admin:
|
||||||
|
site_settings:
|
||||||
|
categories:
|
||||||
|
discourse_assign: "Discourse Assign"
|
||||||
js:
|
js:
|
||||||
|
filters:
|
||||||
|
unassigned:
|
||||||
|
title: "Nepřiděleno"
|
||||||
|
help: "Témata, která nejsou přidělena"
|
||||||
action_codes:
|
action_codes:
|
||||||
assigned: "Zadáno %{who} %{when}"
|
assigned: "Zadáno %{who} %{when}"
|
||||||
assigned_group: "Zadáno %{who} %{when}"
|
assigned_group: "Zadáno %{who} %{when}"
|
||||||
|
assigned_to_post: "Uživateli %{who} přidělen <a href='%{path}'>příspěvek</a> %{when}"
|
||||||
|
assigned_group_to_post: "Skupině %{who} přidělen <a href='%{path}'>příspěvek</a> %{when}"
|
||||||
|
unassigned: "%{who} zrušeno přidělení %{when}"
|
||||||
|
unassigned_group: "%{who} zrušeno přidělení %{when}"
|
||||||
|
unassigned_from_post: "Uživateli %{who} zrušeno přidělení <a href='%{path}'>příspěvku</a> %{when}"
|
||||||
|
unassigned_group_from_post: "Skupině %{who} zrušeno přidělení <a href='%{path}'>příspěvku</a> %{when}"
|
||||||
|
reassigned: "Uživateli %{who} znovu přiděleno %{when}"
|
||||||
|
reassigned_group: "Skupině %{who} znovu přiděleno %{when}"
|
||||||
|
details_change: "Změněny podrobnosti přidělení pro %{who} %{when}"
|
||||||
|
note_change: "Změněna poznámka přidělení pro %{who} %{when}"
|
||||||
|
status_change: "Změněn stav přidělení pro %{who} %{when}"
|
||||||
discourse_assign:
|
discourse_assign:
|
||||||
|
add_unassigned_filter: "Přidat do kategorie filtr \"Nepřiděleno\""
|
||||||
|
cant_act: "Nemůžete reagovat na nahlášení, která byla přiřazena jiným uživatelům"
|
||||||
|
cant_act_unclaimed: "Než začnete reagovat na nahlášení, musíte si toto téma nárokovat."
|
||||||
|
topic_search_placeholder: "Hledat témata podle názvu nebo obsahu příspěvku"
|
||||||
|
sidebar_name_filter_placeholder: "Jméno/Uživatelské jméno"
|
||||||
assigned: "Zadáno"
|
assigned: "Zadáno"
|
||||||
group_everyone: "Všichni"
|
group_everyone: "Všichni"
|
||||||
|
assigned_to: "Přiděleno"
|
||||||
|
assigned_topic_to: "Téma přiděleno <a href='%{path}'>%{username}</a>"
|
||||||
unassign:
|
unassign:
|
||||||
title: "Odebrat zadání"
|
title: "Odebrat zadání"
|
||||||
title_w_ellipsis: "Odebrat zadání..."
|
title_w_ellipsis: "Odebrat zadání..."
|
||||||
|
|
|
@ -27,8 +27,6 @@ da:
|
||||||
group_everyone: "Alle"
|
group_everyone: "Alle"
|
||||||
assigned_to: "Tildelt til"
|
assigned_to: "Tildelt til"
|
||||||
assigned_to_w_ellipsis: "Tildelt til..."
|
assigned_to_w_ellipsis: "Tildelt til..."
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Fjern tildeling"
|
title: "Fjern tildeling"
|
||||||
title_w_ellipsis: "Fjern tildeling..."
|
title_w_ellipsis: "Fjern tildeling..."
|
||||||
|
@ -66,11 +64,8 @@ da:
|
||||||
messages:
|
messages:
|
||||||
assigned_title: "Tildelt (%{count})"
|
assigned_title: "Tildelt (%{count})"
|
||||||
assigned: "Tildelt"
|
assigned: "Tildelt"
|
||||||
admin:
|
assignment_description:
|
||||||
web_hooks:
|
topic: "%{topic_title}"
|
||||||
assign_event:
|
|
||||||
name: "Tildel Begivenhed"
|
|
||||||
details: "Når en bruger tildeler eller fradeler et emne."
|
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
# https://translate.discourse.org/
|
# https://translate.discourse.org/
|
||||||
|
|
||||||
de:
|
de:
|
||||||
|
admin_js:
|
||||||
|
admin:
|
||||||
|
site_settings:
|
||||||
|
categories:
|
||||||
|
discourse_assign: "Discourse – Zuordnen"
|
||||||
js:
|
js:
|
||||||
filters:
|
filters:
|
||||||
unassigned:
|
unassigned:
|
||||||
|
@ -35,9 +40,8 @@ de:
|
||||||
assigned_to: "Zugeordnet zu"
|
assigned_to: "Zugeordnet zu"
|
||||||
assigned_topic_to: "Thema zugeordnet zu <a href='%{path}'>%{username}</a>"
|
assigned_topic_to: "Thema zugeordnet zu <a href='%{path}'>%{username}</a>"
|
||||||
assign_post_to: "#%{post_number} %{username} zugeordnet"
|
assign_post_to: "#%{post_number} %{username} zugeordnet"
|
||||||
|
assign_post_to_multiple: "#%{post_number} zu %{username}"
|
||||||
assigned_to_w_ellipsis: "Zugeordnet zu …"
|
assigned_to_w_ellipsis: "Zugeordnet zu …"
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Zuordnung aufheben"
|
title: "Zuordnung aufheben"
|
||||||
title_w_ellipsis: "Zuordnung aufheben …"
|
title_w_ellipsis: "Zuordnung aufheben …"
|
||||||
|
@ -99,13 +103,21 @@ de:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
Deine zugeordneten Themen und Nachrichten werden hier aufgelistet. Außerdem erhältst du regelmäßig eine Erinnerungsbenachrichtigung betreffend deine Zuordnungen, die du in deinen <a href='%{preferencesUrl}'>Benutzereinstellungen</a> anpassen kannst. <br><br> Um dir selbst oder einer anderen Person ein Thema oder eine Nachricht zuzuordnen, verwende die Zuordnungsschaltfläche %{icon} unten.
|
Deine zugeordneten Themen und Nachrichten werden hier aufgelistet. Außerdem erhältst du regelmäßig eine Erinnerungsbenachrichtigung betreffend deine Zuordnungen, die du in deinen <a href='%{preferencesUrl}'>Benutzereinstellungen</a> anpassen kannst. <br><br> Um dir selbst oder einer anderen Person ein Thema oder eine Nachricht zuzuordnen, verwende die Zuordnungsschaltfläche %{icon} unten.
|
||||||
dismiss_assigned_tooltip: "Alle ungelesenen Zuordnungsbenachrichtigungen als gelesen markieren"
|
dismiss_assigned_tooltip: "Alle ungelesenen Zuordnungsbenachrichtigungen als gelesen markieren"
|
||||||
assigned_to_group: "%{group_name} zugeordnet"
|
assigned_to_group:
|
||||||
assigned_to_you: "dir zugeordnet"
|
post: "Beitrag zugeordnet zu %{group_name}"
|
||||||
|
topic: "Thema zugeordnet zu %{group_name}"
|
||||||
|
assigned_to_you:
|
||||||
|
post: "Beitrag wurde dir zugeordnet"
|
||||||
|
topic: "Thema wurde dir zugeordnet"
|
||||||
|
assignment_description:
|
||||||
|
post: "%{topic_title} (#%{post_number})"
|
||||||
|
topic: "%{topic_title}"
|
||||||
admin:
|
admin:
|
||||||
web_hooks:
|
web_hooks:
|
||||||
assign_event:
|
assign_event:
|
||||||
name: "Ereignis zuordnen"
|
group_name: "Ereignisse zuordnen"
|
||||||
details: "Wenn ein Benutzer ein Thema zuordnet oder die Zuordnung aufhebt."
|
assigned: "Wenn ein Benutzer ein Thema zuordnet"
|
||||||
|
unassigned: "Wenn ein Benutzer die Zuordnung eines Themas aufhebt"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -22,5 +22,8 @@ el:
|
||||||
weekly: "Εβδομαδιαία"
|
weekly: "Εβδομαδιαία"
|
||||||
monthly: "Μηνιαία"
|
monthly: "Μηνιαία"
|
||||||
quarterly: "Τριμηνιαία"
|
quarterly: "Τριμηνιαία"
|
||||||
|
user:
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
notifications:
|
notifications:
|
||||||
assigned: "<span>%{username}</span> %{description}"
|
assigned: "<span>%{username}</span> %{description}"
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
en:
|
en:
|
||||||
|
admin_js:
|
||||||
|
admin:
|
||||||
|
site_settings:
|
||||||
|
categories:
|
||||||
|
discourse_assign: "Discourse Assign"
|
||||||
js:
|
js:
|
||||||
filters:
|
filters:
|
||||||
unassigned:
|
unassigned:
|
||||||
|
@ -32,8 +37,6 @@ en:
|
||||||
# assign_post_to_multiple used in list form, example: "Assigned topic to username0, [#2 to username1], [#10 to username2]"
|
# assign_post_to_multiple used in list form, example: "Assigned topic to username0, [#2 to username1], [#10 to username2]"
|
||||||
assign_post_to_multiple: "#%{post_number} to %{username}"
|
assign_post_to_multiple: "#%{post_number} to %{username}"
|
||||||
assigned_to_w_ellipsis: "Assigned to..."
|
assigned_to_w_ellipsis: "Assigned to..."
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Unassign"
|
title: "Unassign"
|
||||||
title_w_ellipsis: "Unassign..."
|
title_w_ellipsis: "Unassign..."
|
||||||
|
@ -97,13 +100,21 @@ en:
|
||||||
<br><br>
|
<br><br>
|
||||||
To assign a topic or message to yourself or to someone else, look for the %{icon} assign button at the bottom.
|
To assign a topic or message to yourself or to someone else, look for the %{icon} assign button at the bottom.
|
||||||
dismiss_assigned_tooltip: "Mark all unread assign notifications as read"
|
dismiss_assigned_tooltip: "Mark all unread assign notifications as read"
|
||||||
assigned_to_group: "assigned to %{group_name}"
|
assigned_to_group:
|
||||||
assigned_to_you: "assigned to you"
|
post: "post assigned to %{group_name}"
|
||||||
|
topic: "topic assigned to %{group_name}"
|
||||||
|
assigned_to_you:
|
||||||
|
post: "post assigned to you"
|
||||||
|
topic: "topic assigned to you"
|
||||||
|
assignment_description:
|
||||||
|
post: "%{topic_title} (#%{post_number})"
|
||||||
|
topic: "%{topic_title}"
|
||||||
admin:
|
admin:
|
||||||
web_hooks:
|
web_hooks:
|
||||||
assign_event:
|
assign_event:
|
||||||
name: "Assign Event"
|
group_name: "Assign Events"
|
||||||
details: "When a user assigns or unassigns a topic."
|
assigned: "When an user assigns a topic"
|
||||||
|
unassigned: "When an user unassigns a topic"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
# https://translate.discourse.org/
|
# https://translate.discourse.org/
|
||||||
|
|
||||||
es:
|
es:
|
||||||
|
admin_js:
|
||||||
|
admin:
|
||||||
|
site_settings:
|
||||||
|
categories:
|
||||||
|
discourse_assign: "Asignación de Discourse"
|
||||||
js:
|
js:
|
||||||
filters:
|
filters:
|
||||||
unassigned:
|
unassigned:
|
||||||
|
@ -35,9 +40,8 @@ es:
|
||||||
assigned_to: "Asignado a"
|
assigned_to: "Asignado a"
|
||||||
assigned_topic_to: "Tema asignado a <a href='%{path}'>%{username}</a>"
|
assigned_topic_to: "Tema asignado a <a href='%{path}'>%{username}</a>"
|
||||||
assign_post_to: "Asignado #%{post_number} a %{username}"
|
assign_post_to: "Asignado #%{post_number} a %{username}"
|
||||||
|
assign_post_to_multiple: "#%{post_number} a %{username}"
|
||||||
assigned_to_w_ellipsis: "Asignado a..."
|
assigned_to_w_ellipsis: "Asignado a..."
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Anular asignación"
|
title: "Anular asignación"
|
||||||
title_w_ellipsis: "Anular asignación..."
|
title_w_ellipsis: "Anular asignación..."
|
||||||
|
@ -99,13 +103,21 @@ es:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
Tus temas y mensajes asignados aparecerán aquí. También recibirás una notificación periódica de recordatorio de tus asignaciones, que puedes ajustar en tus <a href='%{preferencesUrl}'>preferencias de usuario</a>. <br><br> Para asignar un tema o mensaje a ti mismo o a otra persona, busca el botón %{icon} de asignar en la parte inferior.
|
Tus temas y mensajes asignados aparecerán aquí. También recibirás una notificación periódica de recordatorio de tus asignaciones, que puedes ajustar en tus <a href='%{preferencesUrl}'>preferencias de usuario</a>. <br><br> Para asignar un tema o mensaje a ti mismo o a otra persona, busca el botón %{icon} de asignar en la parte inferior.
|
||||||
dismiss_assigned_tooltip: "Marcar todas las notificaciones de asignación no leídas como leídas"
|
dismiss_assigned_tooltip: "Marcar todas las notificaciones de asignación no leídas como leídas"
|
||||||
assigned_to_group: "asignada a %{group_name}"
|
assigned_to_group:
|
||||||
assigned_to_you: "asignada a ti"
|
post: "publicación asignada a %{group_name}"
|
||||||
|
topic: "tema asignado a %{group_name}"
|
||||||
|
assigned_to_you:
|
||||||
|
post: "publicación asignada a ti"
|
||||||
|
topic: "tema asignado a ti"
|
||||||
|
assignment_description:
|
||||||
|
post: "%{topic_title} (#%{post_number})"
|
||||||
|
topic: "%{topic_title}"
|
||||||
admin:
|
admin:
|
||||||
web_hooks:
|
web_hooks:
|
||||||
assign_event:
|
assign_event:
|
||||||
name: "Asignar evento"
|
group_name: "Asignar eventos"
|
||||||
details: "Cuando un usuario asigna o anula la asignación de un tema."
|
assigned: "Cuando un usuario asigna un tema"
|
||||||
|
unassigned: "Cuando un usuario anula la asignación de un tema"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -42,6 +42,8 @@ et:
|
||||||
user:
|
user:
|
||||||
messages:
|
messages:
|
||||||
assigned: "Määratud"
|
assigned: "Määratud"
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
assigned:
|
assigned:
|
||||||
|
|
|
@ -31,5 +31,8 @@ fa_IR:
|
||||||
weekly: "هفتگی"
|
weekly: "هفتگی"
|
||||||
monthly: "ماهانه"
|
monthly: "ماهانه"
|
||||||
quarterly: "فصلی"
|
quarterly: "فصلی"
|
||||||
|
user:
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
notifications:
|
notifications:
|
||||||
assigned: "<span>%{username}</span> %{description}"
|
assigned: "<span>%{username}</span> %{description}"
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
# https://translate.discourse.org/
|
# https://translate.discourse.org/
|
||||||
|
|
||||||
fi:
|
fi:
|
||||||
|
admin_js:
|
||||||
|
admin:
|
||||||
|
site_settings:
|
||||||
|
categories:
|
||||||
|
discourse_assign: "Discourse-osoitus"
|
||||||
js:
|
js:
|
||||||
filters:
|
filters:
|
||||||
unassigned:
|
unassigned:
|
||||||
|
@ -35,9 +40,8 @@ fi:
|
||||||
assigned_to: "Osoitettu käyttäjälle"
|
assigned_to: "Osoitettu käyttäjälle"
|
||||||
assigned_topic_to: "Osoitti ketjun käyttäjälle <a href='%{path}'>%{username}</a>"
|
assigned_topic_to: "Osoitti ketjun käyttäjälle <a href='%{path}'>%{username}</a>"
|
||||||
assign_post_to: "Osoitti viestin %{post_number} käyttäjälle %{username}"
|
assign_post_to: "Osoitti viestin %{post_number} käyttäjälle %{username}"
|
||||||
|
assign_post_to_multiple: "#%{post_number} käyttäjälle %{username}"
|
||||||
assigned_to_w_ellipsis: "Osoitettu käyttäjälle..."
|
assigned_to_w_ellipsis: "Osoitettu käyttäjälle..."
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Peru osoitus"
|
title: "Peru osoitus"
|
||||||
title_w_ellipsis: "Peru osoitus..."
|
title_w_ellipsis: "Peru osoitus..."
|
||||||
|
@ -99,13 +103,21 @@ fi:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
Sinulle osoitetut ketjut ja viestit luetellaan tässä. Saat myös ajoittain muistutusilmoituksia osoituksistasi, joita voit muuttaa <a href='%{preferencesUrl}'>käyttäjäasetuksissasi</a>. <br><br> Jos haluat osoittaa ketjun tai viestin itsellesi tai jollekulle toiselle, etsi osoituspainike %{icon} alaosasta.
|
Sinulle osoitetut ketjut ja viestit luetellaan tässä. Saat myös ajoittain muistutusilmoituksia osoituksistasi, joita voit muuttaa <a href='%{preferencesUrl}'>käyttäjäasetuksissasi</a>. <br><br> Jos haluat osoittaa ketjun tai viestin itsellesi tai jollekulle toiselle, etsi osoituspainike %{icon} alaosasta.
|
||||||
dismiss_assigned_tooltip: "Merkitse kaikki lukemattomat osoitusilmoitukset luetuiksi"
|
dismiss_assigned_tooltip: "Merkitse kaikki lukemattomat osoitusilmoitukset luetuiksi"
|
||||||
assigned_to_group: "osoitettu ryhmälle %{group_name}"
|
assigned_to_group:
|
||||||
assigned_to_you: "osoitettu sinulle"
|
post: "viesti osoitettu ryhmälle %{group_name}"
|
||||||
|
topic: "ketju osoitettu ryhmälle %{group_name}"
|
||||||
|
assigned_to_you:
|
||||||
|
post: "viesti osoitettu sinulle"
|
||||||
|
topic: "ketju osoitettu sinulle"
|
||||||
|
assignment_description:
|
||||||
|
post: "%{topic_title} (#%{post_number})"
|
||||||
|
topic: "%{topic_title}"
|
||||||
admin:
|
admin:
|
||||||
web_hooks:
|
web_hooks:
|
||||||
assign_event:
|
assign_event:
|
||||||
name: "Osoitustapahtuma"
|
group_name: "Osoitustapahtumat"
|
||||||
details: "Kun käyttäjä osoittaa ketjun tai peruu ketjun osoituksen."
|
assigned: "Kun käyttäjä osoittaa ketjun"
|
||||||
|
unassigned: "Kun käyttäjä peruu ketjun osoituksen"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
# https://translate.discourse.org/
|
# https://translate.discourse.org/
|
||||||
|
|
||||||
fr:
|
fr:
|
||||||
|
admin_js:
|
||||||
|
admin:
|
||||||
|
site_settings:
|
||||||
|
categories:
|
||||||
|
discourse_assign: "Affectation de Discourse"
|
||||||
js:
|
js:
|
||||||
filters:
|
filters:
|
||||||
unassigned:
|
unassigned:
|
||||||
|
@ -35,9 +40,8 @@ fr:
|
||||||
assigned_to: "Attribué à"
|
assigned_to: "Attribué à"
|
||||||
assigned_topic_to: "A attribué le message à <a href='%{path}'>%{username}</a>"
|
assigned_topic_to: "A attribué le message à <a href='%{path}'>%{username}</a>"
|
||||||
assign_post_to: "A attribué %{post_number} à %{username}"
|
assign_post_to: "A attribué %{post_number} à %{username}"
|
||||||
|
assign_post_to_multiple: "#%{post_number} à %{username}"
|
||||||
assigned_to_w_ellipsis: "Attribué à…"
|
assigned_to_w_ellipsis: "Attribué à…"
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Annuler l'attribution"
|
title: "Annuler l'attribution"
|
||||||
title_w_ellipsis: "Annuler l'attribution…"
|
title_w_ellipsis: "Annuler l'attribution…"
|
||||||
|
@ -99,13 +103,21 @@ fr:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
Vos sujets et messages attribués seront répertoriés ici. Vous recevrez également une notification de rappel périodique de vos attributions que vous pouvez ajuster dans vos <a href='%{preferencesUrl}'>préférences d'utilisateur</a>. <br><br> Pour attribuer un sujet ou un message à vous-même ou à quelqu'un d'autre, recherchez le bouton d'attribution %{icon} en bas de l'écran.
|
Vos sujets et messages attribués seront répertoriés ici. Vous recevrez également une notification de rappel périodique de vos attributions que vous pouvez ajuster dans vos <a href='%{preferencesUrl}'>préférences d'utilisateur</a>. <br><br> Pour attribuer un sujet ou un message à vous-même ou à quelqu'un d'autre, recherchez le bouton d'attribution %{icon} en bas de l'écran.
|
||||||
dismiss_assigned_tooltip: "Marquer toutes les notifications d'attribution non lues comme lues"
|
dismiss_assigned_tooltip: "Marquer toutes les notifications d'attribution non lues comme lues"
|
||||||
assigned_to_group: "attribué à %{group_name}"
|
assigned_to_group:
|
||||||
assigned_to_you: "attribué à vous"
|
post: "message attribué à %{group_name}"
|
||||||
|
topic: "sujet attribué à %{group_name}"
|
||||||
|
assigned_to_you:
|
||||||
|
post: "message attribué à vous"
|
||||||
|
topic: "sujet attribué à vous"
|
||||||
|
assignment_description:
|
||||||
|
post: "%{topic_title} (#%{post_number})"
|
||||||
|
topic: "%{topic_title}"
|
||||||
admin:
|
admin:
|
||||||
web_hooks:
|
web_hooks:
|
||||||
assign_event:
|
assign_event:
|
||||||
name: "Événement d'attribution"
|
group_name: "Événements d'attribution"
|
||||||
details: "Lorsqu'un utilisateur attribue ou annule l'attribution d'un sujet."
|
assigned: "Lorsqu'un utilisateur attribue un sujet"
|
||||||
|
unassigned: "Lorsqu'un utilisateur annule l'attribution d'un sujet"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -26,6 +26,8 @@ gl:
|
||||||
user:
|
user:
|
||||||
messages:
|
messages:
|
||||||
assigned: "Asignado"
|
assigned: "Asignado"
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
notifications:
|
notifications:
|
||||||
assigned: "<span>%{username}</span> %{description}"
|
assigned: "<span>%{username}</span> %{description}"
|
||||||
titles:
|
titles:
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
# https://translate.discourse.org/
|
# https://translate.discourse.org/
|
||||||
|
|
||||||
he:
|
he:
|
||||||
|
admin_js:
|
||||||
|
admin:
|
||||||
|
site_settings:
|
||||||
|
categories:
|
||||||
|
discourse_assign: "Discourse הקצאה"
|
||||||
js:
|
js:
|
||||||
filters:
|
filters:
|
||||||
unassigned:
|
unassigned:
|
||||||
|
@ -37,8 +42,6 @@ he:
|
||||||
assign_post_to: "מס׳ %{post_number} הוקצה לטובת %{username}"
|
assign_post_to: "מס׳ %{post_number} הוקצה לטובת %{username}"
|
||||||
assign_post_to_multiple: "מס׳ %{post_number} אל %{username}"
|
assign_post_to_multiple: "מס׳ %{post_number} אל %{username}"
|
||||||
assigned_to_w_ellipsis: "מוקצה לטובת..."
|
assigned_to_w_ellipsis: "מוקצה לטובת..."
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "ביטול הקצאה"
|
title: "ביטול הקצאה"
|
||||||
title_w_ellipsis: "ביטול הקצאה..."
|
title_w_ellipsis: "ביטול הקצאה..."
|
||||||
|
@ -100,13 +103,21 @@ he:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
הנושאים שמוקצים אליך יופיעו כאן. תישלחנה אליך הודעות תזכורת מדי פעם בפעם כדי להזכיר לך את המטלות שלך, ניתן להגדיר אותן <a href='%{preferencesUrl}'>בהעדפות המשתמש</a> שלך. <br><br> כדי להקצות נושא או הודעה לעצמך או למישהו אחר יש לחפש את הכפתור %{icon} הקצאה למטה.
|
הנושאים שמוקצים אליך יופיעו כאן. תישלחנה אליך הודעות תזכורת מדי פעם בפעם כדי להזכיר לך את המטלות שלך, ניתן להגדיר אותן <a href='%{preferencesUrl}'>בהעדפות המשתמש</a> שלך. <br><br> כדי להקצות נושא או הודעה לעצמך או למישהו אחר יש לחפש את הכפתור %{icon} הקצאה למטה.
|
||||||
dismiss_assigned_tooltip: "סימון כל התראות ההקצאה שלא נקראו כהתראות שנקראו"
|
dismiss_assigned_tooltip: "סימון כל התראות ההקצאה שלא נקראו כהתראות שנקראו"
|
||||||
assigned_to_group: "מוקצה לטובת %{group_name}"
|
assigned_to_group:
|
||||||
assigned_to_you: "מוקצה לך"
|
post: "הפוסט הוקצה לטובת %{group_name}"
|
||||||
|
topic: "הנושא הוקצה לטובת %{group_name}"
|
||||||
|
assigned_to_you:
|
||||||
|
post: "הפוסט הוקצה לך"
|
||||||
|
topic: "הנושא הוקצה לך"
|
||||||
|
assignment_description:
|
||||||
|
post: "%{topic_title} (מס׳ %{post_number})"
|
||||||
|
topic: "%{topic_title}"
|
||||||
admin:
|
admin:
|
||||||
web_hooks:
|
web_hooks:
|
||||||
assign_event:
|
assign_event:
|
||||||
name: "הקצאת אירוע"
|
group_name: "הקצאת אירועים"
|
||||||
details: "כאשר משתמש מקצה או מבטל הקצאה של נושא."
|
assigned: "בעת הקצאת נושא על ידי משתמש"
|
||||||
|
unassigned: "בעת ביטול הקצאת נושא על ידי משתמש"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -31,8 +31,6 @@ hu:
|
||||||
group_everyone: "Mindenki"
|
group_everyone: "Mindenki"
|
||||||
assigned_to: "Kiosztva:"
|
assigned_to: "Kiosztva:"
|
||||||
assigned_to_w_ellipsis: "Kiosztva…"
|
assigned_to_w_ellipsis: "Kiosztva…"
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Elvétel"
|
title: "Elvétel"
|
||||||
title_w_ellipsis: "Elvétel…"
|
title_w_ellipsis: "Elvétel…"
|
||||||
|
@ -87,11 +85,8 @@ hu:
|
||||||
no_assignments_title: "Még nincsenek kiosztott feladatai"
|
no_assignments_title: "Még nincsenek kiosztott feladatai"
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
A kiosztott témák és üzenetek itt jelennek meg. Rendszeresen kap egy emlékeztető értesítést is a kiosztott feladatokról, amelyeket a <a href='%{preferencesUrl}'>felhasználói beállításokban</a> módosíthat. <br><br>Téma vagy üzenet saját magának vagy valaki másnak történő kiosztásához keresse a lenti %{icon} kiosztás gombot.
|
A kiosztott témák és üzenetek itt jelennek meg. Rendszeresen kap egy emlékeztető értesítést is a kiosztott feladatokról, amelyeket a <a href='%{preferencesUrl}'>felhasználói beállításokban</a> módosíthat. <br><br>Téma vagy üzenet saját magának vagy valaki másnak történő kiosztásához keresse a lenti %{icon} kiosztás gombot.
|
||||||
admin:
|
assignment_description:
|
||||||
web_hooks:
|
topic: "%{topic_title}"
|
||||||
assign_event:
|
|
||||||
name: "Esemény kiosztása"
|
|
||||||
details: "Amikor egy felhasználó kioszt vagy elvesz egy témát."
|
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
assigned:
|
assigned:
|
||||||
|
|
|
@ -52,6 +52,8 @@ hy:
|
||||||
messages:
|
messages:
|
||||||
assigned_title: "Վերագրված (%{count})"
|
assigned_title: "Վերագրված (%{count})"
|
||||||
assigned: "Վերագրված"
|
assigned: "Վերագրված"
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
assigned:
|
assigned:
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
# https://translate.discourse.org/
|
# https://translate.discourse.org/
|
||||||
|
|
||||||
it:
|
it:
|
||||||
|
admin_js:
|
||||||
|
admin:
|
||||||
|
site_settings:
|
||||||
|
categories:
|
||||||
|
discourse_assign: "Assegnazione Discourse"
|
||||||
js:
|
js:
|
||||||
filters:
|
filters:
|
||||||
unassigned:
|
unassigned:
|
||||||
|
@ -35,9 +40,8 @@ it:
|
||||||
assigned_to: "Assegnato a"
|
assigned_to: "Assegnato a"
|
||||||
assigned_topic_to: "Argomento assegnato a <a href='%{path}'>%{username}</a>"
|
assigned_topic_to: "Argomento assegnato a <a href='%{path}'>%{username}</a>"
|
||||||
assign_post_to: "#%{post_number} assegnato a %{username}"
|
assign_post_to: "#%{post_number} assegnato a %{username}"
|
||||||
|
assign_post_to_multiple: "n°%{post_number} a %{username}"
|
||||||
assigned_to_w_ellipsis: "Assegnato a..."
|
assigned_to_w_ellipsis: "Assegnato a..."
|
||||||
assign_notification: "<p> <span>%{username}</span> %{description} </p>"
|
|
||||||
assign_group_notification: "<p> <span>%{username}</span> %{description} </p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Annulla assegnazione"
|
title: "Annulla assegnazione"
|
||||||
title_w_ellipsis: "Annullamento assegnazione..."
|
title_w_ellipsis: "Annullamento assegnazione..."
|
||||||
|
@ -99,13 +103,21 @@ it:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
Gli argomenti e i messaggi a te assegnati verranno elencati qui. Riceverai anche una notifica di promemoria periodica delle tue assegnazioni, che puoi modificare nelle tue <a href='%{preferencesUrl}'>preferenze utente</a>. <br><br> Per assegnare un argomento o un messaggio a te stesso o a qualcun altro, cerca il pulsante Assegna %{icon} in fondo.
|
Gli argomenti e i messaggi a te assegnati verranno elencati qui. Riceverai anche una notifica di promemoria periodica delle tue assegnazioni, che puoi modificare nelle tue <a href='%{preferencesUrl}'>preferenze utente</a>. <br><br> Per assegnare un argomento o un messaggio a te stesso o a qualcun altro, cerca il pulsante Assegna %{icon} in fondo.
|
||||||
dismiss_assigned_tooltip: "Imposta tutte le notifiche di assegnazione non lette come lette"
|
dismiss_assigned_tooltip: "Imposta tutte le notifiche di assegnazione non lette come lette"
|
||||||
assigned_to_group: "assegnato a %{group_name}"
|
assigned_to_group:
|
||||||
assigned_to_you: "assegnato a te"
|
post: "messaggio assegnato a %{group_name}"
|
||||||
|
topic: "argomento assegnato a %{group_name}"
|
||||||
|
assigned_to_you:
|
||||||
|
post: "messaggio assegnato a te"
|
||||||
|
topic: "argomento assegnato a te"
|
||||||
|
assignment_description:
|
||||||
|
post: "%{topic_title} (n°%{post_number})"
|
||||||
|
topic: "%{topic_title}"
|
||||||
admin:
|
admin:
|
||||||
web_hooks:
|
web_hooks:
|
||||||
assign_event:
|
assign_event:
|
||||||
name: "Evento di assegnazione"
|
group_name: "Assegna eventi"
|
||||||
details: "Quando un utente assegna o annulla l'assegnazione di un argomento."
|
assigned: "Quando un utente assegna un argomento"
|
||||||
|
unassigned: "Quando un utente rimuove l'assegnazione di un argomento"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
# https://translate.discourse.org/
|
# https://translate.discourse.org/
|
||||||
|
|
||||||
ja:
|
ja:
|
||||||
|
admin_js:
|
||||||
|
admin:
|
||||||
|
site_settings:
|
||||||
|
categories:
|
||||||
|
discourse_assign: "Discourse 割り当て"
|
||||||
js:
|
js:
|
||||||
filters:
|
filters:
|
||||||
unassigned:
|
unassigned:
|
||||||
|
@ -35,9 +40,8 @@ ja:
|
||||||
assigned_to: "割り当て先"
|
assigned_to: "割り当て先"
|
||||||
assigned_topic_to: "トピックを <a href='%{path}'>%{username}</a> に割り当てました"
|
assigned_topic_to: "トピックを <a href='%{path}'>%{username}</a> に割り当てました"
|
||||||
assign_post_to: "#%{post_number} を %{username} に割り当てました"
|
assign_post_to: "#%{post_number} を %{username} に割り当てました"
|
||||||
|
assign_post_to_multiple: "#%{post_number} を %{username}"
|
||||||
assigned_to_w_ellipsis: "割り当て先..."
|
assigned_to_w_ellipsis: "割り当て先..."
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "割り当て解除"
|
title: "割り当て解除"
|
||||||
title_w_ellipsis: "割り当て解除..."
|
title_w_ellipsis: "割り当て解除..."
|
||||||
|
@ -99,13 +103,21 @@ ja:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
割り当てられたトピックとメッセージがここに一覧表示されます。また、割り当てのリマインダーが定期的に通知されます。この通知頻度は<a href='%{preferencesUrl}'>ユーザー設定</a>で変更できます。 <br><br>トピックまたはメッセージを自分または別のユーザーに割り当てるには、下にある %{icon} 割り当てボタンを探してください。
|
割り当てられたトピックとメッセージがここに一覧表示されます。また、割り当てのリマインダーが定期的に通知されます。この通知頻度は<a href='%{preferencesUrl}'>ユーザー設定</a>で変更できます。 <br><br>トピックまたはメッセージを自分または別のユーザーに割り当てるには、下にある %{icon} 割り当てボタンを探してください。
|
||||||
dismiss_assigned_tooltip: "すべての未読の割り当てを既読にします"
|
dismiss_assigned_tooltip: "すべての未読の割り当てを既読にします"
|
||||||
assigned_to_group: "が %{group_name} に割り当てました"
|
assigned_to_group:
|
||||||
assigned_to_you: "があなたに割り当てました"
|
post: "%{group_name} に割り当てられた投稿"
|
||||||
|
topic: "%{group_name} に割り当てられたトピック"
|
||||||
|
assigned_to_you:
|
||||||
|
post: "あなたに割り当てられた投稿"
|
||||||
|
topic: "あなたに割り当てらたトピック"
|
||||||
|
assignment_description:
|
||||||
|
post: "%{topic_title} (#%{post_number})"
|
||||||
|
topic: "%{topic_title}"
|
||||||
admin:
|
admin:
|
||||||
web_hooks:
|
web_hooks:
|
||||||
assign_event:
|
assign_event:
|
||||||
name: "割り当てイベント"
|
group_name: "割り当てイベント"
|
||||||
details: "ユーザーがトピックを割り当てたか割り当てを解除したとき。"
|
assigned: "ユーザーがトピックを割り当てたとき"
|
||||||
|
unassigned: "ユーザーがトピックの割り当てを解除したとき"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -59,11 +59,8 @@ ko:
|
||||||
messages:
|
messages:
|
||||||
assigned_title: "할당됨 (%{count})"
|
assigned_title: "할당됨 (%{count})"
|
||||||
assigned: "할당됨"
|
assigned: "할당됨"
|
||||||
admin:
|
assignment_description:
|
||||||
web_hooks:
|
topic: "%{topic_title}"
|
||||||
assign_event:
|
|
||||||
name: "이벤트 할당"
|
|
||||||
details: "사용자가 주제를 할당 또는 할당 해제 할 때"
|
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
assigned:
|
assigned:
|
||||||
|
|
|
@ -31,6 +31,8 @@ lt:
|
||||||
user:
|
user:
|
||||||
messages:
|
messages:
|
||||||
assigned: "Priskirta"
|
assigned: "Priskirta"
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
notifications:
|
notifications:
|
||||||
assigned: "<span>%{username}</span> %{description}"
|
assigned: "<span>%{username}</span> %{description}"
|
||||||
titles:
|
titles:
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
# https://translate.discourse.org/
|
# https://translate.discourse.org/
|
||||||
|
|
||||||
nl:
|
nl:
|
||||||
|
admin_js:
|
||||||
|
admin:
|
||||||
|
site_settings:
|
||||||
|
categories:
|
||||||
|
discourse_assign: "Discourse-toewijzing"
|
||||||
js:
|
js:
|
||||||
filters:
|
filters:
|
||||||
unassigned:
|
unassigned:
|
||||||
|
@ -35,9 +40,8 @@ nl:
|
||||||
assigned_to: "Toegewezen aan"
|
assigned_to: "Toegewezen aan"
|
||||||
assigned_topic_to: "Topic toegewezen aan <a href='%{path}'>%{username}</a>"
|
assigned_topic_to: "Topic toegewezen aan <a href='%{path}'>%{username}</a>"
|
||||||
assign_post_to: "#%{post_number} toegewezen aan %{username}"
|
assign_post_to: "#%{post_number} toegewezen aan %{username}"
|
||||||
|
assign_post_to_multiple: "#%{post_number} aan %{username}"
|
||||||
assigned_to_w_ellipsis: "Toegewezen aan..."
|
assigned_to_w_ellipsis: "Toegewezen aan..."
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Toewijzing opheffen"
|
title: "Toewijzing opheffen"
|
||||||
title_w_ellipsis: "Toewijzing opheffen..."
|
title_w_ellipsis: "Toewijzing opheffen..."
|
||||||
|
@ -99,13 +103,21 @@ nl:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
Je toegewezen topics en berichten worden hier weergegeven. Ook ontvang je periodiek een herinneringsmelding over je toewijzingen, die je kunt aanpassen in je <a href='%{preferencesUrl}'>gebruikersvoorkeuren</a>. <br><br> Om een topic of bericht aan jezelf of iemand anders toe te wijzen, zoek je de knop %{icon} Toewijzen onderaan.
|
Je toegewezen topics en berichten worden hier weergegeven. Ook ontvang je periodiek een herinneringsmelding over je toewijzingen, die je kunt aanpassen in je <a href='%{preferencesUrl}'>gebruikersvoorkeuren</a>. <br><br> Om een topic of bericht aan jezelf of iemand anders toe te wijzen, zoek je de knop %{icon} Toewijzen onderaan.
|
||||||
dismiss_assigned_tooltip: "Alle ongelezen toewijzingsmeldingen markeren als gelezen"
|
dismiss_assigned_tooltip: "Alle ongelezen toewijzingsmeldingen markeren als gelezen"
|
||||||
assigned_to_group: "toegewezen aan %{group_name}"
|
assigned_to_group:
|
||||||
assigned_to_you: "aan jou toegewezen"
|
post: "bericht toegewezen aan %{group_name}"
|
||||||
|
topic: "topic toegewezen aan %{group_name}"
|
||||||
|
assigned_to_you:
|
||||||
|
post: "bericht toegewezen aan jou"
|
||||||
|
topic: "topic toegewezen aan jou"
|
||||||
|
assignment_description:
|
||||||
|
post: "%{topic_title} (#%{post_number})"
|
||||||
|
topic: "%{topic_title}"
|
||||||
admin:
|
admin:
|
||||||
web_hooks:
|
web_hooks:
|
||||||
assign_event:
|
assign_event:
|
||||||
name: "Toewijzingsgebeurtenis"
|
group_name: "Toewijzingsgebeurtenissen"
|
||||||
details: "Wanneer een gebruiker een topic toewijst of de toewijzing ervan opheft."
|
assigned: "Wanneer een gebruiker een topic toewijst"
|
||||||
|
unassigned: "Wanneer een gebruiker de toewijzing van een topic opheft"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -36,8 +36,6 @@ pl_PL:
|
||||||
assigned_topic_to: "Przypisano temat do <a href='%{path}'>%{username}</a>"
|
assigned_topic_to: "Przypisano temat do <a href='%{path}'>%{username}</a>"
|
||||||
assign_post_to: "Przypisano #%{post_number} do %{username}"
|
assign_post_to: "Przypisano #%{post_number} do %{username}"
|
||||||
assigned_to_w_ellipsis: "Przypisano do..."
|
assigned_to_w_ellipsis: "Przypisano do..."
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Cofnij przypisanie"
|
title: "Cofnij przypisanie"
|
||||||
title_w_ellipsis: "Cofnij przypisanie..."
|
title_w_ellipsis: "Cofnij przypisanie..."
|
||||||
|
@ -98,13 +96,19 @@ pl_PL:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
Tutaj zostaną wyświetlone Twoje przypisane tematy i wiadomości. Będziesz również otrzymywać okresowe przypomnienie o swoich przypisach, które możesz dostosować w swoich <a href='%{preferencesUrl}'>preferencjach użytkownika</a>. <br><br> Aby przypisać temat lub wiadomość do siebie lub innej osoby, poszukaj przycisku %{icon} przypisywania na dole.
|
Tutaj zostaną wyświetlone Twoje przypisane tematy i wiadomości. Będziesz również otrzymywać okresowe przypomnienie o swoich przypisach, które możesz dostosować w swoich <a href='%{preferencesUrl}'>preferencjach użytkownika</a>. <br><br> Aby przypisać temat lub wiadomość do siebie lub innej osoby, poszukaj przycisku %{icon} przypisywania na dole.
|
||||||
dismiss_assigned_tooltip: "Oznacz wszystkie nieprzeczytane powiadomienia o przypisaniu jako przeczytane"
|
dismiss_assigned_tooltip: "Oznacz wszystkie nieprzeczytane powiadomienia o przypisaniu jako przeczytane"
|
||||||
assigned_to_group: "przypisany do %{group_name}"
|
assigned_to_group:
|
||||||
assigned_to_you: "przypisany do Ciebie"
|
post: "post przypisany do %{group_name}"
|
||||||
|
topic: "temat przypisany do %{group_name}"
|
||||||
|
assigned_to_you:
|
||||||
|
post: "post przypisany do Ciebie"
|
||||||
|
topic: "temat przypisany do Ciebie"
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
admin:
|
admin:
|
||||||
web_hooks:
|
web_hooks:
|
||||||
assign_event:
|
assign_event:
|
||||||
name: "Przypisz wydarzenie"
|
assigned: "Gdy użytkownik przypisze temat"
|
||||||
details: "Gdy użytkownik przypisuje lub cofa przypisanie tematu."
|
unassigned: "Gdy użytkownik anuluje przypisanie tematu"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
@ -147,5 +151,6 @@ pl_PL:
|
||||||
titles:
|
titles:
|
||||||
assigned: "Przypisany"
|
assigned: "Przypisany"
|
||||||
user_menu:
|
user_menu:
|
||||||
|
view_all_assigned: "wyświetl wszystkie przypisania"
|
||||||
tabs:
|
tabs:
|
||||||
assign_list: "Lista przypisań"
|
assign_list: "Lista przypisań"
|
||||||
|
|
|
@ -36,8 +36,6 @@ pt:
|
||||||
assigned_topic_to: "Tópico atribuído a <a href='%{path}'>%{username}</a>"
|
assigned_topic_to: "Tópico atribuído a <a href='%{path}'>%{username}</a>"
|
||||||
assign_post_to: "Atribuiu #%{post_number} a %{username}"
|
assign_post_to: "Atribuiu #%{post_number} a %{username}"
|
||||||
assigned_to_w_ellipsis: "Atribuído(a) a..."
|
assigned_to_w_ellipsis: "Atribuído(a) a..."
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Cancelar atribuição"
|
title: "Cancelar atribuição"
|
||||||
title_w_ellipsis: "Cancelar atribuição..."
|
title_w_ellipsis: "Cancelar atribuição..."
|
||||||
|
@ -99,13 +97,8 @@ pt:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
Seus tópicos e mensagens atribuídos serão listados aqui. Você receberá uma notificação periódica com um lembrete das suas atribuições, que pode ser ajustada nas suas <a href='%{preferencesUrl}'>preferências do(a) usuário(a)</a>. <br><br> Para atribuir um tópico ou mensagem a si ou a outra pessoa, procure o botão de atribuir %{icon} na parte inferior.
|
Seus tópicos e mensagens atribuídos serão listados aqui. Você receberá uma notificação periódica com um lembrete das suas atribuições, que pode ser ajustada nas suas <a href='%{preferencesUrl}'>preferências do(a) usuário(a)</a>. <br><br> Para atribuir um tópico ou mensagem a si ou a outra pessoa, procure o botão de atribuir %{icon} na parte inferior.
|
||||||
dismiss_assigned_tooltip: "Marcar como lidas todas as notificações não atribuídas não lidas"
|
dismiss_assigned_tooltip: "Marcar como lidas todas as notificações não atribuídas não lidas"
|
||||||
assigned_to_group: "atribuiu a %{group_name}"
|
assignment_description:
|
||||||
assigned_to_you: "atribuiu a você"
|
topic: "%{topic_title}"
|
||||||
admin:
|
|
||||||
web_hooks:
|
|
||||||
assign_event:
|
|
||||||
name: "Atribuir evento"
|
|
||||||
details: "Quando um(a) usuário(a) atribui ou cancela atribuição de um tópico."
|
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
# https://translate.discourse.org/
|
# https://translate.discourse.org/
|
||||||
|
|
||||||
pt_BR:
|
pt_BR:
|
||||||
|
admin_js:
|
||||||
|
admin:
|
||||||
|
site_settings:
|
||||||
|
categories:
|
||||||
|
discourse_assign: "Atribuição do Discourse"
|
||||||
js:
|
js:
|
||||||
filters:
|
filters:
|
||||||
unassigned:
|
unassigned:
|
||||||
|
@ -35,9 +40,8 @@ pt_BR:
|
||||||
assigned_to: "Atribuiu a"
|
assigned_to: "Atribuiu a"
|
||||||
assigned_topic_to: "Tópico atribuído a <a href='%{path}'>%{username}</a>"
|
assigned_topic_to: "Tópico atribuído a <a href='%{path}'>%{username}</a>"
|
||||||
assign_post_to: "Atribuiu #%{post_number} a %{username}"
|
assign_post_to: "Atribuiu #%{post_number} a %{username}"
|
||||||
|
assign_post_to_multiple: "#%{post_number} para %{username}"
|
||||||
assigned_to_w_ellipsis: "Atribuiu a..."
|
assigned_to_w_ellipsis: "Atribuiu a..."
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Remover atribuição"
|
title: "Remover atribuição"
|
||||||
title_w_ellipsis: "Remover atribuição..."
|
title_w_ellipsis: "Remover atribuição..."
|
||||||
|
@ -99,13 +103,21 @@ pt_BR:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
Seus tópicos e mensagens atribuídas serão listados aqui. Você receberá uma notificação periódica de lembrete das suas atribuições, que você pode ajustar em suas <a href='%{preferencesUrl}'>preferências de usuário(a)/a>. <br><br> Para atribuir uma mensagem ou tópico a si ou a outra pessoa, procure o botão de atribuir %{icon} na parte inferior.
|
Seus tópicos e mensagens atribuídas serão listados aqui. Você receberá uma notificação periódica de lembrete das suas atribuições, que você pode ajustar em suas <a href='%{preferencesUrl}'>preferências de usuário(a)/a>. <br><br> Para atribuir uma mensagem ou tópico a si ou a outra pessoa, procure o botão de atribuir %{icon} na parte inferior.
|
||||||
dismiss_assigned_tooltip: "Marcar todas as notificações atribuídas não lidas como lidas"
|
dismiss_assigned_tooltip: "Marcar todas as notificações atribuídas não lidas como lidas"
|
||||||
assigned_to_group: "atribuiu a %{group_name}"
|
assigned_to_group:
|
||||||
assigned_to_you: "atribuiu a você"
|
post: "postagem atribuída a %{group_name}"
|
||||||
|
topic: "tópico atribuído a %{group_name}"
|
||||||
|
assigned_to_you:
|
||||||
|
post: "postagem atribuída a você"
|
||||||
|
topic: "tópico atribuído a você"
|
||||||
|
assignment_description:
|
||||||
|
post: "%{topic_title} (#%{post_number})"
|
||||||
|
topic: "%{topic_title}"
|
||||||
admin:
|
admin:
|
||||||
web_hooks:
|
web_hooks:
|
||||||
assign_event:
|
assign_event:
|
||||||
name: "Evento Atribuir"
|
group_name: "Eventos de atribuição"
|
||||||
details: "Quando usuário(a) atribui ou remove atribuição de um tópico."
|
assigned: "Quando um(a) usuário(a) atribuir um tópico"
|
||||||
|
unassigned: "Quando um(a) usuário(a) cancelar a atribuição de um tópico"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -22,5 +22,8 @@ ro:
|
||||||
weekly: "Săptămânal"
|
weekly: "Săptămânal"
|
||||||
monthly: "Lunar"
|
monthly: "Lunar"
|
||||||
quarterly: "Trimestrial"
|
quarterly: "Trimestrial"
|
||||||
|
user:
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
notifications:
|
notifications:
|
||||||
assigned: "<span>%{username}</span> %{description}"
|
assigned: "<span>%{username}</span> %{description}"
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
# https://translate.discourse.org/
|
# https://translate.discourse.org/
|
||||||
|
|
||||||
ru:
|
ru:
|
||||||
|
admin_js:
|
||||||
|
admin:
|
||||||
|
site_settings:
|
||||||
|
categories:
|
||||||
|
discourse_assign: "Плагин Discourse «Назначение»"
|
||||||
js:
|
js:
|
||||||
filters:
|
filters:
|
||||||
unassigned:
|
unassigned:
|
||||||
|
@ -35,9 +40,8 @@ ru:
|
||||||
assigned_to: "Назначено:"
|
assigned_to: "Назначено:"
|
||||||
assigned_topic_to: "Назначил(а) тему пользователю <a href='%{path}'>%{username}</a>"
|
assigned_topic_to: "Назначил(а) тему пользователю <a href='%{path}'>%{username}</a>"
|
||||||
assign_post_to: "Назначил(а) ответственным %{username} в сообщение #%{post_number}"
|
assign_post_to: "Назначил(а) ответственным %{username} в сообщение #%{post_number}"
|
||||||
|
assign_post_to_multiple: "#%{post_number} для пользователя %{username}"
|
||||||
assigned_to_w_ellipsis: "Назначено..."
|
assigned_to_w_ellipsis: "Назначено..."
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Снять ответственного"
|
title: "Снять ответственного"
|
||||||
title_w_ellipsis: "Отменить назначение..."
|
title_w_ellipsis: "Отменить назначение..."
|
||||||
|
@ -99,13 +103,21 @@ ru:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
Здесь будут перечислены назначенные вами темы и сообщения. Вы также будете получать периодические напоминания о ваших назначениях, которые вы можете изменить в <a href='%{preferencesUrl}'>настройках пользователя</a>. <br><br> Чтобы назначить тему или сообщение себе или кому-то ещё, используйте кнопку %{icon}, расположенную в нижней части темы.
|
Здесь будут перечислены назначенные вами темы и сообщения. Вы также будете получать периодические напоминания о ваших назначениях, которые вы можете изменить в <a href='%{preferencesUrl}'>настройках пользователя</a>. <br><br> Чтобы назначить тему или сообщение себе или кому-то ещё, используйте кнопку %{icon}, расположенную в нижней части темы.
|
||||||
dismiss_assigned_tooltip: "Пометить все непрочитанные уведомления о назначении как прочитанные"
|
dismiss_assigned_tooltip: "Пометить все непрочитанные уведомления о назначении как прочитанные"
|
||||||
assigned_to_group: "назначен(а) группе %{group_name}"
|
assigned_to_group:
|
||||||
assigned_to_you: "назначен(а) вам"
|
post: "публикация назначена группе %{group_name}"
|
||||||
|
topic: "тема назначена группе %{group_name}"
|
||||||
|
assigned_to_you:
|
||||||
|
post: "публикация, назначенная вам"
|
||||||
|
topic: "тема, назначенная вам"
|
||||||
|
assignment_description:
|
||||||
|
post: "%{topic_title} (#%{post_number})"
|
||||||
|
topic: "%{topic_title}"
|
||||||
admin:
|
admin:
|
||||||
web_hooks:
|
web_hooks:
|
||||||
assign_event:
|
assign_event:
|
||||||
name: "Событие назначения"
|
group_name: "Назначение событий"
|
||||||
details: "При назначении или отмене назначения ответственного в тему"
|
assigned: "Когда пользователь назначает тему"
|
||||||
|
unassigned: "Когда пользователь отменяет назначение темы"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -48,6 +48,8 @@ sk:
|
||||||
user:
|
user:
|
||||||
messages:
|
messages:
|
||||||
assigned: "Priradené"
|
assigned: "Priradené"
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
assigned:
|
assigned:
|
||||||
|
|
|
@ -22,5 +22,8 @@ sl:
|
||||||
weekly: "Tedensko"
|
weekly: "Tedensko"
|
||||||
monthly: "Mesečno"
|
monthly: "Mesečno"
|
||||||
quarterly: "V četrtletju"
|
quarterly: "V četrtletju"
|
||||||
|
user:
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
notifications:
|
notifications:
|
||||||
assigned: "<span>%{username}</span> %{description}"
|
assigned: "<span>%{username}</span> %{description}"
|
||||||
|
|
|
@ -19,3 +19,6 @@ sq:
|
||||||
weekly: "Javore"
|
weekly: "Javore"
|
||||||
monthly: "Mujore"
|
monthly: "Mujore"
|
||||||
quarterly: "Tremujorsh"
|
quarterly: "Tremujorsh"
|
||||||
|
user:
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
|
|
|
@ -34,8 +34,6 @@ sv:
|
||||||
group_everyone: "Alla"
|
group_everyone: "Alla"
|
||||||
assigned_to: "Tilldelat till"
|
assigned_to: "Tilldelat till"
|
||||||
assigned_to_w_ellipsis: "Tilldelad till..."
|
assigned_to_w_ellipsis: "Tilldelad till..."
|
||||||
assign_notification: "<p><span>%{username}</span>%{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Otilldela"
|
title: "Otilldela"
|
||||||
title_w_ellipsis: "Ta bort tilldelning..."
|
title_w_ellipsis: "Ta bort tilldelning..."
|
||||||
|
@ -94,13 +92,8 @@ sv:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
Dina tilldelade ämnen och meddelanden visas här i en lista. Du kommer också att få en periodisk påminnelse om dina tilldelningar, som du kan justera i dina <a href='%{preferencesUrl}'>användarinställningar</a>. <br><br> Om du vill tilldela ett ämne eller ett meddelande till dig själv eller till någon annan letar du efter tilldelningsknappen %{icon} längst ned.
|
Dina tilldelade ämnen och meddelanden visas här i en lista. Du kommer också att få en periodisk påminnelse om dina tilldelningar, som du kan justera i dina <a href='%{preferencesUrl}'>användarinställningar</a>. <br><br> Om du vill tilldela ett ämne eller ett meddelande till dig själv eller till någon annan letar du efter tilldelningsknappen %{icon} längst ned.
|
||||||
dismiss_assigned_tooltip: "Markera alla olästa tilldelningsmeddelanden som lästa"
|
dismiss_assigned_tooltip: "Markera alla olästa tilldelningsmeddelanden som lästa"
|
||||||
assigned_to_group: "tilldelad till %{group_name}"
|
assignment_description:
|
||||||
assigned_to_you: "tilldelad till dig"
|
topic: "%{topic_title}"
|
||||||
admin:
|
|
||||||
web_hooks:
|
|
||||||
assign_event:
|
|
||||||
name: "Tilldela händelse"
|
|
||||||
details: "När en användare tilldelar eller återtar tilldelning för ett ämne."
|
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -51,6 +51,8 @@ sw:
|
||||||
messages:
|
messages:
|
||||||
assigned_title: "Amekabidhiwa (%{count})"
|
assigned_title: "Amekabidhiwa (%{count})"
|
||||||
assigned: "Imekabidhiwa"
|
assigned: "Imekabidhiwa"
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
assigned:
|
assigned:
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
# https://translate.discourse.org/
|
# https://translate.discourse.org/
|
||||||
|
|
||||||
tr_TR:
|
tr_TR:
|
||||||
|
admin_js:
|
||||||
|
admin:
|
||||||
|
site_settings:
|
||||||
|
categories:
|
||||||
|
discourse_assign: "Discourse Atama"
|
||||||
js:
|
js:
|
||||||
filters:
|
filters:
|
||||||
unassigned:
|
unassigned:
|
||||||
|
@ -35,9 +40,8 @@ tr_TR:
|
||||||
assigned_to: "Şuraya atandı:"
|
assigned_to: "Şuraya atandı:"
|
||||||
assigned_topic_to: "Konu <a href='%{path}'>%{username}</a> adlı kullanıcıya atandı"
|
assigned_topic_to: "Konu <a href='%{path}'>%{username}</a> adlı kullanıcıya atandı"
|
||||||
assign_post_to: "#%{post_number}, %{username} adlı kullanıcıya atandı"
|
assign_post_to: "#%{post_number}, %{username} adlı kullanıcıya atandı"
|
||||||
|
assign_post_to_multiple: "%{username} adlı kullanıcıya #%{post_number}"
|
||||||
assigned_to_w_ellipsis: "Şuraya atandı..."
|
assigned_to_w_ellipsis: "Şuraya atandı..."
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "Atamayı kaldır"
|
title: "Atamayı kaldır"
|
||||||
title_w_ellipsis: "Atamayı kaldır..."
|
title_w_ellipsis: "Atamayı kaldır..."
|
||||||
|
@ -99,13 +103,21 @@ tr_TR:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
Atanan konularınız ve mesajlarınız burada listelenir. Ayrıca, atamalarınızla ilgili periyodik bir anımsatma bildirimi alırsınız; bunu <a href='%{preferencesUrl}'>kullanıcı tercihlerinizden</a> ayarlayabilirsiniz. <br><br>Kendinize veya bir başkasına bir konu veya mesaj atamak için alttaki %{icon} ata düğmesini kullanın.
|
Atanan konularınız ve mesajlarınız burada listelenir. Ayrıca, atamalarınızla ilgili periyodik bir anımsatma bildirimi alırsınız; bunu <a href='%{preferencesUrl}'>kullanıcı tercihlerinizden</a> ayarlayabilirsiniz. <br><br>Kendinize veya bir başkasına bir konu veya mesaj atamak için alttaki %{icon} ata düğmesini kullanın.
|
||||||
dismiss_assigned_tooltip: "Okunmamış tüm atama bildirimlerini okundu olarak işaretle"
|
dismiss_assigned_tooltip: "Okunmamış tüm atama bildirimlerini okundu olarak işaretle"
|
||||||
assigned_to_group: "%{group_name} adlı gruba atandı"
|
assigned_to_group:
|
||||||
assigned_to_you: "size atandı"
|
post: "gönderi %{group_name} adlı gruba atandı"
|
||||||
|
topic: "konu %{group_name} adlı gruba atandı"
|
||||||
|
assigned_to_you:
|
||||||
|
post: "gönderi size atandı"
|
||||||
|
topic: "konu size atandı"
|
||||||
|
assignment_description:
|
||||||
|
post: "%{topic_title} (#%{post_number})"
|
||||||
|
topic: "%{topic_title}"
|
||||||
admin:
|
admin:
|
||||||
web_hooks:
|
web_hooks:
|
||||||
assign_event:
|
assign_event:
|
||||||
name: "Etkinlik Ata"
|
group_name: "Etkinlik Ata"
|
||||||
details: "Bir kullanıcı bir konuyu atadığında veya atamasını kaldırdığında."
|
assigned: "Bir kullanıcı bir konu atadığında"
|
||||||
|
unassigned: "Bir kullanıcı bir konunun atamasını kaldırdığında"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -59,6 +59,8 @@ uk:
|
||||||
messages:
|
messages:
|
||||||
assigned_title: "Призначено (%{count})"
|
assigned_title: "Призначено (%{count})"
|
||||||
assigned: "Призначено"
|
assigned: "Призначено"
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
assigned:
|
assigned:
|
||||||
|
|
|
@ -31,8 +31,6 @@ ur:
|
||||||
group_everyone: "ہر کوئی"
|
group_everyone: "ہر کوئی"
|
||||||
assigned_to: "جس کو اسائین کیا گیا"
|
assigned_to: "جس کو اسائین کیا گیا"
|
||||||
assigned_to_w_ellipsis: "کو تفویض..."
|
assigned_to_w_ellipsis: "کو تفویض..."
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "غیر اسائین کریں"
|
title: "غیر اسائین کریں"
|
||||||
title_w_ellipsis: "غیر تفویض کریں..."
|
title_w_ellipsis: "غیر تفویض کریں..."
|
||||||
|
@ -87,11 +85,8 @@ ur:
|
||||||
no_assignments_title: "آپ کے پاس ابھی تک کوئی اسائنمنٹ نہیں ہے"
|
no_assignments_title: "آپ کے پاس ابھی تک کوئی اسائنمنٹ نہیں ہے"
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
آپ کے تفویض کردہ عنوانات اور پیغامات یہاں درج ہوں گے۔ آپ کو اپنے اسائنمنٹس کی وقفے وقفہ سے یاد دہانی کا نوٹیفکیشن بھی ملے گا ، جسے آپ اپنی <a href='%{preferencesUrl}'>صارف ترجیحات</a>میں ایڈجسٹ کرسکتے ہیں۔ <br><br> اپنے آپ کو یا کسی اور کو موضوع یا پیغام تفویض کرنے کے لئے ، %{icon} تفویض والے بٹن کو تلاش کریں۔
|
آپ کے تفویض کردہ عنوانات اور پیغامات یہاں درج ہوں گے۔ آپ کو اپنے اسائنمنٹس کی وقفے وقفہ سے یاد دہانی کا نوٹیفکیشن بھی ملے گا ، جسے آپ اپنی <a href='%{preferencesUrl}'>صارف ترجیحات</a>میں ایڈجسٹ کرسکتے ہیں۔ <br><br> اپنے آپ کو یا کسی اور کو موضوع یا پیغام تفویض کرنے کے لئے ، %{icon} تفویض والے بٹن کو تلاش کریں۔
|
||||||
admin:
|
assignment_description:
|
||||||
web_hooks:
|
topic: "%{topic_title}"
|
||||||
assign_event:
|
|
||||||
name: "واقعہ تفویض کریں"
|
|
||||||
details: "جب کوئی صارف کسی موضوع کو تفویض یا غیر متعین کرتا ہے۔"
|
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -29,6 +29,8 @@ vi:
|
||||||
user:
|
user:
|
||||||
messages:
|
messages:
|
||||||
assigned: "Được chỉ định"
|
assigned: "Được chỉ định"
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
notifications:
|
notifications:
|
||||||
assigned: "<span>%{username}</span> %{description}"
|
assigned: "<span>%{username}</span> %{description}"
|
||||||
titles:
|
titles:
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
# https://translate.discourse.org/
|
# https://translate.discourse.org/
|
||||||
|
|
||||||
zh_CN:
|
zh_CN:
|
||||||
|
admin_js:
|
||||||
|
admin:
|
||||||
|
site_settings:
|
||||||
|
categories:
|
||||||
|
discourse_assign: "Discourse Assign"
|
||||||
js:
|
js:
|
||||||
filters:
|
filters:
|
||||||
unassigned:
|
unassigned:
|
||||||
|
@ -35,9 +40,8 @@ zh_CN:
|
||||||
assigned_to: "已分配给"
|
assigned_to: "已分配给"
|
||||||
assigned_topic_to: "将话题分配给 <a href='%{path}'>%{username}</a>"
|
assigned_topic_to: "将话题分配给 <a href='%{path}'>%{username}</a>"
|
||||||
assign_post_to: "将 #%{post_number} 分配给 %{username}"
|
assign_post_to: "将 #%{post_number} 分配给 %{username}"
|
||||||
|
assign_post_to_multiple: "#%{post_number} 被分配给 %{username}"
|
||||||
assigned_to_w_ellipsis: "已分配给…"
|
assigned_to_w_ellipsis: "已分配给…"
|
||||||
assign_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
assign_group_notification: "<p><span>%{username}</span> %{description}</p>"
|
|
||||||
unassign:
|
unassign:
|
||||||
title: "取消分配"
|
title: "取消分配"
|
||||||
title_w_ellipsis: "取消分配…"
|
title_w_ellipsis: "取消分配…"
|
||||||
|
@ -99,13 +103,21 @@ zh_CN:
|
||||||
no_assignments_body: >
|
no_assignments_body: >
|
||||||
分配给您的话题和消息将在此处列出。您还将收到关于您的任务分配的定期提醒通知,您可以在<a href='%{preferencesUrl}'>用户偏好设置</a>中进行调整。 <br><br>要将话题或消息分配给自己或其他人,请查找底部的 %{icon} 分配按钮。
|
分配给您的话题和消息将在此处列出。您还将收到关于您的任务分配的定期提醒通知,您可以在<a href='%{preferencesUrl}'>用户偏好设置</a>中进行调整。 <br><br>要将话题或消息分配给自己或其他人,请查找底部的 %{icon} 分配按钮。
|
||||||
dismiss_assigned_tooltip: "将所有未读分配通知标记为已读"
|
dismiss_assigned_tooltip: "将所有未读分配通知标记为已读"
|
||||||
assigned_to_group: "已被分配至%{group_name}"
|
assigned_to_group:
|
||||||
assigned_to_you: "已被分配给您"
|
post: "帖子被分配给 %{group_name}"
|
||||||
|
topic: "话题被分配给 %{group_name}"
|
||||||
|
assigned_to_you:
|
||||||
|
post: "帖子被分配给您"
|
||||||
|
topic: "话题被分配给您"
|
||||||
|
assignment_description:
|
||||||
|
post: "%{topic_title} (#%{post_number})"
|
||||||
|
topic: "%{topic_title}"
|
||||||
admin:
|
admin:
|
||||||
web_hooks:
|
web_hooks:
|
||||||
assign_event:
|
assign_event:
|
||||||
name: "分配事件"
|
group_name: "分配事件"
|
||||||
details: "当用户分配或取消分配话题时。"
|
assigned: "当用户分配主题时"
|
||||||
|
unassigned: "当用户取消分配主题时"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
in:
|
in:
|
||||||
|
|
|
@ -50,6 +50,8 @@ zh_TW:
|
||||||
user:
|
user:
|
||||||
messages:
|
messages:
|
||||||
assigned: "已指派"
|
assigned: "已指派"
|
||||||
|
assignment_description:
|
||||||
|
topic: "%{topic_title}"
|
||||||
search:
|
search:
|
||||||
advanced:
|
advanced:
|
||||||
assigned:
|
assigned:
|
||||||
|
|
|
@ -43,6 +43,7 @@ pl_PL:
|
||||||
flag_assigned: "Przepraszamy, temat, w którym jest ta flaga, został przypisany do innego użytkownika."
|
flag_assigned: "Przepraszamy, temat, w którym jest ta flaga, został przypisany do innego użytkownika."
|
||||||
flag_unclaimed: "Musisz przejąć ten temat, zanim zaczniesz działać na fladze."
|
flag_unclaimed: "Musisz przejąć ten temat, zanim zaczniesz działać na fladze."
|
||||||
topic_assigned_excerpt: "przypisano ci temat '%{title}'"
|
topic_assigned_excerpt: "przypisano ci temat '%{title}'"
|
||||||
|
topic_group_assigned_excerpt: "przypisano temat '%{title}' do @%{group}"
|
||||||
reminders_frequency:
|
reminders_frequency:
|
||||||
never: "nigdy"
|
never: "nigdy"
|
||||||
daily: "dziennie"
|
daily: "dziennie"
|
||||||
|
|
|
@ -7,7 +7,6 @@ DiscourseAssign::Engine.routes.draw do
|
||||||
get "/suggestions" => "assign#suggestions"
|
get "/suggestions" => "assign#suggestions"
|
||||||
get "/assigned" => "assign#assigned"
|
get "/assigned" => "assign#assigned"
|
||||||
get "/members/:group_name" => "assign#group_members"
|
get "/members/:group_name" => "assign#group_members"
|
||||||
get "/user-menu-assigns" => "assign#user_menu_assigns"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Discourse::Application.routes.draw do
|
Discourse::Application.routes.draw do
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
plugins:
|
discourse_assign:
|
||||||
assign_enabled:
|
assign_enabled:
|
||||||
default: false
|
default: false
|
||||||
client: true
|
client: true
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class EnsureNotificationsConsistency < ActiveRecord::Migration[7.0]
|
||||||
|
def up
|
||||||
|
DB.exec(<<~SQL)
|
||||||
|
DELETE FROM notifications
|
||||||
|
WHERE id IN (
|
||||||
|
SELECT notifications.id FROM notifications
|
||||||
|
LEFT OUTER JOIN assignments ON assignments.id = ((notifications.data::jsonb)->'assignment_id')::int
|
||||||
|
WHERE (notification_type = 34 AND assignments.id IS NULL OR assignments.active = FALSE)
|
||||||
|
)
|
||||||
|
SQL
|
||||||
|
|
||||||
|
DB.exec(<<~SQL)
|
||||||
|
WITH tmp AS (
|
||||||
|
SELECT
|
||||||
|
assignments.assigned_to_id AS user_id,
|
||||||
|
assignments.created_at,
|
||||||
|
assignments.updated_at,
|
||||||
|
assignments.topic_id,
|
||||||
|
(
|
||||||
|
CASE WHEN assignments.target_type = 'Topic' THEN 1
|
||||||
|
ELSE (SELECT posts.post_number FROM posts WHERE posts.id = assignments.target_id)
|
||||||
|
END
|
||||||
|
) AS post_number,
|
||||||
|
json_strip_nulls(json_build_object(
|
||||||
|
'message', 'discourse_assign.assign_notification',
|
||||||
|
'display_username', (SELECT users.username FROM users WHERE users.id = assignments.assigned_by_user_id),
|
||||||
|
'topic_title', topics.title,
|
||||||
|
'assignment_id', assignments.id
|
||||||
|
))::text AS data
|
||||||
|
FROM assignments
|
||||||
|
LEFT OUTER JOIN topics ON topics.deleted_at IS NULL AND topics.id = assignments.topic_id
|
||||||
|
LEFT OUTER JOIN users ON users.id = assignments.assigned_to_id AND assignments.assigned_to_type = 'User'
|
||||||
|
LEFT OUTER JOIN notifications ON ((data::jsonb)->'assignment_id')::int = assignments.id
|
||||||
|
WHERE assignments.active = TRUE
|
||||||
|
AND NOT (topics.id IS NULL OR users.id IS NULL)
|
||||||
|
AND assignments.assigned_to_type = 'User'
|
||||||
|
AND notifications.id IS NULL
|
||||||
|
)
|
||||||
|
INSERT INTO notifications (notification_type, high_priority, read, user_id, created_at, updated_at, topic_id, post_number, data)
|
||||||
|
SELECT 34, TRUE, TRUE, tmp.* FROM tmp
|
||||||
|
SQL
|
||||||
|
|
||||||
|
DB.exec(<<~SQL)
|
||||||
|
WITH tmp AS (
|
||||||
|
SELECT
|
||||||
|
users.id AS user_id,
|
||||||
|
assignments.created_at,
|
||||||
|
assignments.updated_at,
|
||||||
|
assignments.topic_id,
|
||||||
|
(
|
||||||
|
CASE WHEN assignments.target_type = 'Topic' THEN 1
|
||||||
|
ELSE (SELECT posts.post_number FROM posts WHERE posts.id = assignments.target_id)
|
||||||
|
END
|
||||||
|
) AS post_number,
|
||||||
|
json_strip_nulls(json_build_object(
|
||||||
|
'message', 'discourse_assign.assign_group_notification',
|
||||||
|
'display_username', (SELECT groups.name FROM groups WHERE groups.id = assignments.assigned_to_id),
|
||||||
|
'topic_title', topics.title,
|
||||||
|
'assignment_id', assignments.id
|
||||||
|
))::text AS data
|
||||||
|
FROM assignments
|
||||||
|
LEFT OUTER JOIN topics ON topics.deleted_at IS NULL AND topics.id = assignments.topic_id
|
||||||
|
LEFT OUTER JOIN groups ON groups.id = assignments.assigned_to_id AND assignments.assigned_to_type = 'Group'
|
||||||
|
LEFT OUTER JOIN group_users ON groups.id = group_users.group_id
|
||||||
|
LEFT OUTER JOIN users ON users.id = group_users.user_id
|
||||||
|
LEFT OUTER JOIN notifications ON ((data::jsonb)->'assignment_id')::int = assignments.id AND notifications.user_id = users.id
|
||||||
|
WHERE assignments.active = TRUE
|
||||||
|
AND NOT (topics.id IS NULL OR groups.id IS NULL)
|
||||||
|
AND assignments.assigned_to_type = 'Group'
|
||||||
|
AND notifications.id IS NULL
|
||||||
|
)
|
||||||
|
INSERT INTO notifications (notification_type, high_priority, read, user_id, created_at, updated_at, topic_id, post_number, data)
|
||||||
|
SELECT 34, TRUE, TRUE, tmp.* FROM tmp
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
end
|
||||||
|
end
|
|
@ -195,7 +195,7 @@ class ::Assigner
|
||||||
topic.posts.where(post_number: 1).first
|
topic.posts.where(post_number: 1).first
|
||||||
end
|
end
|
||||||
|
|
||||||
def forbidden_reasons(assign_to:, type:, note:, status:)
|
def forbidden_reasons(assign_to:, type:, note:, status:, allow_self_reassign:)
|
||||||
case
|
case
|
||||||
when assign_to.is_a?(User) && !can_assignee_see_target?(assign_to)
|
when assign_to.is_a?(User) && !can_assignee_see_target?(assign_to)
|
||||||
if topic.private_message?
|
if topic.private_message?
|
||||||
|
@ -211,7 +211,7 @@ class ::Assigner
|
||||||
end
|
end
|
||||||
when !can_be_assigned?(assign_to)
|
when !can_be_assigned?(assign_to)
|
||||||
assign_to.is_a?(User) ? :forbidden_assign_to : :forbidden_group_assign_to
|
assign_to.is_a?(User) ? :forbidden_assign_to : :forbidden_group_assign_to
|
||||||
when already_assigned?(assign_to, type, note, status)
|
when !allow_self_reassign && already_assigned?(assign_to, type, note, status)
|
||||||
assign_to.is_a?(User) ? :already_assigned : :group_already_assigned
|
assign_to.is_a?(User) ? :already_assigned : :group_already_assigned
|
||||||
when Assignment.where(topic: topic, active: true).count >= ASSIGNMENTS_PER_TOPIC_LIMIT &&
|
when Assignment.where(topic: topic, active: true).count >= ASSIGNMENTS_PER_TOPIC_LIMIT &&
|
||||||
!reassign?
|
!reassign?
|
||||||
|
@ -223,14 +223,15 @@ class ::Assigner
|
||||||
|
|
||||||
def update_details(assign_to, note, status, skip_small_action_post: false)
|
def update_details(assign_to, note, status, skip_small_action_post: false)
|
||||||
case
|
case
|
||||||
when @target.assignment.note != note && @target.assignment.status != status && status.present?
|
when note.present? && status.present? && @target.assignment.note != note &&
|
||||||
|
@target.assignment.status != status
|
||||||
small_action_text = <<~TEXT
|
small_action_text = <<~TEXT
|
||||||
Status: #{@target.assignment.status} → #{status}
|
Status: #{@target.assignment.status} → #{status}
|
||||||
|
|
||||||
#{note}
|
#{note}
|
||||||
TEXT
|
TEXT
|
||||||
change_type = "details"
|
change_type = "details"
|
||||||
when @target.assignment.note != note
|
when note.present? && @target.assignment.note != note
|
||||||
small_action_text = note
|
small_action_text = note
|
||||||
change_type = "note"
|
change_type = "note"
|
||||||
when @target.assignment.status != status
|
when @target.assignment.status != status
|
||||||
|
@ -239,11 +240,8 @@ class ::Assigner
|
||||||
end
|
end
|
||||||
|
|
||||||
@target.assignment.update!(note: note, status: status)
|
@target.assignment.update!(note: note, status: status)
|
||||||
|
queue_notification(@target.assignment)
|
||||||
queue_notification(assign_to, skip_small_action_post, @target.assignment)
|
publish_assignment(@target.assignment, assign_to, note, status)
|
||||||
|
|
||||||
assignment = @target.assignment
|
|
||||||
publish_assignment(assignment, assign_to, note, status)
|
|
||||||
|
|
||||||
# email is skipped, for now
|
# email is skipped, for now
|
||||||
|
|
||||||
|
@ -255,7 +253,13 @@ class ::Assigner
|
||||||
{ success: true }
|
{ success: true }
|
||||||
end
|
end
|
||||||
|
|
||||||
def assign(assign_to, note: nil, skip_small_action_post: false, status: nil)
|
def assign(
|
||||||
|
assign_to,
|
||||||
|
note: nil,
|
||||||
|
skip_small_action_post: false,
|
||||||
|
status: nil,
|
||||||
|
allow_self_reassign: false
|
||||||
|
)
|
||||||
assigned_to_type = assign_to.is_a?(User) ? "User" : "Group"
|
assigned_to_type = assign_to.is_a?(User) ? "User" : "Group"
|
||||||
|
|
||||||
if topic.private_message? && SiteSetting.invite_on_assign
|
if topic.private_message? && SiteSetting.invite_on_assign
|
||||||
|
@ -263,7 +267,13 @@ class ::Assigner
|
||||||
end
|
end
|
||||||
|
|
||||||
forbidden_reason =
|
forbidden_reason =
|
||||||
forbidden_reasons(assign_to: assign_to, type: assigned_to_type, note: note, status: status)
|
forbidden_reasons(
|
||||||
|
assign_to: assign_to,
|
||||||
|
type: assigned_to_type,
|
||||||
|
note: note,
|
||||||
|
status: status,
|
||||||
|
allow_self_reassign: allow_self_reassign,
|
||||||
|
)
|
||||||
return { success: false, reason: forbidden_reason } if forbidden_reason
|
return { success: false, reason: forbidden_reason } if forbidden_reason
|
||||||
|
|
||||||
if no_assignee_change?(assign_to) && details_change?(note, status)
|
if no_assignee_change?(assign_to) && details_change?(note, status)
|
||||||
|
@ -274,33 +284,31 @@ class ::Assigner
|
||||||
action_code[:user] = topic.assignment.present? ? "reassigned" : "assigned"
|
action_code[:user] = topic.assignment.present? ? "reassigned" : "assigned"
|
||||||
action_code[:group] = topic.assignment.present? ? "reassigned_group" : "assigned_group"
|
action_code[:group] = topic.assignment.present? ? "reassigned_group" : "assigned_group"
|
||||||
|
|
||||||
skip_small_action_post = skip_small_action_post || no_assignee_change?(assign_to)
|
skip_small_action_post =
|
||||||
|
skip_small_action_post || (!allow_self_reassign && no_assignee_change?(assign_to))
|
||||||
|
|
||||||
if topic.assignment.present?
|
if @target.assignment
|
||||||
Jobs.enqueue(
|
Jobs.enqueue(
|
||||||
:unassign_notification,
|
:unassign_notification,
|
||||||
topic_id: topic.id,
|
topic_id: topic.id,
|
||||||
assigned_to_id: topic.assignment.assigned_to_id,
|
assigned_to_id: @target.assignment.assigned_to_id,
|
||||||
assigned_to_type: topic.assignment.assigned_to_type,
|
assigned_to_type: @target.assignment.assigned_to_type,
|
||||||
|
assignment_id: @target.assignment.id,
|
||||||
)
|
)
|
||||||
|
@target.assignment.destroy!
|
||||||
end
|
end
|
||||||
|
|
||||||
@target.assignment&.destroy!
|
|
||||||
|
|
||||||
assignment =
|
assignment =
|
||||||
@target.create_assignment!(
|
@target.create_assignment!(
|
||||||
assigned_to_id: assign_to.id,
|
assigned_to: assign_to,
|
||||||
assigned_to_type: assigned_to_type,
|
assigned_by_user: @assigned_by,
|
||||||
assigned_by_user_id: @assigned_by.id,
|
topic: topic,
|
||||||
topic_id: topic.id,
|
|
||||||
note: note,
|
note: note,
|
||||||
status: status,
|
status: status,
|
||||||
)
|
)
|
||||||
|
|
||||||
first_post.publish_change_to_clients!(:revised, reload_topic: true)
|
first_post.publish_change_to_clients!(:revised, reload_topic: true)
|
||||||
|
queue_notification(assignment)
|
||||||
queue_notification(assign_to, skip_small_action_post, assignment)
|
|
||||||
|
|
||||||
publish_assignment(assignment, assign_to, note, status)
|
publish_assignment(assignment, assign_to, note, status)
|
||||||
|
|
||||||
if assignment.assigned_to_user?
|
if assignment.assigned_to_user?
|
||||||
|
@ -335,7 +343,7 @@ class ::Assigner
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create a webhook event
|
# Create a webhook event
|
||||||
if WebHook.active_web_hooks(:assign).exists?
|
if WebHook.active_web_hooks(:assigned).exists?
|
||||||
assigned_to_type = :assigned
|
assigned_to_type = :assigned
|
||||||
payload = {
|
payload = {
|
||||||
type: assigned_to_type,
|
type: assigned_to_type,
|
||||||
|
@ -370,24 +378,9 @@ class ::Assigner
|
||||||
topic_id: topic.id,
|
topic_id: topic.id,
|
||||||
assigned_to_id: assignment.assigned_to.id,
|
assigned_to_id: assignment.assigned_to.id,
|
||||||
assigned_to_type: assignment.assigned_to_type,
|
assigned_to_type: assignment.assigned_to_type,
|
||||||
|
assignment_id: assignment.id,
|
||||||
)
|
)
|
||||||
|
|
||||||
if assignment.assigned_to_user?
|
|
||||||
if TopicUser.exists?(
|
|
||||||
user_id: assignment.assigned_to_id,
|
|
||||||
topic: topic,
|
|
||||||
notification_level: TopicUser.notification_levels[:watching],
|
|
||||||
notifications_reason_id: TopicUser.notification_reasons[:plugin_changed],
|
|
||||||
)
|
|
||||||
TopicUser.change(
|
|
||||||
assignment.assigned_to_id,
|
|
||||||
topic.id,
|
|
||||||
notification_level: TopicUser.notification_levels[:tracking],
|
|
||||||
notifications_reason_id: TopicUser.notification_reasons[:plugin_changed],
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assigned_to = assignment.assigned_to
|
assigned_to = assignment.assigned_to
|
||||||
|
|
||||||
if SiteSetting.unassign_creates_tracking_post && !silent
|
if SiteSetting.unassign_creates_tracking_post && !silent
|
||||||
|
@ -413,7 +406,7 @@ class ::Assigner
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create a webhook event
|
# Create a webhook event
|
||||||
if WebHook.active_web_hooks(:assign).exists?
|
if WebHook.active_web_hooks(:unassigned).exists?
|
||||||
type = :unassigned
|
type = :unassigned
|
||||||
payload = {
|
payload = {
|
||||||
type: type,
|
type: type,
|
||||||
|
@ -477,17 +470,8 @@ class ::Assigner
|
||||||
@guardian ||= Guardian.new(@assigned_by)
|
@guardian ||= Guardian.new(@assigned_by)
|
||||||
end
|
end
|
||||||
|
|
||||||
def queue_notification(assign_to, skip_small_action_post, assignment)
|
def queue_notification(assignment)
|
||||||
Jobs.enqueue(
|
Jobs.enqueue(:assign_notification, assignment_id: assignment.id)
|
||||||
:assign_notification,
|
|
||||||
topic_id: topic.id,
|
|
||||||
post_id: topic_target? ? first_post.id : @target.id,
|
|
||||||
assigned_to_id: assign_to.id,
|
|
||||||
assigned_to_type: assign_to.is_a?(User) ? "User" : "Group",
|
|
||||||
assigned_by_id: @assigned_by.id,
|
|
||||||
skip_small_action_post: skip_small_action_post,
|
|
||||||
assignment_id: assignment.id,
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_small_action_post(action_code, assign_to, text)
|
def add_small_action_post(action_code, assign_to, text)
|
||||||
|
@ -546,7 +530,7 @@ class ::Assigner
|
||||||
""
|
""
|
||||||
end
|
end
|
||||||
return "unassigned#{suffix}" if assignment.assigned_to_user?
|
return "unassigned#{suffix}" if assignment.assigned_to_user?
|
||||||
return "unassigned_group#{suffix}" if assignment.assigned_to_group?
|
"unassigned_group#{suffix}" if assignment.assigned_to_group?
|
||||||
end
|
end
|
||||||
|
|
||||||
def already_assigned?(assign_to, type, note, status)
|
def already_assigned?(assign_to, type, note, status)
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module DiscourseAssign
|
||||||
|
class CreateNotification
|
||||||
|
class UserAssignment
|
||||||
|
attr_reader :assignment
|
||||||
|
|
||||||
|
def initialize(assignment)
|
||||||
|
@assignment = assignment
|
||||||
|
end
|
||||||
|
|
||||||
|
def excerpt_key
|
||||||
|
"discourse_assign.topic_assigned_excerpt"
|
||||||
|
end
|
||||||
|
|
||||||
|
def notification_message
|
||||||
|
"discourse_assign.assign_notification"
|
||||||
|
end
|
||||||
|
|
||||||
|
def display_username
|
||||||
|
assignment.assigned_by_user.username
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class GroupAssignment < UserAssignment
|
||||||
|
def excerpt_key
|
||||||
|
"discourse_assign.topic_group_assigned_excerpt"
|
||||||
|
end
|
||||||
|
|
||||||
|
def notification_message
|
||||||
|
"discourse_assign.assign_group_notification"
|
||||||
|
end
|
||||||
|
|
||||||
|
def display_username
|
||||||
|
assignment.assigned_to.name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.call(...)
|
||||||
|
new(...).call
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :assignment, :user, :mark_as_read, :assignment_type
|
||||||
|
alias mark_as_read? mark_as_read
|
||||||
|
|
||||||
|
delegate :topic,
|
||||||
|
:post,
|
||||||
|
:assigned_by_user,
|
||||||
|
:assigned_to,
|
||||||
|
:created_at,
|
||||||
|
:updated_at,
|
||||||
|
:assigned_to_user?,
|
||||||
|
:id,
|
||||||
|
to: :assignment,
|
||||||
|
private: true
|
||||||
|
delegate :excerpt_key,
|
||||||
|
:notification_message,
|
||||||
|
:display_username,
|
||||||
|
to: :assignment_type,
|
||||||
|
private: true
|
||||||
|
|
||||||
|
def initialize(assignment:, user:, mark_as_read:)
|
||||||
|
@assignment = assignment
|
||||||
|
@user = user
|
||||||
|
@mark_as_read = mark_as_read
|
||||||
|
@assignment_type =
|
||||||
|
"#{self.class}::#{assignment.assigned_to.class}Assignment".constantize.new(assignment)
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
Assigner.publish_topic_tracking_state(topic, user.id)
|
||||||
|
unless mark_as_read?
|
||||||
|
PostAlerter.new(post).create_notification_alert(
|
||||||
|
user: user,
|
||||||
|
post: post,
|
||||||
|
username: assigned_by_user.username,
|
||||||
|
notification_type: Notification.types[:assigned],
|
||||||
|
excerpt:
|
||||||
|
I18n.t(
|
||||||
|
excerpt_key,
|
||||||
|
title: topic.title,
|
||||||
|
group: assigned_to.name,
|
||||||
|
locale: user.effective_locale,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
end
|
||||||
|
user.notifications.assigned.create!(
|
||||||
|
created_at: created_at,
|
||||||
|
updated_at: updated_at,
|
||||||
|
topic: topic,
|
||||||
|
post_number: post.post_number,
|
||||||
|
high_priority: true,
|
||||||
|
read: mark_as_read?,
|
||||||
|
data: {
|
||||||
|
message: notification_message,
|
||||||
|
display_username: display_username,
|
||||||
|
topic_title: topic.title,
|
||||||
|
assignment_id: id,
|
||||||
|
}.to_json,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,12 +2,15 @@
|
||||||
|
|
||||||
module DiscourseAssign
|
module DiscourseAssign
|
||||||
module GroupExtension
|
module GroupExtension
|
||||||
def self.prepended(base)
|
extend ActiveSupport::Concern
|
||||||
base.class_eval do
|
|
||||||
scope :assignable,
|
prepended do
|
||||||
->(user) {
|
has_many :assignments, as: :assigned_to
|
||||||
where(
|
|
||||||
"assignable_level in (:levels) OR
|
scope :assignable,
|
||||||
|
->(user) do
|
||||||
|
where(
|
||||||
|
"assignable_level in (:levels) OR
|
||||||
(
|
(
|
||||||
assignable_level = #{Group::ALIAS_LEVELS[:members_mods_and_admins]} AND id in (
|
assignable_level = #{Group::ALIAS_LEVELS[:members_mods_and_admins]} AND id in (
|
||||||
SELECT group_id FROM group_users WHERE user_id = :user_id)
|
SELECT group_id FROM group_users WHERE user_id = :user_id)
|
||||||
|
@ -15,11 +18,10 @@ module DiscourseAssign
|
||||||
assignable_level = #{Group::ALIAS_LEVELS[:owners_mods_and_admins]} AND id in (
|
assignable_level = #{Group::ALIAS_LEVELS[:owners_mods_and_admins]} AND id in (
|
||||||
SELECT group_id FROM group_users WHERE user_id = :user_id AND owner IS TRUE)
|
SELECT group_id FROM group_users WHERE user_id = :user_id AND owner IS TRUE)
|
||||||
)",
|
)",
|
||||||
levels: alias_levels(user),
|
levels: alias_levels(user),
|
||||||
user_id: user&.id,
|
user_id: user&.id,
|
||||||
)
|
)
|
||||||
}
|
end
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module DiscourseAssign
|
||||||
|
module NotificationExtension
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
prepended do
|
||||||
|
scope :assigned, -> { where(notification_type: Notification.types[:assigned]) }
|
||||||
|
scope :for_assignment,
|
||||||
|
->(assignment) do
|
||||||
|
assigned.where("((data::jsonb)->'assignment_id')::int IN (?)", assignment)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -5,9 +5,7 @@ module DiscourseAssign
|
||||||
def self.prepended(base)
|
def self.prepended(base)
|
||||||
base.class_eval do
|
base.class_eval do
|
||||||
def self.enqueue_assign_hooks(event, payload)
|
def self.enqueue_assign_hooks(event, payload)
|
||||||
if active_web_hooks("assign").exists?
|
WebHook.enqueue_hooks(:assign, event, payload: payload) if active_web_hooks(event).exists?
|
||||||
WebHook.enqueue_hooks(:assign, event, payload: payload)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,130 +1,190 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class RandomAssignUtils
|
class RandomAssignUtils
|
||||||
def self.raise_error(automation, message)
|
attr_reader :context, :fields, :automation, :topic, :group
|
||||||
raise("[discourse-automation id=#{automation.id}] #{message}.")
|
|
||||||
|
def self.automation_script!(...)
|
||||||
|
new(...).automation_script!
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.log_info(automation, message)
|
def initialize(context, fields, automation)
|
||||||
Rails.logger.info("[discourse-automation id=#{automation.id}] #{message}.")
|
@context = context
|
||||||
end
|
@fields = fields
|
||||||
|
@automation = automation
|
||||||
def self.automation_script!(context, fields, automation)
|
|
||||||
raise_error(automation, "discourse-assign is not enabled") unless SiteSetting.assign_enabled?
|
|
||||||
|
|
||||||
|
raise_error("discourse-assign is not enabled") unless SiteSetting.assign_enabled?
|
||||||
unless topic_id = fields.dig("assigned_topic", "value")
|
unless topic_id = fields.dig("assigned_topic", "value")
|
||||||
raise_error(automation, "`assigned_topic` not provided")
|
raise_error("`assigned_topic` not provided")
|
||||||
end
|
end
|
||||||
|
unless @topic = Topic.find_by(id: topic_id)
|
||||||
unless topic = Topic.find_by(id: topic_id)
|
raise_error("Topic(#{topic_id}) not found")
|
||||||
raise_error(automation, "Topic(#{topic_id}) not found")
|
|
||||||
end
|
|
||||||
|
|
||||||
min_hours = fields.dig("minimum_time_between_assignments", "value").presence
|
|
||||||
if min_hours &&
|
|
||||||
TopicCustomField
|
|
||||||
.where(name: "assigned_to_id", topic_id: topic_id)
|
|
||||||
.where("created_at < ?", min_hours.to_i.hours.ago)
|
|
||||||
.exists?
|
|
||||||
log_info(automation, "Topic(#{topic_id}) has already been assigned recently")
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
|
||||||
unless group_id = fields.dig("assignees_group", "value")
|
unless group_id = fields.dig("assignees_group", "value")
|
||||||
raise_error(automation, "`assignees_group` not provided")
|
raise_error("`assignees_group` not provided")
|
||||||
end
|
end
|
||||||
|
unless @group = Group.find_by(id: group_id)
|
||||||
unless group = Group.find_by(id: group_id)
|
raise_error("Group(#{group_id}) not found")
|
||||||
raise_error(automation, "Group(#{group_id}) not found")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
assignable_user_ids = User.assign_allowed.pluck(:id)
|
|
||||||
users_on_holiday =
|
|
||||||
Set.new(
|
|
||||||
User.where(
|
|
||||||
id: UserCustomField.where(name: "on_holiday", value: "t").select(:user_id),
|
|
||||||
).pluck(:id),
|
|
||||||
)
|
|
||||||
|
|
||||||
group_users = group.group_users.joins(:user)
|
|
||||||
if skip_new_users_for_days = fields.dig("skip_new_users_for_days", "value").presence
|
|
||||||
group_users = group_users.where("users.created_at < ?", skip_new_users_for_days.to_i.days.ago)
|
|
||||||
end
|
|
||||||
|
|
||||||
group_users_ids =
|
|
||||||
group_users
|
|
||||||
.pluck("users.id")
|
|
||||||
.filter { |user_id| assignable_user_ids.include?(user_id) }
|
|
||||||
.reject { |user_id| users_on_holiday.include?(user_id) }
|
|
||||||
|
|
||||||
if group_users_ids.empty?
|
|
||||||
RandomAssignUtils.no_one!(topic_id, group.name)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
max_recently_assigned_days =
|
|
||||||
(fields.dig("max_recently_assigned_days", "value").presence || 180).to_i.days.ago
|
|
||||||
last_assignees_ids =
|
|
||||||
RandomAssignUtils.recently_assigned_users_ids(topic_id, max_recently_assigned_days)
|
|
||||||
users_ids = group_users_ids - last_assignees_ids
|
|
||||||
if users_ids.blank?
|
|
||||||
min_recently_assigned_days =
|
|
||||||
(fields.dig("min_recently_assigned_days", "value").presence || 14).to_i.days.ago
|
|
||||||
recently_assigned_users_ids =
|
|
||||||
RandomAssignUtils.recently_assigned_users_ids(topic_id, min_recently_assigned_days)
|
|
||||||
users_ids = group_users_ids - recently_assigned_users_ids
|
|
||||||
end
|
|
||||||
|
|
||||||
if users_ids.blank?
|
|
||||||
RandomAssignUtils.no_one!(topic_id, group.name)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if fields.dig("in_working_hours", "value")
|
|
||||||
assign_to_user_id =
|
|
||||||
users_ids.shuffle.find { |user_id| RandomAssignUtils.in_working_hours?(user_id) }
|
|
||||||
end
|
|
||||||
|
|
||||||
assign_to_user_id ||= users_ids.sample
|
|
||||||
if assign_to_user_id.blank?
|
|
||||||
RandomAssignUtils.no_one!(topic_id, group.name)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
assign_to = User.find(assign_to_user_id)
|
|
||||||
result = nil
|
|
||||||
if raw = fields.dig("post_template", "value").presence
|
|
||||||
post =
|
|
||||||
PostCreator.new(
|
|
||||||
Discourse.system_user,
|
|
||||||
raw: raw,
|
|
||||||
skip_validations: true,
|
|
||||||
topic_id: topic.id,
|
|
||||||
).create!
|
|
||||||
|
|
||||||
result = Assigner.new(post, Discourse.system_user).assign(assign_to)
|
|
||||||
|
|
||||||
PostDestroyer.new(Discourse.system_user, post).destroy if !result[:success]
|
|
||||||
else
|
|
||||||
result = Assigner.new(topic, Discourse.system_user).assign(assign_to)
|
|
||||||
end
|
|
||||||
|
|
||||||
RandomAssignUtils.no_one!(topic_id, group.name) if !result[:success]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.recently_assigned_users_ids(topic_id, from)
|
def automation_script!
|
||||||
posts =
|
return log_info("Topic(#{topic.id}) has already been assigned recently") if assigned_recently?
|
||||||
Post
|
return no_one! unless assigned_user
|
||||||
.joins(:user)
|
assign_user!
|
||||||
.where(topic_id: topic_id, action_code: %w[assigned reassigned assigned_to_post])
|
end
|
||||||
.where("posts.created_at > ?", from)
|
|
||||||
.order(created_at: :desc)
|
def recently_assigned_users_ids(from)
|
||||||
usernames =
|
usernames =
|
||||||
Post.custom_fields_for_ids(posts, [:action_code_who]).map { |_, v| v["action_code_who"] }.uniq
|
PostCustomField
|
||||||
User.where(username: usernames).limit(100).pluck(:id)
|
.joins(:post)
|
||||||
|
.where(
|
||||||
|
name: "action_code_who",
|
||||||
|
posts: {
|
||||||
|
topic: topic,
|
||||||
|
action_code: %w[assigned reassigned assigned_to_post],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.where("posts.created_at > ?", from)
|
||||||
|
.order("posts.created_at DESC")
|
||||||
|
.pluck(:value)
|
||||||
|
.uniq
|
||||||
|
User
|
||||||
|
.where(username: usernames)
|
||||||
|
.joins(
|
||||||
|
"JOIN unnest('{#{usernames.join(",")}}'::text[]) WITH ORDINALITY t(username, ord) USING(username)",
|
||||||
|
)
|
||||||
|
.limit(100)
|
||||||
|
.order("ord")
|
||||||
|
.pluck(:id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.user_tzinfo(user_id)
|
private
|
||||||
|
|
||||||
|
def assigned_user
|
||||||
|
@assigned_user ||=
|
||||||
|
begin
|
||||||
|
group_users_ids = group_users.pluck(:id)
|
||||||
|
return if group_users_ids.empty?
|
||||||
|
|
||||||
|
last_assignees_ids = recently_assigned_users_ids(max_recently_assigned_days)
|
||||||
|
users_ids = group_users_ids - last_assignees_ids
|
||||||
|
if users_ids.blank?
|
||||||
|
recently_assigned_users_ids = recently_assigned_users_ids(min_recently_assigned_days)
|
||||||
|
users_ids = group_users_ids - recently_assigned_users_ids
|
||||||
|
end
|
||||||
|
users_ids << last_assignees_ids.intersection(group_users_ids).last if users_ids.blank?
|
||||||
|
if fields.dig("in_working_hours", "value")
|
||||||
|
assign_to_user_id = users_ids.shuffle.detect { |user_id| in_working_hours?(user_id) }
|
||||||
|
end
|
||||||
|
assign_to_user_id ||= users_ids.sample
|
||||||
|
|
||||||
|
User.find(assign_to_user_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def assign_user!
|
||||||
|
return create_post_template if post_template
|
||||||
|
Assigner
|
||||||
|
.new(topic, Discourse.system_user)
|
||||||
|
.assign(assigned_user, allow_self_reassign: true)
|
||||||
|
.then do |result|
|
||||||
|
next if result[:success]
|
||||||
|
no_one!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_post_template
|
||||||
|
post =
|
||||||
|
PostCreator.new(
|
||||||
|
Discourse.system_user,
|
||||||
|
raw: post_template,
|
||||||
|
skip_validations: true,
|
||||||
|
topic_id: topic.id,
|
||||||
|
).create!
|
||||||
|
Assigner
|
||||||
|
.new(post, Discourse.system_user)
|
||||||
|
.assign(assigned_user, allow_self_reassign: true)
|
||||||
|
.then do |result|
|
||||||
|
next if result[:success]
|
||||||
|
PostDestroyer.new(Discourse.system_user, post).destroy
|
||||||
|
no_one!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def group_users
|
||||||
|
users =
|
||||||
|
group
|
||||||
|
.users
|
||||||
|
.where(id: User.assign_allowed.select(:id))
|
||||||
|
.where.not(
|
||||||
|
id:
|
||||||
|
User
|
||||||
|
.joins(:_custom_fields)
|
||||||
|
.where(user_custom_fields: { name: "on_holiday", value: "t" })
|
||||||
|
.select(:id),
|
||||||
|
)
|
||||||
|
return users unless skip_new_users_for_days
|
||||||
|
users.where("users.created_at < ?", skip_new_users_for_days)
|
||||||
|
end
|
||||||
|
|
||||||
|
def raise_error(message)
|
||||||
|
raise("[discourse-automation id=#{automation.id}] #{message}.")
|
||||||
|
end
|
||||||
|
|
||||||
|
def log_info(message)
|
||||||
|
Rails.logger.info("[discourse-automation id=#{automation.id}] #{message}.")
|
||||||
|
end
|
||||||
|
|
||||||
|
def no_one!
|
||||||
|
PostCreator.create!(
|
||||||
|
Discourse.system_user,
|
||||||
|
topic_id: topic.id,
|
||||||
|
raw: I18n.t("discourse_automation.scriptables.random_assign.no_one", group: group.name),
|
||||||
|
validate: false,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def assigned_recently?
|
||||||
|
return unless min_hours
|
||||||
|
TopicCustomField
|
||||||
|
.where(name: "assigned_to_id", topic: topic)
|
||||||
|
.where("created_at < ?", min_hours)
|
||||||
|
.exists?
|
||||||
|
end
|
||||||
|
|
||||||
|
def skip_new_users_for_days
|
||||||
|
days = fields.dig("skip_new_users_for_days", "value").presence
|
||||||
|
return unless days
|
||||||
|
days.to_i.days.ago
|
||||||
|
end
|
||||||
|
|
||||||
|
def max_recently_assigned_days
|
||||||
|
@max_days ||= (fields.dig("max_recently_assigned_days", "value").presence || 180).to_i.days.ago
|
||||||
|
end
|
||||||
|
|
||||||
|
def min_recently_assigned_days
|
||||||
|
@min_days ||= (fields.dig("min_recently_assigned_days", "value").presence || 14).to_i.days.ago
|
||||||
|
end
|
||||||
|
|
||||||
|
def post_template
|
||||||
|
@post_template ||= fields.dig("post_template", "value").presence
|
||||||
|
end
|
||||||
|
|
||||||
|
def min_hours
|
||||||
|
hours = fields.dig("minimum_time_between_assignments", "value").presence
|
||||||
|
return unless hours
|
||||||
|
hours.to_i.hours.ago
|
||||||
|
end
|
||||||
|
|
||||||
|
def in_working_hours?(user_id)
|
||||||
|
tzinfo = user_tzinfo(user_id)
|
||||||
|
tztime = tzinfo.now
|
||||||
|
|
||||||
|
!tztime.saturday? && !tztime.sunday? && tztime.hour > 7 && tztime.hour < 11
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_tzinfo(user_id)
|
||||||
timezone = UserOption.where(user_id: user_id).pluck(:timezone).first || "UTC"
|
timezone = UserOption.where(user_id: user_id).pluck(:timezone).first || "UTC"
|
||||||
|
|
||||||
tzinfo = nil
|
tzinfo = nil
|
||||||
|
@ -140,20 +200,4 @@ class RandomAssignUtils
|
||||||
|
|
||||||
tzinfo
|
tzinfo
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.no_one!(topic_id, group)
|
|
||||||
PostCreator.create!(
|
|
||||||
Discourse.system_user,
|
|
||||||
topic_id: topic_id,
|
|
||||||
raw: I18n.t("discourse_automation.scriptables.random_assign.no_one", group: group),
|
|
||||||
validate: false,
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.in_working_hours?(user_id)
|
|
||||||
tzinfo = RandomAssignUtils.user_tzinfo(user_id)
|
|
||||||
tztime = tzinfo.now
|
|
||||||
|
|
||||||
!tztime.saturday? && !tztime.sunday? && tztime.hour > 7 && tztime.hour < 11
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
12
package.json
12
package.json
|
@ -1,10 +1,10 @@
|
||||||
{
|
{
|
||||||
"name": "discourse",
|
"name": "discourse-assign",
|
||||||
"version": "1.0.1",
|
"private": true,
|
||||||
"repository": "https://github.com/discourse/discourse-assign",
|
|
||||||
"author": "Discourse",
|
|
||||||
"license": "MIT",
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint-config-discourse": "^3.4.0"
|
"@discourse/lint-configs": "^1.3.5",
|
||||||
|
"ember-template-lint": "^5.13.0",
|
||||||
|
"eslint": "^8.56.0",
|
||||||
|
"prettier": "^2.8.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
112
plugin.rb
112
plugin.rb
|
@ -1,7 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# name: discourse-assign
|
# name: discourse-assign
|
||||||
# about: Assign users to topics
|
# about: Provides the ability to assign topics and individual posts to a user or group.
|
||||||
|
# meta_topic_id: 58044
|
||||||
# version: 1.0.1
|
# version: 1.0.1
|
||||||
# authors: Sam Saffron
|
# authors: Sam Saffron
|
||||||
# url: https://github.com/discourse/discourse-assign
|
# url: https://github.com/discourse/discourse-assign
|
||||||
|
@ -26,10 +27,12 @@ after_initialize do
|
||||||
require_relative "app/jobs/regular/unassign_notification"
|
require_relative "app/jobs/regular/unassign_notification"
|
||||||
require_relative "app/jobs/scheduled/enqueue_reminders"
|
require_relative "app/jobs/scheduled/enqueue_reminders"
|
||||||
require_relative "lib/assigner"
|
require_relative "lib/assigner"
|
||||||
|
require_relative "lib/discourse_assign/create_notification"
|
||||||
require_relative "lib/discourse_assign/discourse_calendar"
|
require_relative "lib/discourse_assign/discourse_calendar"
|
||||||
require_relative "lib/discourse_assign/group_extension"
|
require_relative "lib/discourse_assign/group_extension"
|
||||||
require_relative "lib/discourse_assign/helpers"
|
require_relative "lib/discourse_assign/helpers"
|
||||||
require_relative "lib/discourse_assign/list_controller_extension"
|
require_relative "lib/discourse_assign/list_controller_extension"
|
||||||
|
require_relative "lib/discourse_assign/notification_extension"
|
||||||
require_relative "lib/discourse_assign/post_extension"
|
require_relative "lib/discourse_assign/post_extension"
|
||||||
require_relative "lib/discourse_assign/topic_extension"
|
require_relative "lib/discourse_assign/topic_extension"
|
||||||
require_relative "lib/discourse_assign/web_hook_extension"
|
require_relative "lib/discourse_assign/web_hook_extension"
|
||||||
|
@ -38,11 +41,12 @@ after_initialize do
|
||||||
require_relative "lib/topic_assigner"
|
require_relative "lib/topic_assigner"
|
||||||
|
|
||||||
reloadable_patch do |plugin|
|
reloadable_patch do |plugin|
|
||||||
Group.class_eval { prepend DiscourseAssign::GroupExtension }
|
Group.prepend(DiscourseAssign::GroupExtension)
|
||||||
ListController.class_eval { prepend DiscourseAssign::ListControllerExtension }
|
ListController.prepend(DiscourseAssign::ListControllerExtension)
|
||||||
Post.class_eval { prepend DiscourseAssign::PostExtension }
|
Post.prepend(DiscourseAssign::PostExtension)
|
||||||
Topic.class_eval { prepend DiscourseAssign::TopicExtension }
|
Topic.prepend(DiscourseAssign::TopicExtension)
|
||||||
WebHook.class_eval { prepend DiscourseAssign::WebHookExtension }
|
WebHook.prepend(DiscourseAssign::WebHookExtension)
|
||||||
|
Notification.prepend(DiscourseAssign::NotificationExtension)
|
||||||
end
|
end
|
||||||
|
|
||||||
register_group_param(:assignable_level)
|
register_group_param(:assignable_level)
|
||||||
|
@ -52,7 +56,7 @@ after_initialize do
|
||||||
|
|
||||||
frequency_field = PendingAssignsReminder::REMINDERS_FREQUENCY
|
frequency_field = PendingAssignsReminder::REMINDERS_FREQUENCY
|
||||||
register_editable_user_custom_field frequency_field
|
register_editable_user_custom_field frequency_field
|
||||||
User.register_custom_field_type frequency_field, :integer
|
register_user_custom_field_type(frequency_field, :integer, max_length: 10)
|
||||||
DiscoursePluginRegistry.serialized_current_user_fields << frequency_field
|
DiscoursePluginRegistry.serialized_current_user_fields << frequency_field
|
||||||
add_to_serializer(:user, :reminders_frequency) { RemindAssignsFrequencySiteSettings.values }
|
add_to_serializer(:user, :reminders_frequency) { RemindAssignsFrequencySiteSettings.values }
|
||||||
|
|
||||||
|
@ -88,13 +92,10 @@ after_initialize do
|
||||||
end
|
end
|
||||||
|
|
||||||
add_to_class(:user, :can_assign?) do
|
add_to_class(:user, :can_assign?) do
|
||||||
@can_assign ||=
|
return @can_assign if defined?(@can_assign)
|
||||||
begin
|
|
||||||
return true if admin?
|
allowed_groups = SiteSetting.assign_allowed_on_groups.split("|").compact
|
||||||
allowed_groups = SiteSetting.assign_allowed_on_groups.split("|").compact
|
@can_assign = admin? || (allowed_groups.present? && groups.where(id: allowed_groups).exists?)
|
||||||
allowed_groups.present? && groups.where(id: allowed_groups).exists? ? :true : :false
|
|
||||||
end
|
|
||||||
@can_assign == :true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
add_to_serializer(:current_user, :never_auto_track_topics) do
|
add_to_serializer(:current_user, :never_auto_track_topics) do
|
||||||
|
@ -167,7 +168,12 @@ after_initialize do
|
||||||
|
|
||||||
on(:unassign_topic) { |topic, unassigning_user| Assigner.new(topic, unassigning_user).unassign }
|
on(:unassign_topic) { |topic, unassigning_user| Assigner.new(topic, unassigning_user).unassign }
|
||||||
|
|
||||||
Site.preloaded_category_custom_fields << "enable_unassigned_filter"
|
if respond_to?(:register_preloaded_category_custom_fields)
|
||||||
|
register_preloaded_category_custom_fields("enable_unassigned_filter")
|
||||||
|
else
|
||||||
|
# TODO: Drop the if-statement and this if-branch in Discourse v3.2
|
||||||
|
Site.preloaded_category_custom_fields << "enable_unassigned_filter"
|
||||||
|
end
|
||||||
|
|
||||||
BookmarkQuery.on_preload do |bookmarks, bookmark_query|
|
BookmarkQuery.on_preload do |bookmarks, bookmark_query|
|
||||||
if SiteSetting.assign_enabled?
|
if SiteSetting.assign_enabled?
|
||||||
|
@ -201,7 +207,8 @@ after_initialize do
|
||||||
allowed_access = SiteSetting.assigns_public || can_assign
|
allowed_access = SiteSetting.assigns_public || can_assign
|
||||||
|
|
||||||
if allowed_access && topics.length > 0
|
if allowed_access && topics.length > 0
|
||||||
assignments = Assignment.strict_loading.where(topic: topics, active: true).includes(:target)
|
assignments =
|
||||||
|
Assignment.strict_loading.active.where(topic: topics).includes(:target, :assigned_to)
|
||||||
assignments_map = assignments.group_by(&:topic_id)
|
assignments_map = assignments.group_by(&:topic_id)
|
||||||
|
|
||||||
user_ids =
|
user_ids =
|
||||||
|
@ -503,7 +510,7 @@ after_initialize do
|
||||||
:topic_view,
|
:topic_view,
|
||||||
:assigned_to_user,
|
:assigned_to_user,
|
||||||
include_condition: -> do
|
include_condition: -> do
|
||||||
(SiteSetting.assigns_public || scope.can_assign?) && object.topic.assigned_to&.is_a?(User)
|
(SiteSetting.assigns_public || scope.can_assign?) && object.topic.assigned_to.is_a?(User)
|
||||||
end,
|
end,
|
||||||
) { DiscourseAssign::Helpers.build_assigned_to_user(object.topic.assigned_to, object.topic) }
|
) { DiscourseAssign::Helpers.build_assigned_to_user(object.topic.assigned_to, object.topic) }
|
||||||
|
|
||||||
|
@ -511,7 +518,7 @@ after_initialize do
|
||||||
:topic_view,
|
:topic_view,
|
||||||
:assigned_to_group,
|
:assigned_to_group,
|
||||||
include_condition: -> do
|
include_condition: -> do
|
||||||
(SiteSetting.assigns_public || scope.can_assign?) && object.topic.assigned_to&.is_a?(Group)
|
(SiteSetting.assigns_public || scope.can_assign?) && object.topic.assigned_to.is_a?(Group)
|
||||||
end,
|
end,
|
||||||
) { DiscourseAssign::Helpers.build_assigned_to_group(object.topic.assigned_to, object.topic) }
|
) { DiscourseAssign::Helpers.build_assigned_to_group(object.topic.assigned_to, object.topic) }
|
||||||
|
|
||||||
|
@ -551,7 +558,7 @@ after_initialize do
|
||||||
:suggested_topic,
|
:suggested_topic,
|
||||||
:assigned_to_user,
|
:assigned_to_user,
|
||||||
include_condition: -> do
|
include_condition: -> do
|
||||||
(SiteSetting.assigns_public || scope.can_assign?) && object.assigned_to&.is_a?(User)
|
(SiteSetting.assigns_public || scope.can_assign?) && object.assigned_to.is_a?(User)
|
||||||
end,
|
end,
|
||||||
) { DiscourseAssign::Helpers.build_assigned_to_user(object.assigned_to, object) }
|
) { DiscourseAssign::Helpers.build_assigned_to_user(object.assigned_to, object) }
|
||||||
|
|
||||||
|
@ -559,7 +566,7 @@ after_initialize do
|
||||||
:suggested_topic,
|
:suggested_topic,
|
||||||
:assigned_to_group,
|
:assigned_to_group,
|
||||||
include_condition: -> do
|
include_condition: -> do
|
||||||
(SiteSetting.assigns_public || scope.can_assign?) && object.assigned_to&.is_a?(Group)
|
(SiteSetting.assigns_public || scope.can_assign?) && object.assigned_to.is_a?(Group)
|
||||||
end,
|
end,
|
||||||
) { DiscourseAssign::Helpers.build_assigned_to_group(object.assigned_to, object) }
|
) { DiscourseAssign::Helpers.build_assigned_to_group(object.assigned_to, object) }
|
||||||
|
|
||||||
|
@ -584,7 +591,7 @@ after_initialize do
|
||||||
:topic_list_item,
|
:topic_list_item,
|
||||||
:assigned_to_user,
|
:assigned_to_user,
|
||||||
include_condition: -> do
|
include_condition: -> do
|
||||||
(SiteSetting.assigns_public || scope.can_assign?) && object.assigned_to&.is_a?(User)
|
(SiteSetting.assigns_public || scope.can_assign?) && object.assigned_to.is_a?(User)
|
||||||
end,
|
end,
|
||||||
) { BasicUserSerializer.new(object.assigned_to, scope: scope, root: false).as_json }
|
) { BasicUserSerializer.new(object.assigned_to, scope: scope, root: false).as_json }
|
||||||
|
|
||||||
|
@ -592,7 +599,7 @@ after_initialize do
|
||||||
:topic_list_item,
|
:topic_list_item,
|
||||||
:assigned_to_group,
|
:assigned_to_group,
|
||||||
include_condition: -> do
|
include_condition: -> do
|
||||||
(SiteSetting.assigns_public || scope.can_assign?) && object.assigned_to&.is_a?(Group)
|
(SiteSetting.assigns_public || scope.can_assign?) && object.assigned_to.is_a?(Group)
|
||||||
end,
|
end,
|
||||||
) { AssignedGroupSerializer.new(object.assigned_to, scope: scope, root: false).as_json }
|
) { AssignedGroupSerializer.new(object.assigned_to, scope: scope, root: false).as_json }
|
||||||
|
|
||||||
|
@ -610,7 +617,7 @@ after_initialize do
|
||||||
:search_topic_list_item,
|
:search_topic_list_item,
|
||||||
:assigned_to_user,
|
:assigned_to_user,
|
||||||
include_condition: -> do
|
include_condition: -> do
|
||||||
(SiteSetting.assigns_public || scope.can_assign?) && object.assigned_to&.is_a?(User)
|
(SiteSetting.assigns_public || scope.can_assign?) && object.assigned_to.is_a?(User)
|
||||||
end,
|
end,
|
||||||
) { DiscourseAssign::Helpers.build_assigned_to_user(object.assigned_to, object) }
|
) { DiscourseAssign::Helpers.build_assigned_to_user(object.assigned_to, object) }
|
||||||
|
|
||||||
|
@ -618,7 +625,7 @@ after_initialize do
|
||||||
:search_topic_list_item,
|
:search_topic_list_item,
|
||||||
:assigned_to_group,
|
:assigned_to_group,
|
||||||
include_condition: -> do
|
include_condition: -> do
|
||||||
(SiteSetting.assigns_public || scope.can_assign?) && object.assigned_to&.is_a?(Group)
|
(SiteSetting.assigns_public || scope.can_assign?) && object.assigned_to.is_a?(Group)
|
||||||
end,
|
end,
|
||||||
) { AssignedGroupSerializer.new(object.assigned_to, scope: scope, root: false).as_json }
|
) { AssignedGroupSerializer.new(object.assigned_to, scope: scope, root: false).as_json }
|
||||||
|
|
||||||
|
@ -635,7 +642,11 @@ after_initialize do
|
||||||
if @user.can_assign?
|
if @user.can_assign?
|
||||||
assign_user = User.find_by_username(@operation[:username])
|
assign_user = User.find_by_username(@operation[:username])
|
||||||
topics.each do |topic|
|
topics.each do |topic|
|
||||||
Assigner.new(topic, @user).assign(assign_user, note: @operation[:note])
|
Assigner.new(topic, @user).assign(
|
||||||
|
assign_user,
|
||||||
|
status: @operation[:status],
|
||||||
|
note: @operation[:note],
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -647,6 +658,7 @@ after_initialize do
|
||||||
end
|
end
|
||||||
|
|
||||||
register_permitted_bulk_action_parameter :username
|
register_permitted_bulk_action_parameter :username
|
||||||
|
register_permitted_bulk_action_parameter :status
|
||||||
register_permitted_bulk_action_parameter :note
|
register_permitted_bulk_action_parameter :note
|
||||||
|
|
||||||
add_to_class(:user_bookmark_base_serializer, :assigned_to) do
|
add_to_class(:user_bookmark_base_serializer, :assigned_to) do
|
||||||
|
@ -663,7 +675,7 @@ after_initialize do
|
||||||
:assigned_to_user,
|
:assigned_to_user,
|
||||||
include_condition: -> do
|
include_condition: -> do
|
||||||
return false if !can_have_assignment?
|
return false if !can_have_assignment?
|
||||||
(SiteSetting.assigns_public || scope.can_assign?) && assigned_to&.is_a?(User)
|
(SiteSetting.assigns_public || scope.can_assign?) && assigned_to.is_a?(User)
|
||||||
end,
|
end,
|
||||||
) do
|
) do
|
||||||
return if !can_have_assignment?
|
return if !can_have_assignment?
|
||||||
|
@ -675,7 +687,7 @@ after_initialize do
|
||||||
:assigned_to_group,
|
:assigned_to_group,
|
||||||
include_condition: -> do
|
include_condition: -> do
|
||||||
return false if !can_have_assignment?
|
return false if !can_have_assignment?
|
||||||
(SiteSetting.assigns_public || scope.can_assign?) && assigned_to&.is_a?(Group)
|
(SiteSetting.assigns_public || scope.can_assign?) && assigned_to.is_a?(Group)
|
||||||
end,
|
end,
|
||||||
) do
|
) do
|
||||||
return if !can_have_assignment?
|
return if !can_have_assignment?
|
||||||
|
@ -694,7 +706,7 @@ after_initialize do
|
||||||
:assigned_to_user,
|
:assigned_to_user,
|
||||||
include_condition: -> do
|
include_condition: -> do
|
||||||
(SiteSetting.assigns_public || scope.can_assign?) &&
|
(SiteSetting.assigns_public || scope.can_assign?) &&
|
||||||
object.assignment&.assigned_to&.is_a?(User) && object.assignment.active
|
object.assignment&.assigned_to.is_a?(User) && object.assignment.active
|
||||||
end,
|
end,
|
||||||
) { BasicUserSerializer.new(object.assignment.assigned_to, scope: scope, root: false).as_json }
|
) { BasicUserSerializer.new(object.assignment.assigned_to, scope: scope, root: false).as_json }
|
||||||
|
|
||||||
|
@ -703,7 +715,7 @@ after_initialize do
|
||||||
:assigned_to_group,
|
:assigned_to_group,
|
||||||
include_condition: -> do
|
include_condition: -> do
|
||||||
(SiteSetting.assigns_public || scope.can_assign?) &&
|
(SiteSetting.assigns_public || scope.can_assign?) &&
|
||||||
object.assignment&.assigned_to&.is_a?(Group) && object.assignment.active
|
object.assignment&.assigned_to.is_a?(Group) && object.assignment.active
|
||||||
end,
|
end,
|
||||||
) do
|
) do
|
||||||
AssignedGroupSerializer.new(object.assignment.assigned_to, scope: scope, root: false).as_json
|
AssignedGroupSerializer.new(object.assignment.assigned_to, scope: scope, root: false).as_json
|
||||||
|
@ -733,13 +745,13 @@ after_initialize do
|
||||||
add_to_serializer(
|
add_to_serializer(
|
||||||
:flagged_topic,
|
:flagged_topic,
|
||||||
:assigned_to_user,
|
:assigned_to_user,
|
||||||
include_condition: -> { object.assigned_to && object.assigned_to&.is_a?(User) },
|
include_condition: -> { object.assigned_to && object.assigned_to.is_a?(User) },
|
||||||
) { DiscourseAssign::Helpers.build_assigned_to_user(object.assigned_to, object) }
|
) { DiscourseAssign::Helpers.build_assigned_to_user(object.assigned_to, object) }
|
||||||
|
|
||||||
add_to_serializer(
|
add_to_serializer(
|
||||||
:flagged_topic,
|
:flagged_topic,
|
||||||
:assigned_to_group,
|
:assigned_to_group,
|
||||||
include_condition: -> { object.assigned_to && object.assigned_to&.is_a?(Group) },
|
include_condition: -> { object.assigned_to && object.assigned_to.is_a?(Group) },
|
||||||
) { DiscourseAssign::Helpers.build_assigned_to_group(object.assigned_to, object) }
|
) { DiscourseAssign::Helpers.build_assigned_to_group(object.assigned_to, object) }
|
||||||
|
|
||||||
# Reviewable
|
# Reviewable
|
||||||
|
@ -836,20 +848,12 @@ after_initialize do
|
||||||
next if !info[:group]
|
next if !info[:group]
|
||||||
|
|
||||||
Assignment
|
Assignment
|
||||||
.where(topic_id: topic.id, active: false)
|
.inactive
|
||||||
|
.where(topic: topic)
|
||||||
.find_each do |assignment|
|
.find_each do |assignment|
|
||||||
next unless assignment.target
|
next unless assignment.target
|
||||||
assignment.update!(active: true)
|
assignment.update!(active: true)
|
||||||
Jobs.enqueue(
|
Jobs.enqueue(:assign_notification, assignment_id: assignment.id)
|
||||||
:assign_notification,
|
|
||||||
topic_id: topic.id,
|
|
||||||
post_id: assignment.target_type.is_a?(Topic) ? topic.first_post.id : assignment.target.id,
|
|
||||||
assigned_to_id: assignment.assigned_to_id,
|
|
||||||
assigned_to_type: assignment.assigned_to_type,
|
|
||||||
assigned_by_id: assignment.assigned_by_user_id,
|
|
||||||
skip_small_action_post: true,
|
|
||||||
assignment_id: assignment.id,
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -863,32 +867,30 @@ after_initialize do
|
||||||
next if !info[:group]
|
next if !info[:group]
|
||||||
|
|
||||||
Assignment
|
Assignment
|
||||||
.where(topic_id: topic.id, active: true)
|
.active
|
||||||
|
.where(topic: topic)
|
||||||
.find_each do |assignment|
|
.find_each do |assignment|
|
||||||
assignment.update!(active: false)
|
assignment.update!(active: false)
|
||||||
Jobs.enqueue(
|
Jobs.enqueue(
|
||||||
:unassign_notification,
|
:unassign_notification,
|
||||||
topic_id: topic.id,
|
topic_id: topic.id,
|
||||||
assigned_to_id: assignment.assigned_to.id,
|
assigned_to_id: assignment.assigned_to_id,
|
||||||
assigned_to_type: assignment.assigned_to_type,
|
assigned_to_type: assignment.assigned_to_type,
|
||||||
|
assignment_id: assignment.id,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
on(:user_removed_from_group) do |user, group|
|
on(:user_added_to_group) do |user, group, automatic:|
|
||||||
assign_allowed_groups = SiteSetting.assign_allowed_on_groups.split("|").map(&:to_i)
|
group.assignments.active.find_each do |assignment|
|
||||||
|
Jobs.enqueue(:assign_notification, assignment_id: assignment.id)
|
||||||
if assign_allowed_groups.include?(group.id)
|
|
||||||
groups = GroupUser.where(user: user).pluck(:group_id)
|
|
||||||
|
|
||||||
if (groups & assign_allowed_groups).empty?
|
|
||||||
topics = Topic.joins(:assignment).where("assignments.assigned_to_id = ?", user.id)
|
|
||||||
|
|
||||||
topics.each { |topic| Assigner.new(topic, Discourse.system_user).unassign }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
on(:user_removed_from_group) do |user, group|
|
||||||
|
user.notifications.for_assignment(group.assignments.select(:id)).destroy_all
|
||||||
|
end
|
||||||
|
|
||||||
on(:post_moved) do |post, original_topic_id|
|
on(:post_moved) do |post, original_topic_id|
|
||||||
assignment =
|
assignment =
|
||||||
Assignment.where(topic_id: original_topic_id, target_type: "Post", target_id: post.id).first
|
Assignment.where(topic_id: original_topic_id, target_type: "Post", target_id: post.id).first
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue