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
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
iv
gitlab-ce
Commits
33c61bd4
Commit
33c61bd4
authored
Jun 17, 2016
by
Felipe Artur
Browse files
Options
Browse Files
Download
Plain Diff
Re-use notifications dropdown/modal for user profile
parents
24f5f071
f82ab42d
Changes
25
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
418 additions
and
171 deletions
+418
-171
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
+6
-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
+26
-6
app/views/notifications/buttons/_notifications.html.haml
app/views/notifications/buttons/_notifications.html.haml
+24
-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
+8
-5
app/views/projects/_home_panel.html.haml
app/views/projects/_home_panel.html.haml
+4
-7
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
+28
-0
app/views/shared/notifications/_notification_dropdown.html.haml
...ews/shared/notifications/_notification_dropdown.html.haml
+12
-0
config/routes.rb
config/routes.rb
+8
-2
doc/workflow/notifications/settings.png
doc/workflow/notifications/settings.png
+0
-0
lib/api/entities.rb
lib/api/entities.rb
+2
-1
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/requests/api/projects_spec.rb
spec/requests/api/projects_spec.rb
+24
-5
spec/services/notification_service_spec.rb
spec/services/notification_service_spec.rb
+76
-14
No files found.
app/assets/javascripts/dispatcher.js.coffee
View file @
33c61bd4
...
@@ -126,6 +126,8 @@ class Dispatcher
...
@@ -126,6 +126,8 @@ class Dispatcher
shortcut_handler
=
new
ShortcutsDashboardNavigation
()
shortcut_handler
=
new
ShortcutsDashboardNavigation
()
when
'profiles'
when
'profiles'
new
Profile
()
new
Profile
()
new
NotificationsForm
()
new
NotificationsDropdown
()
when
'projects'
when
'projects'
new
Project
()
new
Project
()
new
ProjectAvatar
()
new
ProjectAvatar
()
...
@@ -139,6 +141,7 @@ class Dispatcher
...
@@ -139,6 +141,7 @@ class Dispatcher
new
ProjectNew
()
new
ProjectNew
()
when
'show'
when
'show'
new
ProjectShow
()
new
ProjectShow
()
new
NotificationsDropdown
()
when
'wikis'
when
'wikis'
new
Wikis
()
new
Wikis
()
shortcut_handler
=
new
ShortcutsNavigation
()
shortcut_handler
=
new
ShortcutsNavigation
()
...
...
app/assets/javascripts/notifications_dropdown.js.coffee
0 → 100644
View file @
33c61bd4
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 @
33c61bd4
class
@
NotificationsForm
class
@
NotificationsForm
constructor
:
->
constructor
:
->
@
form
=
$
(
'.custom-notifications-form'
)
@
removeEventListeners
()
@
removeEventListeners
()
@
initEventListeners
()
@
initEventListeners
()
...
@@ -14,7 +12,6 @@ class @NotificationsForm
...
@@ -14,7 +12,6 @@ class @NotificationsForm
toggleCheckbox
:
(
e
)
=>
toggleCheckbox
:
(
e
)
=>
$checkbox
=
$
(
e
.
currentTarget
)
$checkbox
=
$
(
e
.
currentTarget
)
$parent
=
$checkbox
.
closest
(
'.checkbox'
)
$parent
=
$checkbox
.
closest
(
'.checkbox'
)
@
saveEvent
(
$checkbox
,
$parent
)
@
saveEvent
(
$checkbox
,
$parent
)
showCheckboxLoadingSpinner
:
(
$parent
)
->
showCheckboxLoadingSpinner
:
(
$parent
)
->
...
@@ -26,11 +23,14 @@ class @NotificationsForm
...
@@ -26,11 +23,14 @@ class @NotificationsForm
.
removeClass
'is-done'
.
removeClass
'is-done'
saveEvent
:
(
$checkbox
,
$parent
)
->
saveEvent
:
(
$checkbox
,
$parent
)
->
form
=
$parent
.
parents
(
'form:first'
)
$
.
ajax
(
$
.
ajax
(
url
:
@
form
.
attr
(
'action'
)
url
:
form
.
attr
(
'action'
)
method
:
'patch'
method
:
form
.
attr
(
'method'
)
dataType
:
'json'
dataType
:
'json'
data
:
@
form
.
serialize
()
data
:
form
.
serialize
()
beforeSend
:
=>
beforeSend
:
=>
@
showCheckboxLoadingSpinner
(
$parent
)
@
showCheckboxLoadingSpinner
(
$parent
)
).
done
(
data
)
->
).
done
(
data
)
->
...
...
app/assets/javascripts/profile.js.coffee
View file @
33c61bd4
...
@@ -8,6 +8,10 @@ class @Profile
...
@@ -8,6 +8,10 @@ class @Profile
$
(
'.js-preferences-form'
).
on
'change.preference'
,
'input[type=radio]'
,
->
$
(
'.js-preferences-form'
).
on
'change.preference'
,
'input[type=radio]'
,
->
$
(
this
).
parents
(
'form'
).
submit
()
$
(
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'
,
->
$
(
'.update-username'
).
on
'ajax:before'
,
->
$
(
'.loading-username'
).
show
()
$
(
'.loading-username'
).
show
()
$
(
this
).
find
(
'.update-success'
).
hide
()
$
(
this
).
find
(
'.update-success'
).
hide
()
...
...
app/assets/javascripts/project.js.coffee
View file @
33c61bd4
...
@@ -34,27 +34,6 @@ class @Project
...
@@ -34,27 +34,6 @@ class @Project
$
(
@
).
parents
(
'.no-password-message'
).
remove
()
$
(
@
).
parents
(
'.no-password-message'
).
remove
()
e
.
preventDefault
()
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
()
@
projectSelectDropdown
()
...
...
app/controllers/groups/notification_settings_controller.rb
deleted
100644 → 0
View file @
24f5f071
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 @
33c61bd4
class
Projects::NotificationSettingsController
<
Projects
::
ApplicationController
class
NotificationSettingsController
<
ApplicationController
before_action
:authenticate_user!
before_action
:authenticate_user!
def
update
def
create
project
=
current_user
.
projects
.
find
(
params
[
:project
][
:id
])
@notification_setting
=
current_user
.
notification_settings_for
(
project
)
@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:
{
render_response
html:
view_to_html_string
(
"projects/buttons/_notifications"
,
locals:
{
project:
@project
,
notification_setting:
@notification_setting
}),
end
saved:
saved
}
def
update
@notification_setting
=
current_user
.
notification_settings
.
find
(
params
[
:id
])
@saved
=
@notification_setting
.
update_attributes
(
notification_setting_params
)
render_response
end
end
private
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
def
notification_setting_params
allowed_fields
=
NotificationSetting
::
EMAIL_EVENTS
.
dup
allowed_fields
=
NotificationSetting
::
EMAIL_EVENTS
.
dup
allowed_fields
<<
:level
allowed_fields
<<
:level
...
...
app/controllers/profiles/notifications_controller.rb
View file @
33c61bd4
class
Profiles::NotificationsController
<
Profiles
::
ApplicationController
class
Profiles::NotificationsController
<
Profiles
::
ApplicationController
def
show
def
show
@user
=
current_user
@user
=
current_user
@group_notifications
=
current_user
.
notification_settings
.
for_groups
@group_notifications
=
current_user
.
notification_settings
.
for_groups
.
order
(
:id
)
@project_notifications
=
current_user
.
notification_settings
.
for_projects
@project_notifications
=
current_user
.
notification_settings
.
for_projects
.
order
(
:id
)
@global_notification_setting
=
current_user
.
global_notification_setting
@global_notification_setting
=
current_user
.
global_notification_setting
end
end
def
update
def
update
if
current_user
.
update_attributes
(
user_params
)
&&
update_notification_settings
if
current_user
.
update_attributes
(
user_params
)
flash
[
:notice
]
=
"Notification settings saved"
flash
[
:notice
]
=
"Notification settings saved"
else
else
flash
[
:alert
]
=
"Failed to save new settings"
flash
[
:alert
]
=
"Failed to save new settings"
...
@@ -19,16 +19,4 @@ class Profiles::NotificationsController < Profiles::ApplicationController
...
@@ -19,16 +19,4 @@ class Profiles::NotificationsController < Profiles::ApplicationController
def
user_params
def
user_params
params
.
require
(
:user
).
permit
(
:notification_email
)
params
.
require
(
:user
).
permit
(
:notification_email
)
end
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
end
app/helpers/notifications_helper.rb
View file @
33c61bd4
...
@@ -64,22 +64,14 @@ module NotificationsHelper
...
@@ -64,22 +64,14 @@ module NotificationsHelper
end
end
end
end
def
notification_level_radio_buttons
# Identifier to trigger individually dropdowns and custom settings modals in the same view
html
=
""
def
notifications_menu_identifier
(
type
,
notification_setting
)
"
#{
type
}
-
#{
notification_setting
.
user_id
}
-
#{
notification_setting
.
source_id
}
-
#{
notification_setting
.
source_type
}
"
NotificationSetting
.
levels
.
each_key
do
|
level
|
end
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
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
end
end
app/services/notification_service.rb
View file @
33c61bd4
...
@@ -159,7 +159,7 @@ class NotificationService
...
@@ -159,7 +159,7 @@ class NotificationService
recipients
=
add_project_watchers
(
recipients
,
note
.
project
)
recipients
=
add_project_watchers
(
recipients
,
note
.
project
)
# Merge project with custom notification
# 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.
# Reject users with Mention notification level, except those mentioned in _this_ note.
recipients
=
reject_mention_users
(
recipients
-
mentioned_users
,
note
.
project
)
recipients
=
reject_mention_users
(
recipients
-
mentioned_users
,
note
.
project
)
...
@@ -277,12 +277,20 @@ class NotificationService
...
@@ -277,12 +277,20 @@ class NotificationService
protected
protected
# Get project/group users with CUSTOM notification level
# 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
=
[]
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
,
:custom
,
action
)
user_ids
+=
notification_settings_for
(
project
.
group
,
: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
))
recipients
.
concat
(
User
.
find
(
user_ids
))
end
end
...
@@ -291,7 +299,8 @@ class NotificationService
...
@@ -291,7 +299,8 @@ class NotificationService
project_members
=
notification_settings_for
(
project
)
project_members
=
notification_settings_for
(
project
)
users_with_project_level_global
=
notification_settings_for
(
project
,
:global
)
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
=
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
)
users_with_project_setting
=
select_project_member_setting
(
project
,
users_with_project_level_global
,
users
)
...
@@ -313,11 +322,21 @@ class NotificationService
...
@@ -313,11 +322,21 @@ class NotificationService
end
end
def
users_with_global_level_watch
(
ids
)
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
(
NotificationSetting
.
where
(
user_id:
ids
,
user_id:
ids
,
source_type:
nil
,
source_type:
nil
,
level:
NotificationSetting
.
levels
[
:watch
]
level:
NotificationSetting
.
levels
[
level
]
)
.
pluck
(
:user_id
)
)
end
end
# Build a list of users based on project notifcation settings
# Build a list of users based on project notifcation settings
...
@@ -497,7 +516,8 @@ class NotificationService
...
@@ -497,7 +516,8 @@ class NotificationService
recipients
=
target
.
participants
(
current_user
)
recipients
=
target
.
participants
(
current_user
)
recipients
=
add_project_watchers
(
recipients
,
project
)
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
=
reject_mention_users
(
recipients
,
project
)
recipients
=
recipients
.
uniq
recipients
=
recipients
.
uniq
...
...
app/views/notifications/buttons/_notifications.html.haml
0 → 100644
View file @
33c61bd4
-
if
notification_setting
.dropdown.notification-dropdown.pull-right
=
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
.
custom?
%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.dropdown-toggle
{
data:
{
toggle:
"dropdown"
,
target:
notifications_menu_identifier
(
"dropdown"
,
notification_setting
)
}
}
%span
.caret
.sr-only
Toggle dropdown
-
else
%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"
)
=
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 @
33c61bd4
...
@@ -9,5 +9,4 @@
...
@@ -9,5 +9,4 @@
=
link_to
group
.
name
,
group_path
(
group
)
=
link_to
group
.
name
,
group_path
(
group
)
.pull-right
.pull-right
=
form_for
[
group
,
setting
],
remote:
true
,
html:
{
class:
'update-notifications'
}
do
|
f
|
=
render
'notifications/buttons/notifications'
,
notification_setting:
setting
=
f
.
select
:level
,
NotificationSetting
.
levels
.
keys
,
{},
class:
'form-control trigger-submit'
app/views/profiles/notifications/_project_settings.html.haml
View file @
33c61bd4
...
@@ -9,5 +9,4 @@
...
@@ -9,5 +9,4 @@
=
link_to_project
(
project
)
=
link_to_project
(
project
)
.pull-right
.pull-right
=
form_for
[
project
.
namespace
.
becomes
(
Namespace
),
project
,
setting
],
remote:
true
,
html:
{
class:
'update-notifications'
}
do
|
f
|
=
render
'notifications/buttons/notifications'
,
notification_setting:
setting
=
f
.
select
:level
,
NotificationSetting
.
levels
.
keys
,
{},
class:
'form-control trigger-submit'
app/views/profiles/notifications/show.html.haml
View file @
33c61bd4
...
@@ -24,12 +24,15 @@
...
@@ -24,12 +24,15 @@
.form-group
.form-group
=
f
.
label
:notification_email
,
class:
"label-light"
=
f
.
label
:notification_email
,
class:
"label-light"
=
f
.
select
:notification_email
,
@user
.
all_emails
,
{
include_blank:
false
},
class:
"select2"
=
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
=
label_tag
:global_notification_level
,
"Global notification level"
,
class:
"label-light"
=
f
.
submit
'Update settings'
,
class:
"btn btn-create"
%br
.clearfix
.form-group.pull-left
=
render
'notifications/buttons/notifications'
,
notification_setting:
@global_notification_setting
.clearfix
%hr
%hr
%h5
%h5
Groups (
#{
@group_notifications
.
count
}
)
Groups (
#{
@group_notifications
.
count
}
)
...
...
app/views/projects/_home_panel.html.haml
View file @
33c61bd4
...
@@ -29,13 +29,10 @@
...
@@ -29,13 +29,10 @@
.project-clone-holder
.project-clone-holder
=
render
"shared/clone_panel"
=
render
"shared/clone_panel"
.project-repo-buttons.project-right-buttons
.project-repo-buttons.btn-group.project-right-buttons
-
if
current_user
=
render
"projects/buttons/download"
=
render
'shared/members/access_request_buttons'
,
source:
@project
=
render
'projects/buttons/dropdown'
.btn-group
=
render
'notifications/buttons/notifications'
,
notification_setting:
@notification_setting
=
render
"projects/buttons/download"
=
render
'projects/buttons/dropdown'
=
render
'projects/buttons/notifications'
:javascript
:javascript
new
Star
();
new
Star
();
app/views/projects/buttons/_notifications.html.haml
deleted
100644 → 0
View file @
24f5f071
-
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
.
custom?
.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
-
else
%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"
)
=
render
"shared/projects/notification_dropdown"
=
content_for
:scripts_body
do
=
render
"shared/projects/custom_notifications"
app/views/shared/notifications/_custom_notifications.html.haml
0 → 100644
View file @
33c61bd4
.modal.fade
{
tabindex:
"-1"
,
role:
"dialog"
,
id:
notifications_menu_identifier
(
"modal"
,
notification_setting
),
aria:
{
labelledby:
"custom-notifications-title"
}
}
.modal-dialog
.modal-content
.modal-header
%button
.close
{
type:
"button"
,
data:
{
dismiss:
"modal"
},
aria:
{
label:
"close"
}
}
%span
{
aria:
{
hidden:
"true"
}
}
×
%h4
#custom-notifications-title
.modal-title
Custom notification events
.modal-body
.container-fluid
=
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
Notification events
.col-lg-9
-
NotificationSetting
::
EMAIL_EVENTS
.
each
do
|
event
,
index
|
=
index
.form-group
.checkbox
{
class:
(
"prepend-top-0"
if
index
==
0
)
}
%label
{
for:
"events_#{event}"
}
=
check_box
(
""
,
event
,
{
name:
"notification_setting[
#{
event
}
]"
,
class:
"js-custom-notification-event"
,
checked:
notification_setting
.
events
[
event
]
})
%strong
=
event
.
to_s
.
humanize
=
icon
(
"spinner spin"
,
class:
"custom-notification-event-loading"
)
app/views/shared/notifications/_notification_dropdown.html.haml
0 → 100644
View file @
33c61bd4
%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
config/routes.rb
View file @
33c61bd4
...
@@ -123,9 +123,17 @@ Rails.application.routes.draw do
...
@@ -123,9 +123,17 @@ Rails.application.routes.draw do
end
end
end
end
#
# Spam reports
# Spam reports
#
resources
:abuse_reports
,
only:
[
:new
,
:create
]
resources
:abuse_reports
,
only:
[
:new
,
:create
]
#
# Notification settings
#
resources
:notification_settings
,
only:
[
:create
,
:update
]
#
#
# Import
# Import
#
#
...
@@ -421,7 +429,6 @@ Rails.application.routes.draw do
...
@@ -421,7 +429,6 @@ Rails.application.routes.draw do
resource
:avatar
,
only:
[
:destroy
]
resource
:avatar
,
only:
[
:destroy
]
resources
:milestones
,
constraints:
{
id:
/[^\/]+/
},
only:
[
:index
,
:show
,
:update
,
:new
,
:create
]
resources
:milestones
,
constraints:
{
id:
/[^\/]+/
},
only:
[
:index
,
:show
,
:update
,
:new
,
:create
]
resource
:notification_setting
,
only:
[
:update
]
end
end
end
end
...
@@ -653,7 +660,6 @@ Rails.application.routes.draw do
...
@@ -653,7 +660,6 @@ Rails.application.routes.draw do
resources
:forks
,
only:
[
:index
,
:new
,
:create
]
resources
:forks
,
only:
[
:index
,
:new
,
:create
]
resource
:import
,
only:
[
:new
,
:create
,
:show
]
resource
:import
,
only:
[
:new
,
:create
,
:show
]
resource
:notification_setting
,
only:
[
:update
]
resources
:refs
,
only:
[]
do
resources
:refs
,
only:
[]
do
collection
do
collection
do
...
...
doc/workflow/notifications/settings.png
View replaced file @
24f5f071
View file @
33c61bd4
86.1 KB
|
W:
|
H:
88.9 KB
|
W:
|
H:
2-up
Swipe
Onion skin
lib/api/entities.rb
View file @
33c61bd4
...
@@ -272,7 +272,8 @@ module API
...
@@ -272,7 +272,8 @@ module API
expose
:access_level
expose
:access_level
expose
:notification_level
do
|
member
,
options
|
expose
:notification_level
do
|
member
,
options
|
if
member
.
notification_setting
if
member
.
notification_setting
NotificationSetting
.
levels
[
member
.
notification_setting
.
level
]
setting
=
member
.
notification_setting
{
level:
NotificationSetting
.
levels
[
setting
.
level
],
events:
setting
.
events
}
end
end
end
end
end
end
...
...
spec/controllers/groups/notification_settings_controller_spec.rb
deleted
100644 → 0
View file @
24f5f071
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 @
33c61bd4
require
'spec_helper'
require
'spec_helper'
describe
Projects
::
NotificationSettingsController
do
describe
NotificationSettingsController
do
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
...
@@ -8,13 +8,12 @@ describe Projects::NotificationSettingsController do
...
@@ -8,13 +8,12 @@ describe Projects::NotificationSettingsController do
project
.
team
<<
[
user
,
:developer
]
project
.
team
<<
[
user
,
:developer
]
end
end
describe
'#
upd
ate'
do
describe
'#
cre
ate'
do
context
'when not authorized'
do
context
'when not authorized'
do
it
'redirects to sign in page'
do
it
'redirects to sign in page'
do
put
:update
,
post
:create
,
namespace_id:
project
.
namespace
.
to_param
,
project:
{
id:
project
.
id
},
project_id:
project
.
to_param
,
notification_setting:
{
level: :participating
}
notification_setting:
{
level: :participating
}
expect
(
response
).
to
redirect_to
(
new_user_session_path
)
expect
(
response
).
to
redirect_to
(
new_user_session_path
)
end
end
...
@@ -26,9 +25,65 @@ describe Projects::NotificationSettingsController do
...
@@ -26,9 +25,65 @@ describe Projects::NotificationSettingsController do
end
end
it
'returns success'
do
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
,
put
:update
,
namespace_id:
project
.
namespace
.
to_param
,
id:
notification_setting
,
project_id:
project
.
to_param
,
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
}
notification_setting:
{
level: :participating
}
expect
(
response
.
status
).
to
eq
200
expect
(
response
.
status
).
to
eq
200
...
@@ -45,8 +100,7 @@ describe Projects::NotificationSettingsController do
...
@@ -45,8 +100,7 @@ describe Projects::NotificationSettingsController do
it
'returns success'
do
it
'returns success'
do
put
:update
,
put
:update
,
namespace_id:
project
.
namespace
.
to_param
,
id:
notification_setting
,
project_id:
project
.
to_param
,
notification_setting:
{
level: :participating
,
events:
custom_events
}
notification_setting:
{
level: :participating
,
events:
custom_events
}
expect
(
response
.
status
).
to
eq
200
expect
(
response
.
status
).
to
eq
200
...
@@ -55,13 +109,13 @@ describe Projects::NotificationSettingsController do
...
@@ -55,13 +109,13 @@ describe Projects::NotificationSettingsController do
end
end
context
'not authorized'
do
context
'not authorized'
do
let
(
:private_project
)
{
create
(
:project
,
:private
)
}
let
(
:other_user
)
{
create
(
:user
)
}
before
{
sign_in
(
user
)
}
before
{
sign_in
(
other_user
)
}
it
'returns 404'
do
it
'returns 404'
do
put
:update
,
put
:update
,
namespace_id:
private_project
.
namespace
.
to_param
,
id:
notification_setting
,
project_id:
private_project
.
to_param
,
notification_setting:
{
level: :participating
}
notification_setting:
{
level: :participating
}
expect
(
response
.
status
).
to
eq
(
404
)
expect
(
response
.
status
).
to
eq
(
404
)
...
...
spec/requests/api/projects_spec.rb
View file @
33c61bd4
...
@@ -428,8 +428,9 @@ describe API::API, api: true do
...
@@ -428,8 +428,9 @@ describe API::API, api: true do
describe
'permissions'
do
describe
'permissions'
do
context
'all projects'
do
context
'all projects'
do
it
'Contains permission information'
do
before
{
project
.
team
<<
[
user
,
:master
]
}
project
.
team
<<
[
user
,
:master
]
it
'contains permission information'
do
get
api
(
"/projects"
,
user
)
get
api
(
"/projects"
,
user
)
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
response
.
status
).
to
eq
(
200
)
...
@@ -437,10 +438,18 @@ describe API::API, api: true do
...
@@ -437,10 +438,18 @@ describe API::API, api: true do
to
eq
(
Gitlab
::
Access
::
MASTER
)
to
eq
(
Gitlab
::
Access
::
MASTER
)
expect
(
json_response
.
first
[
'permissions'
][
'group_access'
]).
to
be_nil
expect
(
json_response
.
first
[
'permissions'
][
'group_access'
]).
to
be_nil
end
end
it
'contains notification level information'
do
get
api
(
"/projects"
,
user
)
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
json_response
.
first
[
'permissions'
][
'project_access'
][
'notification_level'
][
'level'
]).
to
eq
(
NotificationSetting
.
levels
[
:global
])
expect
(
json_response
.
first
[
'permissions'
][
'project_access'
][
'notification_level'
].
keys
).
to
include
(
'events'
)
end
end
end
context
'personal project'
do
context
'personal project'
do
it
'
S
ets project access and returns 200'
do
it
'
s
ets project access and returns 200'
do
project
.
team
<<
[
user
,
:master
]
project
.
team
<<
[
user
,
:master
]
get
api
(
"/projects/
#{
project
.
id
}
"
,
user
)
get
api
(
"/projects/
#{
project
.
id
}
"
,
user
)
...
@@ -452,9 +461,11 @@ describe API::API, api: true do
...
@@ -452,9 +461,11 @@ describe API::API, api: true do
end
end
context
'group project'
do
context
'group project'
do
let
(
:project2
)
{
create
(
:project
,
group:
create
(
:group
))
}
before
{
project2
.
group
.
add_owner
(
user
)
}
it
'should set the owner and return 200'
do
it
'should set the owner and return 200'
do
project2
=
create
(
:project
,
group:
create
(
:group
))
project2
.
group
.
add_owner
(
user
)
get
api
(
"/projects/
#{
project2
.
id
}
"
,
user
)
get
api
(
"/projects/
#{
project2
.
id
}
"
,
user
)
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
response
.
status
).
to
eq
(
200
)
...
@@ -462,6 +473,14 @@ describe API::API, api: true do
...
@@ -462,6 +473,14 @@ describe API::API, api: true do
expect
(
json_response
[
'permissions'
][
'group_access'
][
'access_level'
]).
expect
(
json_response
[
'permissions'
][
'group_access'
][
'access_level'
]).
to
eq
(
Gitlab
::
Access
::
OWNER
)
to
eq
(
Gitlab
::
Access
::
OWNER
)
end
end
it
'shows notification level information'
do
get
api
(
"/projects/
#{
project2
.
id
}
"
,
user
)
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
json_response
[
'permissions'
][
'group_access'
][
'notification_level'
][
'level'
]).
to
eq
(
NotificationSetting
.
levels
[
:global
])
expect
(
json_response
[
'permissions'
][
'group_access'
][
'notification_level'
].
keys
).
to
include
(
'events'
)
end
end
end
end
end
end
end
...
...
spec/services/notification_service_spec.rb
View file @
33c61bd4
This diff is collapsed.
Click to expand it.
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