Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gitlab-ce
Commits
f82ab42d
Commit
f82ab42d
authored
Jun 14, 2016
by
Felipe Artur
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Re-use notifications dropdown on user profile
parent
5c45d593
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
361 additions
and
172 deletions
+361
-172
app/assets/javascripts/dispatcher.js.coffee
app/assets/javascripts/dispatcher.js.coffee
+3
-0
app/assets/javascripts/notifications_dropdown.js.coffee
app/assets/javascripts/notifications_dropdown.js.coffee
+21
-0
app/assets/javascripts/notifications_form.js.coffee
app/assets/javascripts/notifications_form.js.coffee
+7
-6
app/assets/javascripts/profile.js.coffee
app/assets/javascripts/profile.js.coffee
+4
-0
app/assets/javascripts/project.js.coffee
app/assets/javascripts/project.js.coffee
+0
-21
app/controllers/groups/notification_settings_controller.rb
app/controllers/groups/notification_settings_controller.rb
+0
-16
app/controllers/notification_settings_controller.rb
app/controllers/notification_settings_controller.rb
+34
-0
app/controllers/profiles/notifications_controller.rb
app/controllers/profiles/notifications_controller.rb
+3
-15
app/helpers/notifications_helper.rb
app/helpers/notifications_helper.rb
+8
-16
app/services/notification_service.rb
app/services/notification_service.rb
+24
-6
app/views/notifications/buttons/_notifications.html.haml
app/views/notifications/buttons/_notifications.html.haml
+25
-0
app/views/profiles/notifications/_group_settings.html.haml
app/views/profiles/notifications/_group_settings.html.haml
+1
-2
app/views/profiles/notifications/_project_settings.html.haml
app/views/profiles/notifications/_project_settings.html.haml
+1
-2
app/views/profiles/notifications/show.html.haml
app/views/profiles/notifications/show.html.haml
+5
-5
app/views/projects/_home_panel.html.haml
app/views/projects/_home_panel.html.haml
+1
-1
app/views/projects/buttons/_notifications.html.haml
app/views/projects/buttons/_notifications.html.haml
+0
-21
app/views/shared/notifications/_custom_notifications.html.haml
...iews/shared/notifications/_custom_notifications.html.haml
+5
-4
app/views/shared/notifications/_notification_dropdown.html.haml
...ews/shared/notifications/_notification_dropdown.html.haml
+12
-0
app/views/shared/projects/_notification_dropdown.html.haml
app/views/shared/projects/_notification_dropdown.html.haml
+0
-9
config/routes.rb
config/routes.rb
+8
-2
spec/controllers/groups/notification_settings_controller_spec.rb
...ntrollers/groups/notification_settings_controller_spec.rb
+0
-32
spec/controllers/notification_settings_controller_spec.rb
spec/controllers/notification_settings_controller_spec.rb
+125
-0
spec/services/notification_service_spec.rb
spec/services/notification_service_spec.rb
+74
-14
No files found.
app/assets/javascripts/dispatcher.js.coffee
View file @
f82ab42d
...
...
@@ -126,6 +126,8 @@ class Dispatcher
shortcut_handler
=
new
ShortcutsDashboardNavigation
()
when
'profiles'
new
Profile
()
new
NotificationsForm
()
new
NotificationsDropdown
()
when
'projects'
new
Project
()
new
ProjectAvatar
()
...
...
@@ -139,6 +141,7 @@ class Dispatcher
new
ProjectNew
()
when
'show'
new
ProjectShow
()
new
NotificationsDropdown
()
when
'wikis'
new
Wikis
()
shortcut_handler
=
new
ShortcutsNavigation
()
...
...
app/assets/javascripts/notifications_dropdown.js.coffee
0 → 100644
View file @
f82ab42d
class
@
NotificationsDropdown
$
->
$
(
document
)
.
off
'click'
,
'.update-notification'
.
on
'click'
,
'.update-notification'
,
(
e
)
->
e
.
preventDefault
()
notificationLevel
=
$
(
@
).
data
'notification-level'
label
=
$
(
@
).
data
'notification-title'
form
=
$
(
this
).
parents
(
'form:first'
)
form
.
find
(
'.js-notification-loading'
).
toggleClass
'fa-bell fa-spin fa-spinner'
form
.
find
(
'#notification_setting_level'
).
val
(
notificationLevel
)
form
.
submit
();
$
(
document
)
.
off
'ajax:success'
,
'#notification-form'
.
on
'ajax:success'
,
'#notification-form'
,
(
e
,
data
)
->
if
data
.
saved
new
Flash
(
'Notification settings saved'
,
'notice'
)
$
(
e
.
currentTarget
).
closest
(
'.notification-dropdown'
).
replaceWith
(
data
.
html
)
else
new
Flash
(
'Failed to save new settings'
,
'alert'
)
app/assets/javascripts/notifications_form.js.coffee
View file @
f82ab42d
class
@
NotificationsForm
constructor
:
->
@
form
=
$
(
'.custom-notifications-form'
)
@
removeEventListeners
()
@
initEventListeners
()
...
...
@@ -14,7 +12,7 @@ class @NotificationsForm
toggleCheckbox
:
(
e
)
=>
$checkbox
=
$
(
e
.
currentTarget
)
$parent
=
$checkbox
.
closest
(
'.checkbox'
)
console
.
log
(
$parent
)
@
saveEvent
(
$checkbox
,
$parent
)
showCheckboxLoadingSpinner
:
(
$parent
)
->
...
...
@@ -26,11 +24,14 @@ class @NotificationsForm
.
removeClass
'is-done'
saveEvent
:
(
$checkbox
,
$parent
)
->
form
=
$parent
.
parents
(
'form:first'
)
console
.
log
(
form
)
$
.
ajax
(
url
:
@
form
.
attr
(
'action'
)
method
:
'patch'
url
:
form
.
attr
(
'action'
)
method
:
form
.
attr
(
'method'
)
dataType
:
'json'
data
:
@
form
.
serialize
()
data
:
form
.
serialize
()
beforeSend
:
=>
@
showCheckboxLoadingSpinner
(
$parent
)
).
done
(
data
)
->
...
...
app/assets/javascripts/profile.js.coffee
View file @
f82ab42d
...
...
@@ -8,6 +8,10 @@ class @Profile
$
(
'.js-preferences-form'
).
on
'change.preference'
,
'input[type=radio]'
,
->
$
(
this
).
parents
(
'form'
).
submit
()
# Automatically submit email form when it changes
$
(
'#user_notification_email'
).
on
'change'
,
->
$
(
this
).
parents
(
'form'
).
submit
()
$
(
'.update-username'
).
on
'ajax:before'
,
->
$
(
'.loading-username'
).
show
()
$
(
this
).
find
(
'.update-success'
).
hide
()
...
...
app/assets/javascripts/project.js.coffee
View file @
f82ab42d
...
...
@@ -34,27 +34,6 @@ class @Project
$
(
@
).
parents
(
'.no-password-message'
).
remove
()
e
.
preventDefault
()
$
(
document
)
.
off
'click'
,
'.update-notification'
.
on
'click'
,
'.update-notification'
,
(
e
)
->
e
.
preventDefault
()
notificationLevel
=
$
(
@
).
data
'notification-level'
label
=
$
(
@
).
data
'notification-title'
$
(
'.js-notification-loading'
).
toggleClass
'fa-bell fa-spin fa-spinner'
$
(
'#notification_setting_level'
).
val
(
notificationLevel
)
$
(
'#notification-form'
).
submit
()
$
(
document
)
.
off
'ajax:success'
,
'#notification-form'
.
on
'ajax:success'
,
'#notification-form'
,
(
e
,
data
)
->
if
data
.
saved
new
Flash
(
'Notification settings saved'
,
'notice'
)
$
(
'.js-notification-toggle-btns'
)
.
closest
(
'.notification-dropdown'
)
.
replaceWith
(
data
.
html
)
else
new
Flash
(
'Failed to save new settings'
,
'alert'
)
@
projectSelectDropdown
()
...
...
app/controllers/groups/notification_settings_controller.rb
deleted
100644 → 0
View file @
5c45d593
class
Groups::NotificationSettingsController
<
Groups
::
ApplicationController
before_action
:authenticate_user!
def
update
notification_setting
=
current_user
.
notification_settings_for
(
group
)
saved
=
notification_setting
.
update_attributes
(
notification_setting_params
)
render
json:
{
saved:
saved
}
end
private
def
notification_setting_params
params
.
require
(
:notification_setting
).
permit
(
:level
)
end
end
app/controllers/
projects/
notification_settings_controller.rb
→
app/controllers/notification_settings_controller.rb
View file @
f82ab42d
class
Projects::NotificationSettingsController
<
Projects
::
ApplicationController
class
NotificationSettingsController
<
ApplicationController
before_action
:authenticate_user!
def
update
def
create
project
=
current_user
.
projects
.
find
(
params
[
:project
][
:id
])
@notification_setting
=
current_user
.
notification_settings_for
(
project
)
saved
=
@notification_setting
.
update_attributes
(
notification_setting_params
)
@
saved
=
@notification_setting
.
update_attributes
(
notification_setting_params
)
render
json:
{
html:
view_to_html_string
(
"projects/buttons/_notifications"
,
locals:
{
project:
@project
,
notification_setting:
@notification_setting
}),
saved:
saved
}
render_response
end
def
update
@notification_setting
=
current_user
.
notification_settings
.
find
(
params
[
:id
])
@saved
=
@notification_setting
.
update_attributes
(
notification_setting_params
)
render_response
end
private
def
render_response
render
json:
{
html:
view_to_html_string
(
"notifications/buttons/_notifications"
,
notification_setting:
@notification_setting
),
saved:
@saved
}
end
def
notification_setting_params
allowed_fields
=
NotificationSetting
::
EMAIL_EVENTS
.
dup
allowed_fields
<<
:level
...
...
app/controllers/profiles/notifications_controller.rb
View file @
f82ab42d
class
Profiles::NotificationsController
<
Profiles
::
ApplicationController
def
show
@user
=
current_user
@group_notifications
=
current_user
.
notification_settings
.
for_groups
@project_notifications
=
current_user
.
notification_settings
.
for_projects
@group_notifications
=
current_user
.
notification_settings
.
for_groups
.
order
(
:id
)
@project_notifications
=
current_user
.
notification_settings
.
for_projects
.
order
(
:id
)
@global_notification_setting
=
current_user
.
global_notification_setting
end
def
update
if
current_user
.
update_attributes
(
user_params
)
&&
update_notification_settings
if
current_user
.
update_attributes
(
user_params
)
flash
[
:notice
]
=
"Notification settings saved"
else
flash
[
:alert
]
=
"Failed to save new settings"
...
...
@@ -19,16 +19,4 @@ class Profiles::NotificationsController < Profiles::ApplicationController
def
user_params
params
.
require
(
:user
).
permit
(
:notification_email
)
end
def
global_notification_setting_params
params
.
require
(
:global_notification_setting
).
permit
(
:level
)
end
private
def
update_notification_settings
return
true
unless
global_notification_setting_params
current_user
.
global_notification_setting
.
update_attributes
(
global_notification_setting_params
)
end
end
app/helpers/notifications_helper.rb
View file @
f82ab42d
...
...
@@ -62,22 +62,14 @@ module NotificationsHelper
end
end
def
notification_level_radio_buttons
html
=
""
NotificationSetting
.
levels
.
each_key
do
|
level
|
level
=
level
.
to_sym
next
if
level
==
:global
html
<<
content_tag
(
:div
,
class:
"radio"
)
do
content_tag
(
:label
,
{
value:
level
})
do
radio_button_tag
(
:"global_notification_setting[level]"
,
level
,
@global_notification_setting
.
level
.
to_sym
==
level
)
+
content_tag
(
:div
,
level
.
to_s
.
capitalize
,
class:
"level-title"
)
+
content_tag
(
:p
,
notification_description
(
level
))
end
end
end
# Identifier to trigger individually dropdowns and custom settings modals in the same view
def
notifications_menu_identifier
(
type
,
notification_setting
)
"
#{
type
}
-
#{
notification_setting
.
user_id
}
-
#{
notification_setting
.
source_id
}
-
#{
notification_setting
.
source_type
}
"
end
html
.
html_safe
# Create hidden field to send notification setting source to controller
def
hidden_setting_source_input
(
notification_setting
)
return
unless
notification_setting
.
source_type
hidden_field_tag
"
#{
notification_setting
.
source_type
.
downcase
}
[id]"
,
notification_setting
.
source_id
end
end
app/services/notification_service.rb
View file @
f82ab42d
...
...
@@ -159,7 +159,7 @@ class NotificationService
recipients
=
add_project_watchers
(
recipients
,
note
.
project
)
# Merge project with custom notification
recipients
=
add_
project_
custom_notifications
(
recipients
,
note
.
project
,
:new_note
)
recipients
=
add_custom_notifications
(
recipients
,
note
.
project
,
:new_note
)
# Reject users with Mention notification level, except those mentioned in _this_ note.
recipients
=
reject_mention_users
(
recipients
-
mentioned_users
,
note
.
project
)
...
...
@@ -257,12 +257,20 @@ class NotificationService
protected
# Get project/group users with CUSTOM notification level
def
add_
project_
custom_notifications
(
recipients
,
project
,
action
)
def
add_custom_notifications
(
recipients
,
project
,
action
)
user_ids
=
[]
# Users with a notification setting on group or project
user_ids
+=
notification_settings_for
(
project
,
:custom
,
action
)
user_ids
+=
notification_settings_for
(
project
.
group
,
:custom
,
action
)
# Users with global level custom
users_with_project_level_global
=
notification_settings_for
(
project
,
:global
)
users_with_group_level_global
=
notification_settings_for
(
project
.
group
,
:global
)
global_users_ids
=
users_with_project_level_global
.
concat
(
users_with_group_level_global
)
user_ids
+=
users_with_global_level_custom
(
global_users_ids
,
action
)
recipients
.
concat
(
User
.
find
(
user_ids
))
end
...
...
@@ -271,7 +279,7 @@ class NotificationService
project_members
=
notification_settings_for
(
project
)
users_with_project_level_global
=
notification_settings_for
(
project
,
:global
)
users_with_group_level_global
=
notification_settings_for
(
project
,
:global
)
users_with_group_level_global
=
notification_settings_for
(
project
.
group
,
:global
)
users
=
users_with_global_level_watch
([
users_with_project_level_global
,
users_with_group_level_global
].
flatten
.
uniq
)
users_with_project_setting
=
select_project_member_setting
(
project
,
users_with_project_level_global
,
users
)
...
...
@@ -293,11 +301,21 @@ class NotificationService
end
def
users_with_global_level_watch
(
ids
)
settings_with_global_level_of
(
:watch
,
ids
).
pluck
(
:user_id
)
end
def
users_with_global_level_custom
(
ids
,
action
)
settings
=
settings_with_global_level_of
(
:custom
,
ids
)
settings
=
settings
.
select
{
|
setting
|
setting
.
events
[
action
]
}
settings
.
map
(
&
:user_id
)
end
def
settings_with_global_level_of
(
level
,
ids
)
NotificationSetting
.
where
(
user_id:
ids
,
source_type:
nil
,
level:
NotificationSetting
.
levels
[
:watch
]
)
.
pluck
(
:user_id
)
level:
NotificationSetting
.
levels
[
level
]
)
end
# Build a list of users based on project notifcation settings
...
...
@@ -477,7 +495,7 @@ class NotificationService
recipients
=
target
.
participants
(
current_user
)
recipients
=
add_project_watchers
(
recipients
,
project
)
recipients
=
add_
project_
custom_notifications
(
recipients
,
project
,
custom_action
)
recipients
=
add_custom_notifications
(
recipients
,
project
,
custom_action
)
recipients
=
reject_mention_users
(
recipients
,
project
)
recipients
=
recipients
.
uniq
...
...
app/views/notifications/buttons/_notifications.html.haml
0 → 100644
View file @
f82ab42d
-
if
notification_setting
.dropdown.notification-dropdown.pull-right
-
url
=
notification_setting
.
persisted?
?
notification_setting_path
(
notification_setting
)
:
notification_settings_path
(
notification_setting
)
=
form_for
notification_setting
,
remote:
true
,
html:
{
class:
"inline"
,
id:
"notification-form"
}
do
|
f
|
=
hidden_setting_source_input
(
notification_setting
)
=
f
.
hidden_field
:level
,
class:
"notification_setting_level"
.js-notification-toggle-btns
.btn-group
-
if
notification_setting
.
level
!=
"custom"
%button
.dropdown-new.btn.btn-default.notifications-btn
#notifications-button
{
type:
"button"
,
data:
{
toggle:
"dropdown"
,
target:
notifications_menu_identifier
(
"dropdown"
,
notification_setting
)
}
}
=
icon
(
"bell"
,
class:
"js-notification-loading"
)
=
notification_title
(
notification_setting
.
level
)
=
icon
(
"caret-down"
)
-
else
%button
.dropdown-new.btn.btn-default.notifications-btn
#notifications-button
{
type:
"button"
,
data:
{
toggle:
"modal"
,
target:
"#"
+
notifications_menu_identifier
(
"modal"
,
notification_setting
)
}
}
=
icon
(
"bell"
,
class:
"js-notification-loading"
)
=
notification_title
(
notification_setting
.
level
)
%button
.btn.btn-danger.dropdown-toggle
{
data:
{
toggle:
"dropdown"
,
target:
notifications_menu_identifier
(
"dropdown"
,
notification_setting
)
}
}
%span
.caret
.sr-only
Toggle dropdown
=
render
"shared/notifications/notification_dropdown"
,
notification_setting:
notification_setting
=
content_for
:scripts_body
do
=
render
"shared/notifications/custom_notifications"
,
notification_setting:
notification_setting
app/views/profiles/notifications/_group_settings.html.haml
View file @
f82ab42d
...
...
@@ -9,5 +9,4 @@
=
link_to
group
.
name
,
group_path
(
group
)
.pull-right
=
form_for
[
group
,
setting
],
remote:
true
,
html:
{
class:
'update-notifications'
}
do
|
f
|
=
f
.
select
:level
,
NotificationSetting
.
levels
.
keys
,
{},
class:
'form-control trigger-submit'
=
render
'notifications/buttons/notifications'
,
notification_setting:
setting
app/views/profiles/notifications/_project_settings.html.haml
View file @
f82ab42d
...
...
@@ -9,5 +9,4 @@
=
link_to_project
(
project
)
.pull-right
=
form_for
[
project
.
namespace
.
becomes
(
Namespace
),
project
,
setting
],
remote:
true
,
html:
{
class:
'update-notifications'
}
do
|
f
|
=
f
.
select
:level
,
NotificationSetting
.
levels
.
keys
,
{},
class:
'form-control trigger-submit'
=
render
'notifications/buttons/notifications'
,
notification_setting:
setting
app/views/profiles/notifications/show.html.haml
View file @
f82ab42d
...
...
@@ -24,12 +24,12 @@
.form-group
=
f
.
label
:notification_email
,
class:
"label-light"
=
f
.
select
:notification_email
,
@user
.
all_emails
,
{
include_blank:
false
},
class:
"select2"
.form-group
=
f
.
label
:notification_level
,
class:
'label-light'
=
notification_level_radio_buttons
.prepend-top-default
=
f
.
submit
'Update settings'
,
class:
"btn btn-create"
.form-group.pull-left
=
render
'notifications/buttons/notifications'
,
notification_setting:
@global_notification_setting
.clearfix
%hr
%h5
Groups (
#{
@group_notifications
.
count
}
)
...
...
app/views/projects/_home_panel.html.haml
View file @
f82ab42d
...
...
@@ -32,7 +32,7 @@
.project-repo-buttons.btn-group.project-right-buttons
=
render
"projects/buttons/download"
=
render
'projects/buttons/dropdown'
=
render
'
projects/buttons/notifications'
=
render
'
notifications/buttons/notifications'
,
notification_setting:
@notification_setting
:javascript
new
Star
();
app/views/projects/buttons/_notifications.html.haml
deleted
100644 → 0
View file @
5c45d593
-
if
@notification_setting
.dropdown.notification-dropdown.pull-right
=
form_for
@notification_setting
,
url:
namespace_project_notification_setting_path
(
@project
.
namespace
.
becomes
(
Namespace
),
@project
),
method: :patch
,
remote:
true
,
html:
{
class:
"inline"
,
id:
"notification-form"
}
do
|
f
|
=
f
.
hidden_field
:level
.js-notification-toggle-btns
-
if
@notification_setting
.
level
!=
"custom"
%button
.dropdown-new.btn.btn-default.notifications-btn
#notifications-button
{
type:
"button"
,
data:
{
toggle:
"dropdown"
,
target:
".notification-dropdown"
}
}
=
icon
(
"bell"
,
class:
"js-notification-loading"
)
=
notification_title
(
@notification_setting
.
level
)
=
icon
(
"caret-down"
)
-
else
.btn-group
%button
.dropdown-new.btn.btn-default.notifications-btn
#notifications-button
{
type:
"button"
,
data:
{
toggle:
"modal"
,
target:
"#custom-notifications-modal"
}
}
=
icon
(
"bell"
,
class:
"js-notification-loading"
)
=
notification_title
(
@notification_setting
.
level
)
%button
.btn.btn-danger.dropdown-toggle
{
data:
{
toggle:
"dropdown"
,
target:
".notification-dropdown"
}
}
%span
.caret
.sr-only
Toggle dropdown
=
render
"shared/projects/notification_dropdown"
=
content_for
:scripts_body
do
=
render
"shared/projects/custom_notifications"
app/views/shared/
project
s/_custom_notifications.html.haml
→
app/views/shared/
notification
s/_custom_notifications.html.haml
View file @
f82ab42d
#custom-notifications-modal
.modal.fade
{
tabindex:
"-1"
,
role:
"dialog"
,
aria:
{
labelledby:
"custom-notifications-title"
}
}
.modal.fade
{
tabindex:
"-1"
,
role:
"dialog"
,
id:
notifications_menu_identifier
(
"modal"
,
notification_setting
)
,
aria:
{
labelledby:
"custom-notifications-title"
}
}
.modal-dialog
.modal-content
.modal-header
...
...
@@ -6,10 +6,11 @@
%span
{
aria:
{
hidden:
"true"
}
}
×
%h4
#custom-notifications-title
.modal-title
Custom notification events
.modal-body
.container-fluid
=
form_for
@notification_setting
,
url:
namespace_project_notification_setting_path
(
@project
.
namespace
.
becomes
(
Namespace
),
@project
),
method: :patch
,
html:
{
class:
"custom-notifications-form"
}
do
|
f
|
=
f
.
hidden_field
:level
=
form_for
notification_setting
,
html:
{
class:
"custom-notifications-form"
}
do
|
f
|
=
hidden_setting_source_input
(
notification_setting
)
.row
.col-lg-3
%h4
.prepend-top-0
...
...
@@ -20,7 +21,7 @@
.form-group
.checkbox
{
class:
(
"prepend-top-0"
if
index
==
0
)
}
%label
{
for:
"events_#{event}"
}
=
check_box
(
"
notification_setting"
,
event
,
{
id:
"events_
#{
event
}
"
,
class:
"js-custom-notification-event"
})
=
check_box
(
"
"
,
event
,
{
name:
"notification_setting[
#{
event
}
]"
,
class:
"js-custom-notification-event"
,
checked:
notification_setting
.
events
[
event
]
})
%strong
=
event
.
to_s
.
humanize
...
...
app/views/shared/notifications/_notification_dropdown.html.haml
0 → 100644
View file @
f82ab42d
%ul
.dropdown-menu.dropdown-menu-no-wrap.dropdown-menu-align-right.dropdown-menu-selectable.dropdown-menu-large
{
role:
"menu"
,
class:
notifications_menu_identifier
(
"dropdown"
,
notification_setting
)
}
-
NotificationSetting
.
levels
.
each_key
do
|
level
|
-
next
if
level
==
"custom"
-
next
if
level
==
"global"
&&
notification_setting
.
source
.
nil?
=
notification_list_item
(
level
,
notification_setting
)
-
unless
notification_setting
.
custom?
%li
.divider
%li
%a
.update-notification
{
href:
"#"
,
role:
"button"
,
data:
{
toggle:
"modal"
,
target:
"#"
+
notifications_menu_identifier
(
"modal"
,
notification_setting
),
notification_level:
"custom"
,
notification_title:
"Custom"
}
}
Custom
app/views/shared/projects/_notification_dropdown.html.haml
deleted
100644 → 0
View file @
5c45d593
%ul
.dropdown-menu.dropdown-menu-no-wrap.dropdown-menu-align-right.dropdown-menu-selectable.dropdown-menu-large
{
role:
"menu"
}
-
NotificationSetting
.
levels
.
each
do
|
level
|
-
if
level
.
first
!=
"custom"
=
notification_list_item
(
level
.
first
,
@notification_setting
)
-
if
@notification_setting
.
level
!=
"custom"
%li
.divider
%li
%a
.update-notification
{
href:
"#"
,
role:
"button"
,
data:
{
toggle:
"modal"
,
target:
"#custom-notifications-modal"
,
notification_level:
"custom"
,
notification_title:
"Custom"
}
}
Custom
config/routes.rb
View file @
f82ab42d
...
...
@@ -118,9 +118,17 @@ Rails.application.routes.draw do
end
end
#
# Spam reports
#
resources
:abuse_reports
,
only:
[
:new
,
:create
]
#
# Notification settings
#
resources
:notification_settings
,
only:
[
:create
,
:update
]
#
# Import
#
...
...
@@ -416,7 +424,6 @@ Rails.application.routes.draw do
resource
:avatar
,
only:
[
:destroy
]
resources
:milestones
,
constraints:
{
id:
/[^\/]+/
},
only:
[
:index
,
:show
,
:update
,
:new
,
:create
]
resource
:notification_setting
,
only:
[
:update
]
end
end
...
...
@@ -648,7 +655,6 @@ Rails.application.routes.draw do
resources
:forks
,
only:
[
:index
,
:new
,
:create
]
resource
:import
,
only:
[
:new
,
:create
,
:show
]
resource
:notification_setting
,
only:
[
:update
]
resources
:refs
,
only:
[]
do
collection
do
...
...
spec/controllers/groups/notification_settings_controller_spec.rb
deleted
100644 → 0
View file @
5c45d593
require
'spec_helper'
describe
Groups
::
NotificationSettingsController
do
let
(
:group
)
{
create
(
:group
)
}
let
(
:user
)
{
create
(
:user
)
}
describe
'#update'
do
context
'when not authorized'
do
it
'redirects to sign in page'
do
put
:update
,
group_id:
group
.
to_param
,
notification_setting:
{
level: :participating
}
expect
(
response
).
to
redirect_to
(
new_user_session_path
)
end
end
context
'when authorized'
do
before
do
sign_in
(
user
)
end
it
'returns success'
do
put
:update
,
group_id:
group
.
to_param
,
notification_setting:
{
level: :participating
}
expect
(
response
.
status
).
to
eq
200
end
end
end
end
spec/controllers/
projects/
notification_settings_controller_spec.rb
→
spec/controllers/notification_settings_controller_spec.rb
View file @
f82ab42d
require
'spec_helper'
describe
Projects
::
NotificationSettingsController
do
describe
NotificationSettingsController
do
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:user
)
{
create
(
:user
)
}
...
...
@@ -8,13 +8,12 @@ describe Projects::NotificationSettingsController do
project
.
team
<<
[
user
,
:developer
]
end
describe
'#
upd
ate'
do
describe
'#
cre
ate'
do
context
'when not authorized'
do
it
'redirects to sign in page'
do
put
:update
,
namespace_id:
project
.
namespace
.
to_param
,
project_id:
project
.
to_param
,
notification_setting:
{
level: :participating
}
post
:create
,
project:
{
id:
project
.
id
},
notification_setting:
{
level: :participating
}
expect
(
response
).
to
redirect_to
(
new_user_session_path
)
end
...
...
@@ -26,9 +25,65 @@ describe Projects::NotificationSettingsController do
end
it
'returns success'
do
post
:create
,
project:
{
id:
project
.
id
},
notification_setting:
{
level: :participating
}
expect
(
response
.
status
).
to
eq
200
end
context
'and setting custom notification setting'
do
let
(
:custom_events
)
do
events
=
{}
NotificationSetting
::
EMAIL_EVENTS
.
each
do
|
event
|
events
[
event
]
=
"true"
end
end
it
'returns success'
do
post
:create
,
project:
{
id:
project
.
id
},
notification_setting:
{
level: :participating
,
events:
custom_events
}
expect
(
response
.
status
).
to
eq
200
end
end
end
context
'not authorized'
do
let
(
:private_project
)
{
create
(
:project
,
:private
)
}
before
{
sign_in
(
user
)
}
it
'returns 404'
do
post
:create
,
project:
{
id:
private_project
.
id
},
notification_setting:
{
level: :participating
}
expect
(
response
.
status
).
to
eq
(
404
)
end
end
end
describe
'#update'
do
let
(
:notification_setting
)
{
user
.
global_notification_setting
}
context
'when not authorized'
do
it
'redirects to sign in page'
do
put
:update
,
namespace_id:
project
.
namespace
.
to_param
,
project_id:
project
.
to_param
,
id:
notification_setting
,
notification_setting:
{
level: :participating
}
expect
(
response
).
to
redirect_to
(
new_user_session_path
)
end
end
context
'when authorized'
do
before
{
sign_in
(
user
)
}
it
'returns success'
do
put
:update
,
id:
notification_setting
,
notification_setting:
{
level: :participating
}
expect
(
response
.
status
).
to
eq
200
...
...
@@ -45,8 +100,7 @@ describe Projects::NotificationSettingsController do
it
'returns success'
do
put
:update
,
namespace_id:
project
.
namespace
.
to_param
,
project_id:
project
.
to_param
,
id:
notification_setting
,
notification_setting:
{
level: :participating
,
events:
custom_events
}
expect
(
response
.
status
).
to
eq
200
...
...
@@ -55,13 +109,13 @@ describe Projects::NotificationSettingsController do
end
context
'not authorized'
do
let
(
:private_project
)
{
create
(
:project
,
:private
)
}
before
{
sign_in
(
user
)
}
let
(
:other_user
)
{
create
(
:user
)
}
before
{
sign_in
(
other_user
)
}
it
'returns 404'
do
put
:update
,
namespace_id:
private_project
.
namespace
.
to_param
,
project_id:
private_project
.
to_param
,
id:
notification_setting
,
notification_setting:
{
level: :participating
}
expect
(
response
.
status
).
to
eq
(
404
)
...
...
spec/services/notification_service_spec.rb
View file @
f82ab42d
...
...
@@ -46,7 +46,8 @@ describe NotificationService, services: true do
project
.
team
<<
[
issue
.
assignee
,
:master
]
project
.
team
<<
[
note
.
author
,
:master
]
create
(
:note_on_issue
,
noteable:
issue
,
project_id:
issue
.
project_id
,
note:
'@subscribed_participant cc this guy'
)
update_custom_notification
(
:new_note
)
update_custom_notification
(
:new_note
,
@u_guest_custom
,
project
)
update_custom_notification
(
:new_note
,
@u_custom_global
)
end
describe
:new_note
do
...
...
@@ -54,7 +55,7 @@ describe NotificationService, services: true do
add_users_with_subscription
(
note
.
project
,
issue
)
# Ensure create SentNotification by noteable = issue 6 times, not noteable = note
expect
(
SentNotification
).
to
receive
(
:record
).
with
(
issue
,
any_args
).
exactly
(
7
).
times
expect
(
SentNotification
).
to
receive
(
:record
).
with
(
issue
,
any_args
).
exactly
(
8
).
times
ActionMailer
::
Base
.
deliveries
.
clear
...
...
@@ -63,6 +64,7 @@ describe NotificationService, services: true do
should_email
(
@u_watcher
)
should_email
(
note
.
noteable
.
author
)
should_email
(
note
.
noteable
.
assignee
)
should_email
(
@u_custom_global
)
should_email
(
@u_mentioned
)
should_email
(
@subscriber
)
should_email
(
@watcher_and_subscriber
)
...
...
@@ -105,10 +107,12 @@ describe NotificationService, services: true do
before
do
note
.
project
.
namespace_id
=
group
.
id
note
.
project
.
group
.
add_user
(
@u_watcher
,
GroupMember
::
MASTER
)
note
.
project
.
group
.
add_user
(
@u_custom_global
,
GroupMember
::
MASTER
)
note
.
project
.
save
@u_watcher
.
notification_settings_for
(
note
.
project
).
participating!
@u_watcher
.
notification_settings_for
(
note
.
project
.
group
).
global!
update_custom_notification
(
:new_note
,
@u_custom_global
)
ActionMailer
::
Base
.
deliveries
.
clear
end
...
...
@@ -118,6 +122,7 @@ describe NotificationService, services: true do
should_email
(
note
.
noteable
.
author
)
should_email
(
note
.
noteable
.
assignee
)
should_email
(
@u_mentioned
)
should_email
(
@u_custom_global
)
should_not_email
(
@u_guest_custom
)
should_not_email
(
@u_guest_watcher
)
should_not_email
(
@u_watcher
)
...
...
@@ -138,6 +143,10 @@ describe NotificationService, services: true do
let
(
:admin
)
{
create
(
:admin
)
}
let
(
:confidential_issue
)
{
create
(
:issue
,
:confidential
,
project:
project
,
author:
author
,
assignee:
assignee
)
}
let
(
:note
)
{
create
(
:note_on_issue
,
noteable:
confidential_issue
,
project:
project
,
note:
"
#{
author
.
to_reference
}
#{
assignee
.
to_reference
}
#{
non_member
.
to_reference
}
#{
member
.
to_reference
}
#{
admin
.
to_reference
}
"
)
}
let
(
:guest_watcher
)
{
create_user_with_notification
(
:watch
,
"guest-watcher-confidential"
)
}
before
do
end
it
'filters out users that can not read the issue'
do
project
.
team
<<
[
member
,
:developer
]
...
...
@@ -149,6 +158,7 @@ describe NotificationService, services: true do
notification
.
new_note
(
note
)
should_not_email
(
non_member
)
should_not_email
(
guest_watcher
)
should_email
(
author
)
should_email
(
assignee
)
should_email
(
member
)
...
...
@@ -223,6 +233,9 @@ describe NotificationService, services: true do
should_email
(
member
)
end
# it emails custom global users on mention
should_email
(
@u_custom_global
)
should_email
(
@u_guest_watcher
)
should_email
(
note
.
noteable
.
author
)
should_not_email
(
note
.
author
)
...
...
@@ -241,13 +254,15 @@ describe NotificationService, services: true do
build_team
(
note
.
project
)
ActionMailer
::
Base
.
deliveries
.
clear
allow_any_instance_of
(
Commit
).
to
receive
(
:author
).
and_return
(
@u_committer
)
update_custom_notification
(
:new_note
)
update_custom_notification
(
:new_note
,
@u_guest_custom
,
project
)
update_custom_notification
(
:new_note
,
@u_custom_global
)
end
describe
'#new_note, #perform_enqueued_jobs'
do
it
do
notification
.
new_note
(
note
)
should_email
(
@u_guest_watcher
)
should_email
(
@u_custom_global
)
should_email
(
@u_guest_custom
)
should_email
(
@u_committer
)
should_email
(
@u_watcher
)
...
...
@@ -289,7 +304,8 @@ describe NotificationService, services: true do
build_team
(
issue
.
project
)
add_users_with_subscription
(
issue
.
project
,
issue
)
ActionMailer
::
Base
.
deliveries
.
clear
update_custom_notification
(
:new_issue
)
update_custom_notification
(
:new_issue
,
@u_guest_custom
,
project
)
update_custom_notification
(
:new_issue
,
@u_custom_global
)
end
describe
'#new_issue'
do
...
...
@@ -300,6 +316,7 @@ describe NotificationService, services: true do
should_email
(
@u_watcher
)
should_email
(
@u_guest_watcher
)
should_email
(
@u_guest_custom
)
should_email
(
@u_custom_global
)
should_email
(
@u_participant_mentioned
)
should_not_email
(
@u_mentioned
)
should_not_email
(
@u_participating
)
...
...
@@ -345,6 +362,7 @@ describe NotificationService, services: true do
notification
.
new_issue
(
confidential_issue
,
@u_disabled
)
should_not_email
(
@u_guest_watcher
)
should_not_email
(
non_member
)
should_not_email
(
author
)
should_email
(
assignee
)
...
...
@@ -355,7 +373,10 @@ describe NotificationService, services: true do
end
describe
'#reassigned_issue'
do
before
{
update_custom_notification
(
:reassign_issue
)
}
before
do
update_custom_notification
(
:reassign_issue
,
@u_guest_custom
,
project
)
update_custom_notification
(
:reassign_issue
,
@u_custom_global
)
end
it
'emails new assignee'
do
notification
.
reassigned_issue
(
issue
,
@u_disabled
)
...
...
@@ -364,6 +385,7 @@ describe NotificationService, services: true do
should_email
(
@u_watcher
)
should_email
(
@u_guest_watcher
)
should_email
(
@u_guest_custom
)
should_email
(
@u_custom_global
)
should_email
(
@u_participant_mentioned
)
should_email
(
@subscriber
)
should_not_email
(
@unsubscriber
)
...
...
@@ -383,6 +405,7 @@ describe NotificationService, services: true do
should_email
(
@u_guest_custom
)
should_email
(
@u_participant_mentioned
)
should_email
(
@subscriber
)
should_email
(
@u_custom_global
)
should_not_email
(
@unsubscriber
)
should_not_email
(
@u_participating
)
should_not_email
(
@u_disabled
)
...
...
@@ -400,6 +423,7 @@ describe NotificationService, services: true do
should_email
(
@u_guest_custom
)
should_email
(
@u_participant_mentioned
)
should_email
(
@subscriber
)
should_email
(
@u_custom_global
)
should_not_email
(
@unsubscriber
)
should_not_email
(
@u_participating
)
should_not_email
(
@u_disabled
)
...
...
@@ -417,6 +441,7 @@ describe NotificationService, services: true do
should_email
(
@u_guest_custom
)
should_email
(
@u_participant_mentioned
)
should_email
(
@subscriber
)
should_email
(
@u_custom_global
)
should_not_email
(
@unsubscriber
)
should_not_email
(
@u_participating
)
should_not_email
(
@u_disabled
)
...
...
@@ -433,6 +458,7 @@ describe NotificationService, services: true do
should_email
(
@u_guest_custom
)
should_email
(
@u_participant_mentioned
)
should_email
(
@subscriber
)
should_email
(
@u_custom_global
)
should_not_email
(
issue
.
assignee
)
should_not_email
(
@unsubscriber
)
should_not_email
(
@u_participating
)
...
...
@@ -531,7 +557,10 @@ describe NotificationService, services: true do
end
describe
'#close_issue'
do
before
{
update_custom_notification
(
:close_issue
)
}
before
do
update_custom_notification
(
:close_issue
,
@u_guest_custom
,
project
)
update_custom_notification
(
:close_issue
,
@u_custom_global
)
end
it
'should sent email to issue assignee and issue author'
do
notification
.
close_issue
(
issue
,
@u_disabled
)
...
...
@@ -541,6 +570,7 @@ describe NotificationService, services: true do
should_email
(
@u_watcher
)
should_email
(
@u_guest_watcher
)
should_email
(
@u_guest_custom
)
should_email
(
@u_custom_global
)
should_email
(
@u_participant_mentioned
)
should_email
(
@subscriber
)
should_email
(
@watcher_and_subscriber
)
...
...
@@ -580,7 +610,10 @@ describe NotificationService, services: true do
end
describe
'#reopen_issue'
do
before
{
update_custom_notification
(
:reopen_issue
)
}
before
do
update_custom_notification
(
:reopen_issue
,
@u_guest_custom
,
project
)
update_custom_notification
(
:reopen_issue
,
@u_custom_global
)
end
it
'should send email to issue assignee and issue author'
do
notification
.
reopen_issue
(
issue
,
@u_disabled
)
...
...
@@ -590,6 +623,7 @@ describe NotificationService, services: true do
should_email
(
@u_watcher
)
should_email
(
@u_guest_watcher
)
should_email
(
@u_guest_custom
)
should_email
(
@u_custom_global
)
should_email
(
@u_participant_mentioned
)
should_email
(
@subscriber
)
should_email
(
@watcher_and_subscriber
)
...
...
@@ -639,7 +673,11 @@ describe NotificationService, services: true do
end
describe
'#new_merge_request'
do
before
{
update_custom_notification
(
:new_merge_request
)
}
before
do
update_custom_notification
(
:new_merge_request
,
@u_guest_custom
,
project
)
update_custom_notification
(
:new_merge_request
,
@u_custom_global
)
end
it
do
notification
.
new_merge_request
(
merge_request
,
@u_disabled
)
...
...
@@ -650,6 +688,7 @@ describe NotificationService, services: true do
should_email
(
@u_participant_mentioned
)
should_email
(
@u_guest_watcher
)
should_email
(
@u_guest_custom
)
should_email
(
@u_custom_global
)
should_not_email
(
@u_participating
)
should_not_email
(
@u_disabled
)
should_not_email
(
@u_lazy_participant
)
...
...
@@ -696,7 +735,10 @@ describe NotificationService, services: true do
end
describe
'#reassigned_merge_request'
do
before
{
update_custom_notification
(
:reassign_merge_request
)
}
before
do
update_custom_notification
(
:reassign_merge_request
,
@u_guest_custom
,
project
)
update_custom_notification
(
:reassign_merge_request
,
@u_custom_global
)
end
it
do
notification
.
reassigned_merge_request
(
merge_request
,
merge_request
.
author
)
...
...
@@ -708,6 +750,7 @@ describe NotificationService, services: true do
should_email
(
@watcher_and_subscriber
)
should_email
(
@u_guest_watcher
)
should_email
(
@u_guest_custom
)
should_email
(
@u_custom_global
)
should_not_email
(
@unsubscriber
)
should_not_email
(
@u_participating
)
should_not_email
(
@u_disabled
)
...
...
@@ -775,7 +818,10 @@ describe NotificationService, services: true do
end
describe
'#closed_merge_request'
do
before
{
update_custom_notification
(
:close_merge_request
)
}
before
do
update_custom_notification
(
:close_merge_request
,
@u_guest_custom
,
project
)
update_custom_notification
(
:close_merge_request
,
@u_custom_global
)
end
it
do
notification
.
close_mr
(
merge_request
,
@u_disabled
)
...
...
@@ -784,6 +830,7 @@ describe NotificationService, services: true do
should_email
(
@u_watcher
)
should_email
(
@u_guest_watcher
)
should_email
(
@u_guest_custom
)
should_email
(
@u_custom_global
)
should_email
(
@u_participant_mentioned
)
should_email
(
@subscriber
)
should_email
(
@watcher_and_subscriber
)
...
...
@@ -824,7 +871,10 @@ describe NotificationService, services: true do
end
describe
'#merged_merge_request'
do
before
{
update_custom_notification
(
:merge_merge_request
)
}
before
do
update_custom_notification
(
:merge_merge_request
,
@u_guest_custom
,
project
)
update_custom_notification
(
:merge_merge_request
,
@u_custom_global
)
end
it
do
notification
.
merge_mr
(
merge_request
,
@u_disabled
)
...
...
@@ -835,6 +885,7 @@ describe NotificationService, services: true do
should_email
(
@subscriber
)
should_email
(
@watcher_and_subscriber
)
should_email
(
@u_guest_watcher
)
should_email
(
@u_custom_global
)
should_email
(
@u_guest_custom
)
should_not_email
(
@unsubscriber
)
should_not_email
(
@u_participating
)
...
...
@@ -873,7 +924,10 @@ describe NotificationService, services: true do
end
describe
'#reopen_merge_request'
do
before
{
update_custom_notification
(
:reopen_merge_request
)
}
before
do
update_custom_notification
(
:reopen_merge_request
,
@u_guest_custom
,
project
)
update_custom_notification
(
:reopen_merge_request
,
@u_custom_global
)
end
it
do
notification
.
reopen_mr
(
merge_request
,
@u_disabled
)
...
...
@@ -885,6 +939,7 @@ describe NotificationService, services: true do
should_email
(
@watcher_and_subscriber
)
should_email
(
@u_guest_watcher
)
should_email
(
@u_guest_custom
)
should_email
(
@u_custom_global
)
should_not_email
(
@unsubscriber
)
should_not_email
(
@u_participating
)
should_not_email
(
@u_disabled
)
...
...
@@ -937,6 +992,7 @@ describe NotificationService, services: true do
should_email
(
@u_watcher
)
should_email
(
@u_participating
)
should_email
(
@u_lazy_participant
)
should_email
(
@u_custom_global
)
should_not_email
(
@u_guest_watcher
)
should_not_email
(
@u_guest_custom
)
should_not_email
(
@u_disabled
)
...
...
@@ -953,6 +1009,7 @@ describe NotificationService, services: true do
@u_committer
=
create
(
:user
,
username:
'committer'
)
@u_not_mentioned
=
create_global_setting_for
(
create
(
:user
,
username:
'regular'
),
:participating
)
@u_outsider_mentioned
=
create
(
:user
,
username:
'outsider'
)
@u_custom_global
=
create_global_setting_for
(
create
(
:user
,
username:
'custom_global'
),
:custom
)
# User to be participant by default
# This user does not contain any record in notification settings table
...
...
@@ -970,6 +1027,7 @@ describe NotificationService, services: true do
project
.
team
<<
[
@u_committer
,
:master
]
project
.
team
<<
[
@u_not_mentioned
,
:master
]
project
.
team
<<
[
@u_lazy_participant
,
:master
]
project
.
team
<<
[
@u_custom_global
,
:master
]
end
def
create_global_setting_for
(
user
,
level
)
...
...
@@ -989,8 +1047,10 @@ describe NotificationService, services: true do
user
end
def
update_custom_notification
(
event
)
setting
=
@u_guest_custom
.
notification_settings_for
(
project
)
# Create custom notifications
# When resource is nil it means global notification
def
update_custom_notification
(
event
,
user
,
resource
=
nil
)
setting
=
user
.
notification_settings_for
(
resource
)
setting
.
events
[
event
]
=
true
setting
.
save
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment