System notification modal window [SCI-2957 and SCI-2958] (#1484)

* Added new system notification modal

* Adding loading system notification on sign in
This commit is contained in:
aignatov-bio 2019-02-15 13:07:29 +01:00 committed by GitHub
parent ada0846f38
commit c598541e09
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 9122 additions and 16 deletions

View file

@ -18,10 +18,33 @@ function SystemNotificationsMarkAsSeen() {
}
}
function bindSystemNotificationAjax() {
var SystemNotificationModal = null;
var SystemNotificationModalBody = null;
var SystemNotificationModalTitle = null;
SystemNotificationModal = $('#manage-module-system-notification-modal');
SystemNotificationModalBody = SystemNotificationModal.find('.modal-body');
SystemNotificationModalTitle = SystemNotificationModal.find('#manage-module-system-notification-modal-label');
$('.modal-system-notification')
.on('ajax:success', function(ev, data) {
var SystemNotification = $('.system-notification[data-system-notification-id=' + data.id + ']')[0];
SystemNotificationModalBody.html(data.modal_body);
SystemNotificationModalTitle.text(data.modal_title);
// Open modal
SystemNotificationModal.modal('show');
if (SystemNotification.dataset.unread === '1') {
$.post('system_notifications/' + data.id + '/mark_as_read');
}
});
}
function initSystemNotificationsButton() {
$('.btn-more-notifications')
.on('ajax:success', function(e, data) {
$(data.html).insertAfter($('.notifications-container .system-notification').last());
bindSystemNotificationAjax();
if (data.more_url) {
$(this).attr('href', data.more_url);
} else {
@ -30,10 +53,9 @@ function initSystemNotificationsButton() {
});
}
(function() {
$(window).scroll(function() {
SystemNotificationsMarkAsSeen();
});
initSystemNotificationsButton();
$(window).scroll(function() {
SystemNotificationsMarkAsSeen();
}());
});
initSystemNotificationsButton();
SystemNotificationsMarkAsSeen();
bindSystemNotificationAjax();

View file

@ -17,6 +17,11 @@ class SystemNotificationsController < ApplicationController
end
end
def show
render json: current_user.system_notifications.modals
.find_by_id(params[:id]) || {}
end
# Update seen_at parameter for system notifications
def mark_as_seen
notifications = JSON.parse(params[:notifications])
@ -26,6 +31,13 @@ class SystemNotificationsController < ApplicationController
render json: { result: 'failed' }
end
def mark_as_read
current_user.user_system_notifications.mark_as_read(params[:id])
render json: { result: 'ok' }
rescue StandardError
render json: { result: 'failed' }
end
private
def prepare_notifications

View file

@ -1,6 +1,6 @@
class Users::SessionsController < Devise::SessionsController
# before_filter :configure_sign_in_params, only: [:create]
after_action :after_sign_in, only: :create
# GET /resource/sign_in
def new
# If user was redirected here from OAuth's authorize/new page (Doorkeeper
@ -32,7 +32,6 @@ class Users::SessionsController < Devise::SessionsController
sign_in(:user, user)
# This will cause new token to be generated
user.update(authentication_token: nil)
redirect_url = root_path
else
flash[:error] = t('devise.sessions.auth_token_create.wrong_credentials')
@ -46,6 +45,10 @@ class Users::SessionsController < Devise::SessionsController
end
end
def after_sign_in
flash[:system_notification_modal] = true
end
protected
# If you have extra params to permit, append them to the sanitizer.

View file

@ -2,6 +2,8 @@
class SystemNotification < ApplicationRecord
include PgSearch
scope :modals, -> { select(:modal_title, :modal_body, :id) }
# Full text postgreSQL search configuration
pg_search_scope :search_notifications, against: %i(title description),
using: {
@ -34,7 +36,8 @@ class SystemNotification < ApplicationRecord
:title,
:description,
:last_time_changed_at,
'user_system_notifications.seen_at'
'user_system_notifications.seen_at',
'user_system_notifications.read_at'
)
end

View file

@ -486,6 +486,11 @@ class User < ApplicationRecord
user_identities.where(provider: provider).exists?
end
# This method must be overwriten for addons that will be installed
def show_login_system_notification?
user_system_notifications.show_on_login.present?
end
# json friendly attributes
NOTIFICATIONS_TYPES = %w(assignments_notification recent_notification
assignments_email_notification

View file

@ -4,8 +4,40 @@ class UserSystemNotification < ApplicationRecord
belongs_to :user
belongs_to :system_notification
def self.mark_as_seen(notifications)
where(system_notification_id: notifications)
def self.mark_as_seen(notifications_id)
where(system_notification_id: notifications_id)
.update_all(seen_at: Time.now)
end
def self.mark_as_read(notification_id)
notification = find_by_system_notification_id(notification_id)
if notification && notification.read_at.nil?
notification.update(read_at: Time.now)
end
end
def self.show_on_login(update_read_time = false)
# for notification check leave update_read_time empty
notification = joins(:system_notification)
.where('system_notifications.show_on_login = true')
.order('system_notifications.last_time_changed_at DESC')
.select(
:modal_title,
:modal_body,
'user_system_notifications.id',
:read_at,
:user_id,
:system_notification_id
)
.first
if notification && notification.read_at.nil?
if update_read_time
notification.update(
read_at: Time.now,
seen_at: Time.now
)
end
notification
end
end
end

View file

@ -40,6 +40,9 @@
<%= render "shared/about_modal" %>
<%= render "shared/file_preview_modal.html.erb" %>
<%= render "shared/navigation" %>
<% if user_signed_in? && flash[:system_notification_modal] && current_user.show_login_system_notification? %>
<%= render partial: "/system_notifications/system_notification_modal", locals: { notification: current_user.user_system_notifications.show_on_login(true) } %>
<% end %>
<% unless user_signed_in? %>
<%= render partial: 'shared/flash_alerts',

View file

@ -1,12 +1,15 @@
<div
class="system-notification"
data-new="<%= notification.seen_at ? 0 : 1 %>"
data-unread="<%= notification.read_at ? 0 : 1 %>"
data-system-notification-id="<%= notification.id %>"
>
<div class="status-block">
<div class="status-icon <%= notification.seen_at ? "seen" : "" %>">
<i class="fas fa-gift"></i>
</div>
<%= link_to system_notification_path(notification.id, format: :json), class: "modal-system-notification", remote: true do %>
<div class="status-icon <%= notification.seen_at ? "seen" : "" %>">
<i class="fas fa-gift"></i>
</div>
<% end %>
</div>
<div class="body-block">
<div class="datetime">

View file

@ -0,0 +1,21 @@
<div class="modal" id="manage-module-system-notification-modal" tabindex="-1" role="dialog" aria-labelledby="manage-module-system-notification-modal-label">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="manage-module-system-notification-modal-label">
<%= notification ? notification.modal_title.html_safe : '' %>
</h4>
</div>
<div class="modal-body">
<%= notification ? notification.modal_body.html_safe : '' %>
</div>
</div>
</div>
</div>
<% if notification %>
<script>
$('#manage-module-system-notification-modal').modal('show')
</script>
<% end %>

View file

@ -1,4 +1,7 @@
<% provide(:head_title, t("system_notifications.index.whats_new")) %>
<%= render partial: "system_notification_modal", locals: { notification: nil} %>
<div class="content-pane" id="system-notifications-index">
<h3 class="title-container">
<strong><%= t("system_notifications.index.whats_new") %></strong>

View file

@ -426,10 +426,13 @@ Rails.application.routes.draw do
end
# System notifications routes
resources :system_notifications, only: [:index] do
resources :system_notifications, only: [:index,:show] do
collection do
post 'mark_as_seen'
end
member do
post 'mark_as_read'
end
end
# tinyMCE image uploader endpoint

View file

@ -23,4 +23,4 @@ if User.count.zero?
[],
Extends::INITIAL_USER_OPTIONS
)
end
end

8996
yarn.lock Normal file

File diff suppressed because it is too large Load diff