summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Barbosa Alexandre <dbalexandre@gmail.com>2016-11-15 19:59:12 -0200
committerDouglas Barbosa Alexandre <dbalexandre@gmail.com>2016-11-15 21:39:37 -0200
commit2d6fd2c922be2043ed6bbae481c032908960baeb (patch)
tree367cca816e2bf0781bc16ae3d2ef0130a227a54a
parent2475dff7646ee8b7a1ff0d5fe055e8f186d9b63a (diff)
downloadgitlab-ce-2d6fd2c922be2043ed6bbae481c032908960baeb.tar.gz
Allow users to subscribe to a group label at group or project level
-rw-r--r--app/assets/javascripts/group_label_subscription.js.es648
-rw-r--r--app/assets/stylesheets/pages/labels.scss10
-rw-r--r--app/helpers/labels_helper.rb14
-rw-r--r--app/models/concerns/subscribable.rb27
-rw-r--r--app/views/shared/_label.html.haml34
5 files changed, 122 insertions, 11 deletions
diff --git a/app/assets/javascripts/group_label_subscription.js.es6 b/app/assets/javascripts/group_label_subscription.js.es6
new file mode 100644
index 00000000000..3bc1d7127d1
--- /dev/null
+++ b/app/assets/javascripts/group_label_subscription.js.es6
@@ -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 = {}));
diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss
index 4eed1c7bfa6..e39ce19f846 100644
--- a/app/assets/stylesheets/pages/labels.scss
+++ b/app/assets/stylesheets/pages/labels.scss
@@ -90,7 +90,7 @@
@media (min-width: $screen-sm-min) {
display: inline-block;
- width: 35%;
+ width: 30%;
margin-left: 10px;
margin-bottom: 0;
vertical-align: middle;
@@ -222,6 +222,14 @@
width: 100%;
}
+.label-subscription {
+ vertical-align: middle;
+
+ .dropdown-group-label a {
+ cursor: pointer;
+ }
+}
+
.label-subscribe-button {
.label-subscribe-button-icon {
&[disabled] {
diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb
index a7c8a8a8650..7495414f525 100644
--- a/app/helpers/labels_helper.rb
+++ b/app/helpers/labels_helper.rb
@@ -140,6 +140,20 @@ module LabelsHelper
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)
label.subscribed?(current_user, project) ? 'subscribed' : 'unsubscribed'
end
diff --git a/app/models/concerns/subscribable.rb b/app/models/concerns/subscribable.rb
index 0723db548d8..83daa9b1a64 100644
--- a/app/models/concerns/subscribable.rb
+++ b/app/models/concerns/subscribable.rb
@@ -33,22 +33,41 @@ module Subscribable
end
def toggle_subscription(user, project = nil)
+ unsubscribe_from_other_levels(user, project)
+
find_or_initialize_subscription(user, project).
update(subscribed: !subscribed?(user, project))
end
def subscribe(user, project = nil)
- find_or_initialize_subscription(user, project).
- update(subscribed: true)
+ unsubscribe_from_other_levels(user, project)
+
+ find_or_initialize_subscription(user, project)
+ .update(subscribed: true)
end
def unsubscribe(user, project = nil)
- find_or_initialize_subscription(user, project).
- update(subscribed: false)
+ unsubscribe_from_other_levels(user, project)
+
+ find_or_initialize_subscription(user, project)
+ .update(subscribed: false)
end
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)
subscriptions.
find_or_initialize_by(user_id: user.id, project_id: project.try(:id))
diff --git a/app/views/shared/_label.html.haml b/app/views/shared/_label.html.haml
index 942da5dd5b7..e217b1ec85e 100644
--- a/app/views/shared/_label.html.haml
+++ b/app/views/shared/_label.html.haml
@@ -20,7 +20,7 @@
= pluralize open_issues_count, 'open issue'
- if current_user && defined?(@project)
%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)
- if can?(current_user, :admin_label, label)
%li
@@ -36,9 +36,27 @@
- if current_user && defined?(@project)
.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) } }
- %span= label_subscription_toggle_button_text(label, @project)
- = icon('spinner spin', class: 'label-subscribe-button-loading')
+ - 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)
+ = 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)
= 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')
- if current_user && defined?(@project)
- :javascript
- new gl.LabelSubscription('##{dom_id(label)} .label-subscription');
+ - if label.is_a?(ProjectLabel)
+ :javascript
+ new gl.LabelSubscription('##{dom_id(label)} .label-subscription');
+ - else
+ :javascript
+ new gl.GroupLabelSubscription('##{dom_id(label)} .label-subscription');