Allow users to subscribe to a group label at group or project level
This commit is contained in:
parent
733fbebe0e
commit
1af4d29b94
5 changed files with 122 additions and 11 deletions
48
app/assets/javascripts/group_label_subscription.js.es6
Normal file
48
app/assets/javascripts/group_label_subscription.js.es6
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/* eslint-disable */
|
||||||
|
(function(global) {
|
||||||
|
class GroupLabelSubscription {
|
||||||
|
constructor(container) {
|
||||||
|
const $container = $(container);
|
||||||
|
this.$dropdown = $container.find('.dropdown');
|
||||||
|
this.$unsubscribeBtn = $container.find('.js-unsubscribe-button');
|
||||||
|
|
||||||
|
$container.on('click', '.js-subscribe-button', this.subscribe.bind(this));
|
||||||
|
$container.on('click', '.js-unsubscribe-button', this.unsubscribe.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsubscribe(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const url = this.$unsubscribeBtn.attr('data-url');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: url
|
||||||
|
}).done(() => {
|
||||||
|
this.$dropdown.toggleClass('hidden');
|
||||||
|
this.$unsubscribeBtn.toggleClass('hidden');
|
||||||
|
this.$unsubscribeBtn.removeAttr('data-url');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribe(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const $btn = $(event.currentTarget);
|
||||||
|
const url = $btn.attr('data-url');
|
||||||
|
|
||||||
|
this.$unsubscribeBtn.attr('data-url', url);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: url
|
||||||
|
}).done(() => {
|
||||||
|
this.$dropdown.toggleClass('hidden');
|
||||||
|
this.$unsubscribeBtn.toggleClass('hidden');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
global.GroupLabelSubscription = GroupLabelSubscription;
|
||||||
|
|
||||||
|
})(window.gl || (window.gl = {}));
|
|
@ -90,7 +90,7 @@
|
||||||
|
|
||||||
@media (min-width: $screen-sm-min) {
|
@media (min-width: $screen-sm-min) {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 35%;
|
width: 30%;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
@ -222,6 +222,14 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.label-subscription {
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
.dropdown-group-label a {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.label-subscribe-button {
|
.label-subscribe-button {
|
||||||
.label-subscribe-button-icon {
|
.label-subscribe-button-icon {
|
||||||
&[disabled] {
|
&[disabled] {
|
||||||
|
|
|
@ -140,6 +140,20 @@ module LabelsHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def group_label_subscription_status(label, project)
|
||||||
|
return 'project-level' if label.subscribed?(current_user, project)
|
||||||
|
return 'group-level' if label.subscribed?(current_user)
|
||||||
|
|
||||||
|
'unsubscribed'
|
||||||
|
end
|
||||||
|
|
||||||
|
def group_label_unsubscribe_path(label, project)
|
||||||
|
case group_label_subscription_status(label, project)
|
||||||
|
when 'project-level' then toggle_subscription_namespace_project_label_path(@project.namespace, @project, label)
|
||||||
|
when 'group-level' then toggle_subscription_group_label_path(label.group, label)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def label_subscription_status(label, project)
|
def label_subscription_status(label, project)
|
||||||
label.subscribed?(current_user, project) ? 'subscribed' : 'unsubscribed'
|
label.subscribed?(current_user, project) ? 'subscribed' : 'unsubscribed'
|
||||||
end
|
end
|
||||||
|
|
|
@ -33,22 +33,41 @@ module Subscribable
|
||||||
end
|
end
|
||||||
|
|
||||||
def toggle_subscription(user, project = nil)
|
def toggle_subscription(user, project = nil)
|
||||||
|
unsubscribe_from_other_levels(user, project)
|
||||||
|
|
||||||
find_or_initialize_subscription(user, project).
|
find_or_initialize_subscription(user, project).
|
||||||
update(subscribed: !subscribed?(user, project))
|
update(subscribed: !subscribed?(user, project))
|
||||||
end
|
end
|
||||||
|
|
||||||
def subscribe(user, project = nil)
|
def subscribe(user, project = nil)
|
||||||
find_or_initialize_subscription(user, project).
|
unsubscribe_from_other_levels(user, project)
|
||||||
update(subscribed: true)
|
|
||||||
|
find_or_initialize_subscription(user, project)
|
||||||
|
.update(subscribed: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def unsubscribe(user, project = nil)
|
def unsubscribe(user, project = nil)
|
||||||
find_or_initialize_subscription(user, project).
|
unsubscribe_from_other_levels(user, project)
|
||||||
update(subscribed: false)
|
|
||||||
|
find_or_initialize_subscription(user, project)
|
||||||
|
.update(subscribed: false)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def unsubscribe_from_other_levels(user, project)
|
||||||
|
other_subscriptions = subscriptions.where(user: user)
|
||||||
|
|
||||||
|
other_subscriptions =
|
||||||
|
if project.blank?
|
||||||
|
other_subscriptions.where.not(project: nil)
|
||||||
|
else
|
||||||
|
other_subscriptions.where(project: nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
other_subscriptions.update_all(subscribed: false)
|
||||||
|
end
|
||||||
|
|
||||||
def find_or_initialize_subscription(user, project)
|
def find_or_initialize_subscription(user, project)
|
||||||
subscriptions.
|
subscriptions.
|
||||||
find_or_initialize_by(user_id: user.id, project_id: project.try(:id))
|
find_or_initialize_by(user_id: user.id, project_id: project.try(:id))
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
= pluralize open_issues_count, 'open issue'
|
= pluralize open_issues_count, 'open issue'
|
||||||
- if current_user && defined?(@project)
|
- if current_user && defined?(@project)
|
||||||
%li.label-subscription
|
%li.label-subscription
|
||||||
%a.js-subscribe-button.label-subscribe-button.subscription-status{ role: "button", href: "#", data: { toggle: "tooltip", status: label_subscription_status(label, @project), url: toggle_subscription_namespace_project_label_path(@project.namespace, @project, label) } }
|
%a.js-subscribe-button.label-subscribe-button{ role: 'button', href: '#', data: { toggle: 'tooltip', status: label_subscription_status(label, @project), url: toggle_subscription_namespace_project_label_path(@project.namespace, @project, label) } }
|
||||||
%span= label_subscription_toggle_button_text(label, @project)
|
%span= label_subscription_toggle_button_text(label, @project)
|
||||||
- if can?(current_user, :admin_label, label)
|
- if can?(current_user, :admin_label, label)
|
||||||
%li
|
%li
|
||||||
|
@ -36,9 +36,27 @@
|
||||||
|
|
||||||
- if current_user && defined?(@project)
|
- if current_user && defined?(@project)
|
||||||
.label-subscription.inline
|
.label-subscription.inline
|
||||||
%button.js-subscribe-button.label-subscribe-button.btn.btn-default.btn-action.subscription-status{ type: "button", title: label_subscription_toggle_button_text(label, @project), data: { toggle: "tooltip", status: label_subscription_status(label, @project), url: toggle_subscription_namespace_project_label_path(@project.namespace, @project, label) } }
|
- if label.is_a?(ProjectLabel)
|
||||||
|
%button.js-subscribe-button.label-subscribe-button.btn.btn-default.btn-action{ type: 'button', title: label_subscription_toggle_button_text(label, @project), data: { toggle: 'tooltip', status: label_subscription_status(label, @project), url: toggle_subscription_namespace_project_label_path(@project.namespace, @project, label) } }
|
||||||
%span= label_subscription_toggle_button_text(label, @project)
|
%span= label_subscription_toggle_button_text(label, @project)
|
||||||
= icon('spinner spin', class: 'label-subscribe-button-loading')
|
= icon('spinner spin', class: 'label-subscribe-button-loading')
|
||||||
|
- else
|
||||||
|
- status = group_label_subscription_status(label, @project).inquiry
|
||||||
|
|
||||||
|
%button.js-unsubscribe-button.label-subscribe-button.btn.btn-default.btn-action{ type: 'button', class: ('hidden' if status.unsubscribed?), title: 'Unsubscribe', data: { toggle: 'tooltip', url: group_label_unsubscribe_path(label, @project) } }
|
||||||
|
%span Unsubscribe
|
||||||
|
= icon('spinner spin', class: 'label-subscribe-button-loading')
|
||||||
|
|
||||||
|
.dropdown.dropdown-group-label{ class: ('hidden' unless status.unsubscribed?) }
|
||||||
|
%button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'}
|
||||||
|
%span Subscribe
|
||||||
|
= icon('chevron-down')
|
||||||
|
%ul.dropdown-menu
|
||||||
|
%li
|
||||||
|
%a.js-subscribe-button{ data: { url: toggle_subscription_namespace_project_label_path(@project.namespace, @project, label) } }
|
||||||
|
Project level
|
||||||
|
%a.js-subscribe-button{ data: { url: toggle_subscription_group_label_path(label.group, label) } }
|
||||||
|
Group level
|
||||||
|
|
||||||
- if can?(current_user, :admin_label, label)
|
- if can?(current_user, :admin_label, label)
|
||||||
= link_to edit_label_path(label), title: "Edit", class: 'btn btn-transparent btn-action', data: {toggle: "tooltip"} do
|
= link_to edit_label_path(label), title: "Edit", class: 'btn btn-transparent btn-action', data: {toggle: "tooltip"} do
|
||||||
|
@ -49,5 +67,9 @@
|
||||||
= icon('trash-o')
|
= icon('trash-o')
|
||||||
|
|
||||||
- if current_user && defined?(@project)
|
- if current_user && defined?(@project)
|
||||||
|
- if label.is_a?(ProjectLabel)
|
||||||
:javascript
|
:javascript
|
||||||
new gl.LabelSubscription('##{dom_id(label)} .label-subscription');
|
new gl.LabelSubscription('##{dom_id(label)} .label-subscription');
|
||||||
|
- else
|
||||||
|
:javascript
|
||||||
|
new gl.GroupLabelSubscription('##{dom_id(label)} .label-subscription');
|
||||||
|
|
Loading…
Reference in a new issue