From 220708fa6ebca4ece1be0af4bb72933a4d72cc76 Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Mon, 13 Jun 2016 16:51:35 -0300 Subject: Remove schema from branch history --- app/assets/javascripts/dispatcher.js.coffee | 1 + .../javascripts/notifications_form.js.coffee | 49 ++++++++++++++++++++++ app/assets/javascripts/project.js.coffee | 35 +++++++++------- app/assets/stylesheets/pages/projects.scss | 22 +++++++--- .../projects/notification_settings_controller.rb | 20 +++++++-- app/models/notification_setting.rb | 9 ++-- app/services/notification_service.rb | 5 +++ .../projects/buttons/_notifications.html.haml | 30 ++++++++----- .../projects/_custom_notifications.html.haml | 27 ++++++++++++ .../projects/_notification_dropdown.html.haml | 9 ++++ features/steps/project/project.rb | 2 +- 11 files changed, 170 insertions(+), 39 deletions(-) create mode 100644 app/assets/javascripts/notifications_form.js.coffee create mode 100644 app/views/shared/projects/_custom_notifications.html.haml create mode 100644 app/views/shared/projects/_notification_dropdown.html.haml diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index 29ac0f70b30..ad0d2617294 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -75,6 +75,7 @@ class Dispatcher when 'projects:show' shortcut_handler = new ShortcutsNavigation() + new NotificationsForm() new TreeView() if $('#tree-slider').length when 'groups:activity' new Activities() diff --git a/app/assets/javascripts/notifications_form.js.coffee b/app/assets/javascripts/notifications_form.js.coffee new file mode 100644 index 00000000000..cfe8e133b66 --- /dev/null +++ b/app/assets/javascripts/notifications_form.js.coffee @@ -0,0 +1,49 @@ +class @NotificationsForm + constructor: -> + @form = $('.custom-notifications-form') + + @removeEventListeners() + @initEventListeners() + + removeEventListeners: -> + $(document).off 'change', '.js-custom-notification-event' + + initEventListeners: -> + $(document).on 'change', '.js-custom-notification-event', @toggleCheckbox + + toggleCheckbox: (e) => + $checkbox = $(e.currentTarget) + $parent = $checkbox.closest('.checkbox') + + @saveEvent($checkbox, $parent) + + showCheckboxLoadingSpinner: ($parent) -> + $parent + .addClass 'is-loading' + .find '.custom-notification-event-loading' + .removeClass 'fa-check' + .addClass 'fa-spin fa-spinner' + .removeClass 'is-done' + + saveEvent: ($checkbox, $parent) -> + $.ajax( + url: @form.attr('action') + method: 'patch' + dataType: 'json' + data: @form.serialize() + beforeSend: => + @showCheckboxLoadingSpinner($parent) + ).done (data) -> + $checkbox.enable() + + if data.saved + $parent + .find '.custom-notification-event-loading' + .toggleClass 'fa-spin fa-spinner fa-check is-done' + + setTimeout(-> + $parent + .removeClass 'is-loading' + .find '.custom-notification-event-loading' + .toggleClass 'fa-spin fa-spinner fa-check is-done' + , 2000) diff --git a/app/assets/javascripts/project.js.coffee b/app/assets/javascripts/project.js.coffee index 07be85a32a5..236f0899147 100644 --- a/app/assets/javascripts/project.js.coffee +++ b/app/assets/javascripts/project.js.coffee @@ -34,21 +34,26 @@ class @Project $(@).parents('.no-password-message').remove() e.preventDefault() - $('.update-notification').on 'click', (e) -> - e.preventDefault() - notification_level = $(@).data 'notification-level' - label = $(@).data 'notification-title' - $('#notification_setting_level').val(notification_level) - $('#notification-form').submit() - $('#notifications-button').empty().append("" + label + "") - $(@).parents('ul').find('li.active').removeClass 'active' - $(@).parent().addClass 'active' - - $('#notification-form').on 'ajax:success', (e, data) -> - if data.saved - new Flash("Notification settings saved", "notice") - else - new Flash("Failed to save new settings", "alert") + $(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() diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index bb250904255..ea708872cc8 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -133,11 +133,6 @@ } } - .btn-group:not(:first-child):not(:last-child) > .btn { - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; - } - form { margin-left: 10px; } @@ -604,3 +599,20 @@ pre.light-well { } } } + +.custom-notifications-form { + .is-loading { + .custom-notification-event-loading { + display: inline-block; + } + } +} + +.custom-notification-event-loading { + display: none; + margin-left: 5px; + + &.is-done { + color: $gl-text-green; + } +} diff --git a/app/controllers/projects/notification_settings_controller.rb b/app/controllers/projects/notification_settings_controller.rb index 7d81cc03c73..13b38501ae4 100644 --- a/app/controllers/projects/notification_settings_controller.rb +++ b/app/controllers/projects/notification_settings_controller.rb @@ -2,10 +2,24 @@ class Projects::NotificationSettingsController < Projects::ApplicationController before_action :authenticate_user! def update - notification_setting = current_user.notification_settings_for(project) - saved = notification_setting.update_attributes(notification_setting_params) + @notification_setting = current_user.notification_settings_for(project) - render json: { saved: saved } + if params[:custom_events].nil? + saved = @notification_setting.update_attributes(notification_setting_params) + else + events = params[:events] || {} + + NotificationSetting::EMAIL_EVENTS.each do |event| + @notification_setting.events[event] = events[event] + end + + saved = @notification_setting.save + end + + render json: { + html: view_to_html_string("projects/buttons/_notifications", locals: { project: @project, notification_setting: @notification_setting }), + saved: saved, + } end private diff --git a/app/models/notification_setting.rb b/app/models/notification_setting.rb index 3f8c5b2caa9..f41b011c0ae 100644 --- a/app/models/notification_setting.rb +++ b/app/models/notification_setting.rb @@ -19,7 +19,7 @@ class NotificationSetting < ActiveRecord::Base :new_note, :new_issue, :reopen_issue, - :closed_issue, + :close_issue, :reassign_issue, :new_merge_request, :reopen_merge_request, @@ -42,13 +42,12 @@ class NotificationSetting < ActiveRecord::Base setting end - # Set all event attributes as true when level is not custom + # Set all event attributes to false when level is not custom or being initialized def set_events - # Level is a ENUM cannot compare to symbol - return if level == "custom" + return if self.custom? || self.persisted? EMAIL_EVENTS.each do |event| - self.send("#{event}=", true) + events[event] = false end end end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 38cc00f1a05..841912b72c5 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -29,6 +29,7 @@ class NotificationService # * issue assignee if their notification level is not Disabled # * project team members with notification level higher then Participating # * watchers of the issue's labels + # * users with custom level checked with "new issue" # def new_issue(issue, current_user) new_resource_email(issue, issue.project, :new_issue_email) @@ -39,6 +40,7 @@ class NotificationService # * issue author if their notification level is not Disabled # * issue assignee if their notification level is not Disabled # * project team members with notification level higher then Participating + # * users with custom level checked with "close issue" # def close_issue(issue, current_user) close_resource_email(issue, issue.project, current_user, :closed_issue_email) @@ -48,6 +50,7 @@ class NotificationService # # * issue old assignee if their notification level is not Disabled # * issue new assignee if their notification level is not Disabled + # * users with custom level checked with "reassign issue" # def reassigned_issue(issue, current_user) reassign_resource_email(issue, issue.project, current_user, :reassigned_issue_email) @@ -66,6 +69,7 @@ class NotificationService # * mr assignee if their notification level is not Disabled # * project team members with notification level higher then Participating # * watchers of the mr's labels + # * users with custom level checked with "new merge request" # def new_merge_request(merge_request, current_user) new_resource_email(merge_request, merge_request.target_project, :new_merge_request_email) @@ -75,6 +79,7 @@ class NotificationService # # * merge_request old assignee if their notification level is not Disabled # * merge_request assignee if their notification level is not Disabled + # * users with custom level checked with "reassign merge request" # def reassigned_merge_request(merge_request, current_user) reassign_resource_email(merge_request, merge_request.target_project, current_user, :reassigned_merge_request_email) diff --git a/app/views/projects/buttons/_notifications.html.haml b/app/views/projects/buttons/_notifications.html.haml index 3b97dc9328f..47a12e6f8cb 100644 --- a/app/views/projects/buttons/_notifications.html.haml +++ b/app/views/projects/buttons/_notifications.html.haml @@ -1,11 +1,21 @@ - if @notification_setting - = 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 - .dropdown - %button.btn.btn-default.notifications-btn#notifications-button{ data: { toggle: "dropdown" }, aria: { haspopup: "true", expanded: "false" } } - = icon('bell') - = notification_title(@notification_setting.level) - = icon('caret-down') - %ul.dropdown-menu.dropdown-menu-no-wrap.dropdown-menu-align-right.dropdown-menu-selectable.dropdown-menu-large{ role: "menu" } - - NotificationSetting.levels.each do |level| - = notification_list_item(level.first, @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" diff --git a/app/views/shared/projects/_custom_notifications.html.haml b/app/views/shared/projects/_custom_notifications.html.haml new file mode 100644 index 00000000000..8569c523ef4 --- /dev/null +++ b/app/views/shared/projects/_custom_notifications.html.haml @@ -0,0 +1,27 @@ +#custom-notifications-modal.modal.fade{ tabindex: "-1", role: "dialog", 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, url: namespace_project_notification_setting_path(@project.namespace.becomes(Namespace), @project), method: :patch, html: { class: "custom-notifications-form" } do |f| + = hidden_field_tag "custom_events", "true" + = f.hidden_field :level + .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_tag "events[#{event}]", true, @notification_setting.events[event], id: "events_#{event}", class: "js-custom-notification-event" + %strong + = event.to_s.humanize + = icon("spinner spin", class: "custom-notification-event-loading") diff --git a/app/views/shared/projects/_notification_dropdown.html.haml b/app/views/shared/projects/_notification_dropdown.html.haml new file mode 100644 index 00000000000..6388f907eb3 --- /dev/null +++ b/app/views/shared/projects/_notification_dropdown.html.haml @@ -0,0 +1,9 @@ +%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 diff --git a/features/steps/project/project.rb b/features/steps/project/project.rb index 2a1a8e776f0..98b57e5cbfb 100644 --- a/features/steps/project/project.rb +++ b/features/steps/project/project.rb @@ -126,7 +126,7 @@ class Spinach::Features::Project < Spinach::FeatureSteps end step 'I click notifications drop down button' do - find('#notifications-button').click + first('.notifications-btn').click end step 'I choose Mention setting' do -- cgit v1.2.1