Skip to content
Snippets Groups Projects
Commit 655dc109 authored by Paul Slaughter's avatar Paul Slaughter Committed by 🤖 GitLab Bot 🤖
Browse files

Merge branch...

Merge branch '50020-fe-allow-email-notifications-to-be-disabled-for-all-users-of-a-group' into 'master'

UI for disabling group/project email notifications

Closes #50020

See merge request gitlab-org/gitlab-ce!30961

(cherry picked from commit 1068483f)

7699a87e UI for disabling group/project email notification
bad143ff Rename canChangeEmailsDisabled to canDisableEmails
38b3f9ec Hide emails_disabled checkbox if disabled in group
5e1fc2f5 Apply suggestion to...
bcd5cee9 Addressed review feedback
d602fc12 Minor fixes for gitlab.pot
1ee32758 Update permissions documentation
43c87103 Vue file prettified
e5ec00ce Apply suggestion to app/views/shared/notifications/_button.html.haml
e2de0db9 Disable the subgroup checkbox
dbd7fcbd Add checked to emails_disabled group settings
parent eded0c78
No related branches found
No related tags found
No related merge requests found
Showing
with 164 additions and 23 deletions
Loading
@@ -28,6 +28,11 @@ export default {
Loading
@@ -28,6 +28,11 @@ export default {
type: Object, type: Object,
required: true, required: true,
}, },
canDisableEmails: {
type: Boolean,
required: false,
default: false,
},
canChangeVisibilityLevel: { canChangeVisibilityLevel: {
type: Boolean, type: Boolean,
required: false, required: false,
Loading
@@ -104,6 +109,7 @@ export default {
Loading
@@ -104,6 +109,7 @@ export default {
lfsEnabled: true, lfsEnabled: true,
requestAccessEnabled: true, requestAccessEnabled: true,
highlightChangesClass: false, highlightChangesClass: false,
emailsDisabled: false,
}; };
   
return { ...defaults, ...this.currentSettings }; return { ...defaults, ...this.currentSettings };
Loading
@@ -341,5 +347,14 @@ export default {
Loading
@@ -341,5 +347,14 @@ export default {
/> />
</project-setting-row> </project-setting-row>
</div> </div>
<project-setting-row v-if="canDisableEmails" class="mb-3">
<label class="js-emails-disabled">
<input :value="emailsDisabled" type="hidden" name="project[emails_disabled]" />
<input v-model="emailsDisabled" type="checkbox" /> {{ __('Disable email notifications') }}
</label>
<span class="form-text text-muted">{{
__('This setting will override user notification preferences for all project members.')
}}</span>
</project-setting-row>
</div> </div>
</template> </template>
Loading
@@ -31,6 +31,11 @@ module GroupsHelper
Loading
@@ -31,6 +31,11 @@ module GroupsHelper
can?(current_user, :change_share_with_group_lock, group) can?(current_user, :change_share_with_group_lock, group)
end end
   
def can_disable_group_emails?(group)
Feature.enabled?(:emails_disabled, group, default_enabled: true) &&
can?(current_user, :set_emails_disabled, group) && !group.parent&.emails_disabled?
end
def group_issues_count(state:) def group_issues_count(state:)
IssuesFinder IssuesFinder
.new(current_user, group_id: @group.id, state: state, non_archived: true, include_subgroups: true) .new(current_user, group_id: @group.id, state: state, non_archived: true, include_subgroups: true)
Loading
Loading
Loading
@@ -5,7 +5,7 @@ module NotificationsHelper
Loading
@@ -5,7 +5,7 @@ module NotificationsHelper
   
def notification_icon_class(level) def notification_icon_class(level)
case level.to_sym case level.to_sym
when :disabled when :disabled, :owner_disabled
'microphone-slash' 'microphone-slash'
when :participating when :participating
'volume-up' 'volume-up'
Loading
@@ -18,6 +18,16 @@ module NotificationsHelper
Loading
@@ -18,6 +18,16 @@ module NotificationsHelper
end end
end end
   
def notification_icon_level(notification_setting, emails_disabled = false)
if emails_disabled
'owner_disabled'
elsif notification_setting.global?
current_user.global_notification_setting.level
else
notification_setting.level
end
end
def notification_icon(level, text = nil) def notification_icon(level, text = nil)
icon("#{notification_icon_class(level)} fw", text: text) icon("#{notification_icon_class(level)} fw", text: text)
end end
Loading
@@ -53,6 +63,8 @@ module NotificationsHelper
Loading
@@ -53,6 +63,8 @@ module NotificationsHelper
_('Use your global notification setting') _('Use your global notification setting')
when :custom when :custom
_('You will only receive notifications for the events you choose') _('You will only receive notifications for the events you choose')
when :owner_disabled
_('Notifications have been disabled by the project or group owner')
end end
end end
   
Loading
Loading
Loading
@@ -155,6 +155,12 @@ module ProjectsHelper
Loading
@@ -155,6 +155,12 @@ module ProjectsHelper
end end
end end
   
def can_disable_emails?(project, current_user)
return false if project.group&.emails_disabled?
can?(current_user, :set_emails_disabled, project) && Feature.enabled?(:emails_disabled, project, default_enabled: true)
end
def last_push_event def last_push_event
current_user&.recent_push(@project) current_user&.recent_push(@project)
end end
Loading
@@ -541,13 +547,15 @@ module ProjectsHelper
Loading
@@ -541,13 +547,15 @@ module ProjectsHelper
snippetsAccessLevel: feature.snippets_access_level, snippetsAccessLevel: feature.snippets_access_level,
pagesAccessLevel: feature.pages_access_level, pagesAccessLevel: feature.pages_access_level,
containerRegistryEnabled: !!project.container_registry_enabled, containerRegistryEnabled: !!project.container_registry_enabled,
lfsEnabled: !!project.lfs_enabled lfsEnabled: !!project.lfs_enabled,
emailsDisabled: project.emails_disabled?
} }
end end
   
def project_permissions_panel_data(project) def project_permissions_panel_data(project)
{ {
currentSettings: project_permissions_settings(project), currentSettings: project_permissions_settings(project),
canDisableEmails: can_disable_emails?(project, current_user),
canChangeVisibilityLevel: can_change_visibility_level?(project, current_user), canChangeVisibilityLevel: can_change_visibility_level?(project, current_user),
allowedVisibilityOptions: project_allowed_visibility_levels(project), allowedVisibilityOptions: project_allowed_visibility_levels(project),
visibilityHelpPath: help_page_path('public_access/public_access'), visibilityHelpPath: help_page_path('public_access/public_access'),
Loading
Loading
Loading
@@ -98,6 +98,10 @@ class IssuableSidebarBasicEntity < Grape::Entity
Loading
@@ -98,6 +98,10 @@ class IssuableSidebarBasicEntity < Grape::Entity
autocomplete_projects_path(project_id: issuable.project.id) autocomplete_projects_path(project_id: issuable.project.id)
end end
   
expose :project_emails_disabled do |issuable|
issuable.project.emails_disabled?
end
private private
   
def current_user def current_user
Loading
Loading
- can_create_subgroups = can?(current_user, :create_subgroup, @group) - can_create_subgroups = can?(current_user, :create_subgroup, @group)
- emails_disabled = @group.emails_disabled?
   
.group-home-panel .group-home-panel
.row.mb-3 .row.mb-3
Loading
@@ -21,7 +22,7 @@
Loading
@@ -21,7 +22,7 @@
.home-panel-buttons.col-md-12.col-lg-6.d-inline-flex.flex-wrap.justify-content-lg-end .home-panel-buttons.col-md-12.col-lg-6.d-inline-flex.flex-wrap.justify-content-lg-end
- if current_user - if current_user
.group-buttons .group-buttons
= render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn' = render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn', emails_disabled: emails_disabled
- if can? current_user, :create_projects, @group - if can? current_user, :create_projects, @group
- new_project_label = _("New project") - new_project_label = _("New project")
- new_subgroup_label = _("New subgroup") - new_subgroup_label = _("New subgroup")
Loading
Loading
Loading
@@ -11,12 +11,18 @@
Loading
@@ -11,12 +11,18 @@
.form-check .form-check
= f.check_box :share_with_group_lock, disabled: !can_change_share_with_group_lock?(@group), class: 'form-check-input' = f.check_box :share_with_group_lock, disabled: !can_change_share_with_group_lock?(@group), class: 'form-check-input'
= f.label :share_with_group_lock, class: 'form-check-label' do = f.label :share_with_group_lock, class: 'form-check-label' do
%span %span.d-block
- group_link = link_to @group.name, group_path(@group) - group_link = link_to @group.name, group_path(@group)
= s_('GroupSettings|Prevent sharing a project within %{group} with other groups').html_safe % { group: group_link } = s_('GroupSettings|Prevent sharing a project within %{group} with other groups').html_safe % { group: group_link }
%br
%span.descr.text-muted= share_with_group_lock_help_text(@group) %span.descr.text-muted= share_with_group_lock_help_text(@group)
   
.form-group.append-bottom-default
.form-check
= f.check_box :emails_disabled, checked: @group.emails_disabled?, disabled: !can_disable_group_emails?(@group), class: 'form-check-input'
= f.label :emails_disabled, class: 'form-check-label' do
%span.d-block= s_('GroupSettings|Disable email notifications')
%span.text-muted= s_('GroupSettings|This setting will override user notification preferences for all members of the group, subgroups, and projects.')
= render_if_exists 'groups/settings/ip_restriction', f: f, group: @group = render_if_exists 'groups/settings/ip_restriction', f: f, group: @group
= render 'groups/settings/lfs', f: f = render 'groups/settings/lfs', f: f
= render 'groups/settings/project_creation_level', f: f, group: @group = render 'groups/settings/project_creation_level', f: f, group: @group
Loading
Loading
- emails_disabled = group.emails_disabled?
.gl-responsive-table-row.notification-list-item .gl-responsive-table-row.notification-list-item
.table-section.section-40 .table-section.section-40
%span.notification.fa.fa-holder.append-right-5 %span.notification.fa.fa-holder.append-right-5
- if setting.global? = notification_icon(notification_icon_level(setting, emails_disabled))
= notification_icon(current_user.global_notification_setting.level)
- else
= notification_icon(setting.level)
   
%span.str-truncated %span.str-truncated
= link_to group.name, group_path(group) = link_to group.name, group_path(group)
   
.table-section.section-30.text-right .table-section.section-30.text-right
= render 'shared/notifications/button', notification_setting: setting = render 'shared/notifications/button', notification_setting: setting, emails_disabled: emails_disabled
   
.table-section.section-30 .table-section.section-30
= form_for @user.notification_settings.find { |ns| ns.source == group }, url: profile_notifications_group_path(group), method: :put, html: { class: 'update-notifications' } do |f| = form_for @user.notification_settings.find { |ns| ns.source == group }, url: profile_notifications_group_path(group), method: :put, html: { class: 'update-notifications' } do |f|
Loading
Loading
- emails_disabled = project.emails_disabled?
%li.notification-list-item %li.notification-list-item
%span.notification.fa.fa-holder.append-right-5 %span.notification.fa.fa-holder.append-right-5
- if setting.global? = notification_icon(notification_icon_level(setting, emails_disabled))
= notification_icon(current_user.global_notification_setting.level)
- else
= notification_icon(setting.level)
   
%span.str-truncated %span.str-truncated
= link_to_project(project) = link_to_project(project)
   
.float-right .float-right
= render 'shared/notifications/button', notification_setting: setting = render 'shared/notifications/button', notification_setting: setting, emails_disabled: emails_disabled
- empty_repo = @project.empty_repo? - empty_repo = @project.empty_repo?
- show_auto_devops_callout = show_auto_devops_callout?(@project) - show_auto_devops_callout = show_auto_devops_callout?(@project)
- max_project_topic_length = 15 - max_project_topic_length = 15
- emails_disabled = @project.emails_disabled?
.project-home-panel{ class: [("empty-project" if empty_repo), ("js-keep-hidden-on-navigation" if vue_file_list_enabled?)] } .project-home-panel{ class: [("empty-project" if empty_repo), ("js-keep-hidden-on-navigation" if vue_file_list_enabled?)] }
.row.append-bottom-8 .row.append-bottom-8
.home-panel-title-row.col-md-12.col-lg-6.d-flex .home-panel-title-row.col-md-12.col-lg-6.d-flex
Loading
@@ -41,7 +43,7 @@
Loading
@@ -41,7 +43,7 @@
.project-repo-buttons.col-md-12.col-lg-6.d-inline-flex.flex-wrap.justify-content-lg-end .project-repo-buttons.col-md-12.col-lg-6.d-inline-flex.flex-wrap.justify-content-lg-end
- if current_user - if current_user
.d-inline-flex .d-inline-flex
= render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn-xs' = render 'shared/notifications/new_button', notification_setting: @notification_setting, btn_class: 'btn-xs', emails_disabled: emails_disabled
   
.count-buttons.d-inline-flex .count-buttons.d-inline-flex
= render 'projects/buttons/star' = render 'projects/buttons/star'
Loading
Loading
Loading
@@ -137,7 +137,11 @@
Loading
@@ -137,7 +137,11 @@
.js-sidebar-participants-entry-point .js-sidebar-participants-entry-point
   
- if signed_in - if signed_in
.js-sidebar-subscriptions-entry-point - if issuable_sidebar[:project_emails_disabled]
.block.js-emails-disabled
= notification_description(:owner_disabled)
- else
.js-sidebar-subscriptions-entry-point
   
- project_ref = issuable_sidebar[:reference] - project_ref = issuable_sidebar[:reference]
.block.project-reference .block.project-reference
Loading
Loading
- btn_class = local_assigns.fetch(:btn_class, nil) - btn_class = local_assigns.fetch(:btn_class, '')
- emails_disabled = local_assigns.fetch(:emails_disabled, false)
   
- if notification_setting - if notification_setting
- if emails_disabled
- button_title = notification_description(:owner_disabled)
- aria_label = button_title
- btn_class << " disabled"
- else
- button_title = _("Notification setting")
- aria_label = _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }
.js-notification-dropdown.notification-dropdown.mr-md-2.home-panel-action-button.dropdown.inline .js-notification-dropdown.notification-dropdown.mr-md-2.home-panel-action-button.dropdown.inline
= form_for notification_setting, remote: true, html: { class: "inline notification-form" } do |f| = form_for notification_setting, remote: true, html: { class: "inline notification-form" } do |f|
= hidden_setting_source_input(notification_setting) = hidden_setting_source_input(notification_setting)
Loading
@@ -8,14 +17,14 @@
Loading
@@ -8,14 +17,14 @@
.js-notification-toggle-btns .js-notification-toggle-btns
%div{ class: ("btn-group" if notification_setting.custom?) } %div{ class: ("btn-group" if notification_setting.custom?) }
- if notification_setting.custom? - if notification_setting.custom?
%button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn.text-left#notifications-button{ type: "button", title: _("Notification setting"), class: "#{btn_class}", "aria-label" => _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }, data: { container: "body", toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } } %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn.text-left#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => aria_label, data: { container: "body", toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } }
= icon("bell", class: "js-notification-loading") = icon("bell", class: "js-notification-loading")
= notification_title(notification_setting.level) = notification_title(notification_setting.level)
%button.btn.dropdown-toggle{ data: { toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } } %button.btn.dropdown-toggle{ data: { toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
= icon('caret-down') = icon('caret-down')
.sr-only Toggle dropdown .sr-only Toggle dropdown
- else - else
%button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: _("Notification setting"), class: "#{btn_class}", "aria-label" => _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }, data: { container: "body", toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } } %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => aria_label, data: { container: "body", toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
.float-left .float-left
= icon("bell", class: "js-notification-loading") = icon("bell", class: "js-notification-loading")
= notification_title(notification_setting.level) = notification_title(notification_setting.level)
Loading
Loading
- btn_class = local_assigns.fetch(:btn_class, nil) - btn_class = local_assigns.fetch(:btn_class, '')
- emails_disabled = local_assigns.fetch(:emails_disabled, false)
   
- if notification_setting - if notification_setting
- if emails_disabled
- button_title = notification_description(:owner_disabled)
- btn_class << " disabled"
- else
- button_title = _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }
.js-notification-dropdown.notification-dropdown.home-panel-action-button.prepend-top-default.append-right-8.dropdown.inline .js-notification-dropdown.notification-dropdown.home-panel-action-button.prepend-top-default.append-right-8.dropdown.inline
= form_for notification_setting, remote: true, html: { class: "inline notification-form no-label" } do |f| = form_for notification_setting, remote: true, html: { class: "inline notification-form no-label" } do |f|
= hidden_setting_source_input(notification_setting) = hidden_setting_source_input(notification_setting)
Loading
@@ -9,14 +16,14 @@
Loading
@@ -9,14 +16,14 @@
.js-notification-toggle-btns .js-notification-toggle-btns
%div{ class: ("btn-group" if notification_setting.custom?) } %div{ class: ("btn-group" if notification_setting.custom?) }
- if notification_setting.custom? - if notification_setting.custom?
%button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }, class: "#{btn_class}", "aria-label" => _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }, data: { container: "body", placement: 'top', toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } } %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => button_title, data: { container: "body", placement: 'top', toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } }
= notification_setting_icon(notification_setting) = notification_setting_icon(notification_setting)
%span.js-notification-loading.fa.hidden %span.js-notification-loading.fa.hidden
%button.btn.dropdown-toggle{ data: { toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" }, class: "#{btn_class}" } %button.btn.dropdown-toggle{ data: { toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" }, class: "#{btn_class}" }
= sprite_icon("arrow-down", css_class: "icon mr-0") = sprite_icon("arrow-down", css_class: "icon mr-0")
.sr-only Toggle dropdown .sr-only Toggle dropdown
- else - else
%button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }, class: "#{btn_class}", "aria-label" => _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }, data: { container: "body", placement: 'top', toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } } %button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: button_title, class: "#{btn_class}", "aria-label" => button_title, data: { container: "body", placement: 'top', toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
= notification_setting_icon(notification_setting) = notification_setting_icon(notification_setting)
%span.js-notification-loading.fa.hidden %span.js-notification-loading.fa.hidden
= sprite_icon("arrow-down", css_class: "icon") = sprite_icon("arrow-down", css_class: "icon")
Loading
Loading
---
title: UI for disabling group/project email notifications
merge_request: 30961
author: Dustin Spicuzza
type: added
Loading
@@ -379,6 +379,17 @@ To enable this feature, navigate to the group settings page, expand the
Loading
@@ -379,6 +379,17 @@ To enable this feature, navigate to the group settings page, expand the
Define project templates at a group level by setting a group as the template source. Define project templates at a group level by setting a group as the template source.
[Learn more about group-level project templates](custom_project_templates.md). [Learn more about group-level project templates](custom_project_templates.md).
   
#### Disabling email notifications
You can disable all email notifications related to the group, which also includes
it's subgroups and projects.
To enable this feature:
1. Navigate to the group's **Settings > General** page.
1. Expand the **Permissions, LFS, 2FA** section, and select **Disable email notifications**.
1. Click **Save changes**.
### Advanced settings ### Advanced settings
   
- **Projects**: View all projects within that group, add members to each project, - **Projects**: View all projects within that group, add members to each project,
Loading
Loading
Loading
@@ -125,6 +125,7 @@ The following table depicts the various user permission levels in a project.
Loading
@@ -125,6 +125,7 @@ The following table depicts the various user permission levels in a project.
| Transfer project to another namespace | | | | | ✓ | | Transfer project to another namespace | | | | | ✓ |
| Remove project | | | | | ✓ | | Remove project | | | | | ✓ |
| Delete issues | | | | | ✓ | | Delete issues | | | | | ✓ |
| Disable notification emails | | | | | ✓ |
| Force push to protected branches (*4*) | | | | | | | Force push to protected branches (*4*) | | | | | |
| Remove protected branches (*4*) | | | | | | | Remove protected branches (*4*) | | | | | |
   
Loading
@@ -219,6 +220,7 @@ group.
Loading
@@ -219,6 +220,7 @@ group.
| Remove group | | | | | ✓ | | Remove group | | | | | ✓ |
| Delete group epic **(ULTIMATE)** | | | | | ✓ | | Delete group epic **(ULTIMATE)** | | | | | ✓ |
| View group Audit Events | | | | | ✓ | | View group Audit Events | | | | | ✓ |
| Disable notification emails | | | | | ✓ |
   
- (1): Groups can be set to [allow either Owners or Owners and - (1): Groups can be set to [allow either Owners or Owners and
Maintainers to create subgroups](group/subgroups/index.md#creating-a-subgroup) Maintainers to create subgroups](group/subgroups/index.md#creating-a-subgroup)
Loading
Loading
Loading
@@ -32,6 +32,12 @@ links will be missing from the sidebar UI.
Loading
@@ -32,6 +32,12 @@ links will be missing from the sidebar UI.
You can still access them with direct links if you can access Merge Requests. This is deliberate, if you can see You can still access them with direct links if you can access Merge Requests. This is deliberate, if you can see
Issues or Merge Requests, both of which use Labels and Milestones, then you shouldn't be denied access to Labels and Milestones pages. Issues or Merge Requests, both of which use Labels and Milestones, then you shouldn't be denied access to Labels and Milestones pages.
   
#### Disabling email notifications
You can disable all email notifications related to the project by selecting the
**Disable email notifications** checkbox. Only the project owner is allowed to change
this setting.
### Issue settings ### Issue settings
   
Add an [issue description template](../description_templates.md#description-templates) to your project, so that every new issue will start with a custom template. Add an [issue description template](../description_templates.md#description-templates) to your project, so that every new issue will start with a custom template.
Loading
Loading
Loading
@@ -51,6 +51,10 @@ Organization like this is suitable for users that belong to different groups but
Loading
@@ -51,6 +51,10 @@ Organization like this is suitable for users that belong to different groups but
same need for being notified for every group they are member of. same need for being notified for every group they are member of.
These settings can be configured on group page under the name of the group. It will be the dropdown with the bell icon. They can also be configured on the user profile notifications dropdown. These settings can be configured on group page under the name of the group. It will be the dropdown with the bell icon. They can also be configured on the user profile notifications dropdown.
   
The group owner can disable email notifications for a group, which also includes
it's subgroups and projects. If this is the case, you will not receive any corresponding notifications,
and the notification button will be disabled with an explanatory tooltip.
### Project Settings ### Project Settings
   
![notification settings](img/notification_project_settings.png) ![notification settings](img/notification_project_settings.png)
Loading
@@ -60,6 +64,10 @@ other setting.
Loading
@@ -60,6 +64,10 @@ other setting.
This is suitable for users that have different needs for notifications per project basis. This is suitable for users that have different needs for notifications per project basis.
These settings can be configured on project page under the name of the project. It will be the dropdown with the bell icon. They can also be configured on the user profile notifications dropdown. These settings can be configured on project page under the name of the project. It will be the dropdown with the bell icon. They can also be configured on the user profile notifications dropdown.
   
The project owner (or it's group owner) can disable email notifications for the project.
If this is the case, you will not receive any corresponding notifications, and the notification
button will be disabled with an explanatory tooltip.
## Notification events ## Notification events
   
Below is the table of events users can be notified of: Below is the table of events users can be notified of:
Loading
Loading
Loading
@@ -3932,6 +3932,9 @@ msgstr ""
Loading
@@ -3932,6 +3932,9 @@ msgstr ""
msgid "Disable" msgid "Disable"
msgstr "" msgstr ""
   
msgid "Disable email notifications"
msgstr ""
msgid "Disable for this project" msgid "Disable for this project"
msgstr "" msgstr ""
   
Loading
@@ -5440,6 +5443,9 @@ msgstr ""
Loading
@@ -5440,6 +5443,9 @@ msgstr ""
msgid "GroupSettings|Default to Auto DevOps pipeline for all projects within this group" msgid "GroupSettings|Default to Auto DevOps pipeline for all projects within this group"
msgstr "" msgstr ""
   
msgid "GroupSettings|Disable email notifications"
msgstr ""
msgid "GroupSettings|Learn more about badges." msgid "GroupSettings|Learn more about badges."
msgstr "" msgstr ""
   
Loading
@@ -5467,6 +5473,9 @@ msgstr ""
Loading
@@ -5467,6 +5473,9 @@ msgstr ""
msgid "GroupSettings|This setting will be applied to all subgroups unless overridden by a group owner. Groups that already have access to the project will continue to have access unless removed manually." msgid "GroupSettings|This setting will be applied to all subgroups unless overridden by a group owner. Groups that already have access to the project will continue to have access unless removed manually."
msgstr "" msgstr ""
   
msgid "GroupSettings|This setting will override user notification preferences for all members of the group, subgroups, and projects."
msgstr ""
msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group" msgid "GroupSettings|cannot be disabled when the parent group \"Share with group lock\" is enabled, except by the owner of the parent group"
msgstr "" msgstr ""
   
Loading
@@ -7548,6 +7557,9 @@ msgstr ""
Loading
@@ -7548,6 +7557,9 @@ msgstr ""
msgid "Notifications" msgid "Notifications"
msgstr "" msgstr ""
   
msgid "Notifications have been disabled by the project or group owner"
msgstr ""
msgid "Notifications off" msgid "Notifications off"
msgstr "" msgstr ""
   
Loading
@@ -11608,6 +11620,9 @@ msgstr ""
Loading
@@ -11608,6 +11620,9 @@ msgstr ""
msgid "This setting can be overridden in each project." msgid "This setting can be overridden in each project."
msgstr "" msgstr ""
   
msgid "This setting will override user notification preferences for all project members."
msgstr ""
msgid "This setting will update the hostname that is used to generate private commit emails. %{learn_more}" msgid "This setting will update the hostname that is used to generate private commit emails. %{learn_more}"
msgstr "" msgstr ""
   
Loading
Loading
Loading
@@ -161,4 +161,27 @@ describe 'Group show page' do
Loading
@@ -161,4 +161,27 @@ describe 'Group show page' do
expect(find('.group-row:nth-child(3) .namespace-title > a')).to have_content(project3.title) expect(find('.group-row:nth-child(3) .namespace-title > a')).to have_content(project3.title)
end end
end end
context 'notification button', :js do
let(:maintainer) { create(:user) }
let!(:project) { create(:project, namespace: group) }
before do
group.add_maintainer(maintainer)
sign_in(maintainer)
end
it 'is enabled by default' do
visit path
expect(page).to have_selector('.notifications-btn:not(.disabled)', visible: true)
end
it 'is disabled if emails are disabled' do
group.update_attribute(:emails_disabled, true)
visit path
expect(page).to have_selector('.notifications-btn.disabled', visible: true)
end
end
end end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment