mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-27 10:14:17 +08:00
Merge pull request #1514 from biosistemika/features/system-notifications
Features/system notifications
This commit is contained in:
commit
bcd0b433b6
10 changed files with 60 additions and 75 deletions
|
@ -113,6 +113,7 @@
|
||||||
button
|
button
|
||||||
.on('click', function() {
|
.on('click', function() {
|
||||||
noRecentText.hide();
|
noRecentText.hide();
|
||||||
|
$('.dropdown-system-notifications .system-notification').remove();
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: button.attr('data-href'),
|
url: button.attr('data-href'),
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
|
@ -120,12 +121,6 @@
|
||||||
beforeSend: animateSpinner($('.system-notifications-dropdown-header'), true),
|
beforeSend: animateSpinner($('.system-notifications-dropdown-header'), true),
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
var ul = $('.dropdown-system-notifications');
|
var ul = $('.dropdown-system-notifications');
|
||||||
// After closing system notification modal release system notifications dropdown
|
|
||||||
$('#manage-module-system-notification-modal').on('hidden.bs.modal', function() {
|
|
||||||
setTimeout(function() {
|
|
||||||
$('.dropdown.system-notifications')[0].dataset.closable = true;
|
|
||||||
}, 100);
|
|
||||||
});
|
|
||||||
$('.system-notifications-dropdown-header')
|
$('.system-notifications-dropdown-header')
|
||||||
.nextAll('.system-notification')
|
.nextAll('.system-notification')
|
||||||
.remove();
|
.remove();
|
||||||
|
@ -136,7 +131,7 @@
|
||||||
noRecentText.show();
|
noRecentText.show();
|
||||||
}
|
}
|
||||||
bindSystemNotificationAjax();
|
bindSystemNotificationAjax();
|
||||||
SystemNotificationsMarkAsSeen('.dropdown-system-notifications');
|
SystemNotificationsMarkAsSeen();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('#count-system-notifications').hide();
|
$('#count-system-notifications').hide();
|
||||||
|
@ -146,15 +141,5 @@
|
||||||
|
|
||||||
// init
|
// init
|
||||||
loadDropdownSystemNotifications();
|
loadDropdownSystemNotifications();
|
||||||
$('.dropdown-system-notifications').scroll(function() {
|
|
||||||
SystemNotificationsMarkAsSeen('.dropdown-system-notifications');
|
|
||||||
});
|
|
||||||
loadUnseenNotificationsNumber('system-notifications', '.fa-gift');
|
loadUnseenNotificationsNumber('system-notifications', '.fa-gift');
|
||||||
// Override dropdown menu closing action while system notification modal open
|
|
||||||
$('.dropdown.system-notifications').on('hide.bs.dropdown', function() {
|
|
||||||
if (this.dataset.closable === 'false') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,18 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// update selected notiifcations
|
// update selected notiifcations
|
||||||
function SystemNotificationsMarkAsSeen(container = window) {
|
function SystemNotificationsMarkAsSeen() {
|
||||||
var WindowSize = $(container).height();
|
if ($('.system-notification[data-new="1"]').length > 0) {
|
||||||
var NotificationsToUpdate = [];
|
$.post('/system_notifications/mark_as_seen');
|
||||||
_.each($('.system-notification[data-new="1"]'), function(el) {
|
|
||||||
var NotificationTopPosition = el.getBoundingClientRect().top;
|
|
||||||
if (NotificationTopPosition > 0 && NotificationTopPosition < WindowSize) {
|
|
||||||
NotificationsToUpdate.push(el.dataset.systemNotificationId);
|
|
||||||
el.dataset.new = 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (NotificationsToUpdate.length > 0) {
|
|
||||||
$.post('/system_notifications/mark_as_seen', { notifications: JSON.stringify(NotificationsToUpdate) });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,13 +18,15 @@ function bindSystemNotificationAjax() {
|
||||||
|
|
||||||
$('.modal-system-notification')
|
$('.modal-system-notification')
|
||||||
.on('ajax:success', function(ev, data) {
|
.on('ajax:success', function(ev, data) {
|
||||||
var SystemNotification = $('.system-notification[data-system-notification-id=' + data.id + ']')[0];
|
var SystemNotification = $('.system-notification[data-system-notification-id=' + data.id + ']');
|
||||||
SystemNotificationModalBody.html(data.modal_body);
|
SystemNotificationModalBody.html(data.modal_body);
|
||||||
SystemNotificationModalTitle.text(data.modal_title);
|
SystemNotificationModalTitle.text(data.modal_title);
|
||||||
$('.dropdown.system-notifications')[0].dataset.closable = false;
|
$('.dropdown.system-notifications').removeClass('open');
|
||||||
// Open modal
|
// Open modal
|
||||||
SystemNotificationModal.modal('show');
|
SystemNotificationModal.modal('show');
|
||||||
if (SystemNotification.dataset.unread === '1') {
|
if (SystemNotification[0].dataset.unread === '1') {
|
||||||
|
$.each(SystemNotification, (index, e) => { e.dataset.unread = '0'; });
|
||||||
|
SystemNotification.find('.status-icon').addClass('seen');
|
||||||
$.post('/system_notifications/' + data.id + '/mark_as_read');
|
$.post('/system_notifications/' + data.id + '/mark_as_read');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -42,7 +35,7 @@ function bindSystemNotificationAjax() {
|
||||||
function initSystemNotificationsButton() {
|
function initSystemNotificationsButton() {
|
||||||
$('.btn-more-notifications')
|
$('.btn-more-notifications')
|
||||||
.on('ajax:success', function(e, data) {
|
.on('ajax:success', function(e, data) {
|
||||||
$(data.html).insertAfter($('.notifications-container .system-notification').last());
|
$(data.html).insertAfter($('.system-notifications-container .system-notification').last());
|
||||||
bindSystemNotificationAjax();
|
bindSystemNotificationAjax();
|
||||||
if (data.more_url) {
|
if (data.more_url) {
|
||||||
$(this).attr('href', data.more_url);
|
$(this).attr('href', data.more_url);
|
||||||
|
@ -52,9 +45,6 @@ function initSystemNotificationsButton() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$(window).scroll(function() {
|
|
||||||
SystemNotificationsMarkAsSeen();
|
|
||||||
});
|
|
||||||
initSystemNotificationsButton();
|
initSystemNotificationsButton();
|
||||||
SystemNotificationsMarkAsSeen();
|
SystemNotificationsMarkAsSeen();
|
||||||
bindSystemNotificationAjax();
|
bindSystemNotificationAjax();
|
||||||
|
|
|
@ -13,6 +13,16 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
&[data-unread="0"] {
|
||||||
|
|
||||||
|
.body-block {
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: $color-concrete;
|
background: $color-concrete;
|
||||||
opacity: .7;
|
opacity: .7;
|
||||||
|
@ -55,6 +65,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
font-weight: bold;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
@ -71,9 +82,11 @@
|
||||||
#system-notifications-index {
|
#system-notifications-index {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
#search-bar-notifications {
|
#search-bar-notifications {
|
||||||
border-bottom: 1px solid $color-gainsboro;
|
border-bottom: 1px solid $color-gainsboro;
|
||||||
|
display: none;
|
||||||
margin: 10px 0 0;
|
margin: 10px 0 0;
|
||||||
padding: 0 0 10px;
|
padding: 0 0 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -111,3 +124,11 @@
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#manage-module-system-notification-modal {
|
||||||
|
.modal-title {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
.modal-body {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -24,8 +24,7 @@ class SystemNotificationsController < ApplicationController
|
||||||
|
|
||||||
# Update seen_at parameter for system notifications
|
# Update seen_at parameter for system notifications
|
||||||
def mark_as_seen
|
def mark_as_seen
|
||||||
notifications = JSON.parse(params[:notifications])
|
current_user.user_system_notifications.mark_as_seen
|
||||||
current_user.user_system_notifications.mark_as_seen(notifications)
|
|
||||||
render json: { result: 'ok' }
|
render json: { result: 'ok' }
|
||||||
rescue StandardError
|
rescue StandardError
|
||||||
render json: { result: 'failed' }
|
render json: { result: 'failed' }
|
||||||
|
|
|
@ -9,9 +9,8 @@ class UserSystemNotification < ApplicationRecord
|
||||||
|
|
||||||
scope :unseen, -> { where(seen_at: nil) }
|
scope :unseen, -> { where(seen_at: nil) }
|
||||||
|
|
||||||
def self.mark_as_seen(notifications_id)
|
def self.mark_as_seen
|
||||||
where(system_notification_id: notifications_id)
|
unseen.update_all(seen_at: Time.now)
|
||||||
.update_all(seen_at: Time.now)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.mark_as_read(notification_id)
|
def self.mark_as_read(notification_id)
|
||||||
|
|
|
@ -1,25 +1,24 @@
|
||||||
<%= link_to system_notification_path(notification.id, format: :json), class: "modal-system-notification", remote: true do %>
|
<%= link_to system_notification_path(notification.id, format: :json), {
|
||||||
<div
|
class: "modal-system-notification system-notification",
|
||||||
class="system-notification"
|
'data-new': notification.seen_at ? 0 : 1,
|
||||||
data-new="<%= notification.seen_at ? 0 : 1 %>"
|
'data-unread': notification.read_at ? 0 : 1,
|
||||||
data-unread="<%= notification.read_at ? 0 : 1 %>"
|
'data-system-notification-id': notification.id,
|
||||||
data-system-notification-id="<%= notification.id %>"
|
remote: true
|
||||||
>
|
} do %>
|
||||||
<div class="status-block">
|
<div class="status-block">
|
||||||
<div class="status-icon <%= notification.seen_at ? "seen" : "" %>">
|
<div class="status-icon <%= notification.read_at ? "seen" : "" %>">
|
||||||
<i class="fas fa-gift"></i>
|
<i class="fas fa-gift"></i>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="body-block">
|
</div>
|
||||||
<div class="datetime">
|
<div class="body-block">
|
||||||
<span><%= l(notification.last_time_changed_at, format: :full) %></span>
|
<div class="datetime">
|
||||||
</div>
|
<span><%= l(notification.last_time_changed_at, format: :full) %></span>
|
||||||
<h5 class="title">
|
</div>
|
||||||
<strong><%= notification.title %></strong>
|
<h5 class="title">
|
||||||
</h5>
|
<%= notification.title %>
|
||||||
<div class="message">
|
</h5>
|
||||||
<span><%= notification.description %></span>
|
<div class="message">
|
||||||
</div>
|
<span><%= notification.description %></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<div class="notifications-container">
|
<div class="system-notifications-container">
|
||||||
<%= render partial: "list", locals: { notifications: @system_notifications[:notifications] } %>
|
<%= render partial: "list", locals: { notifications: @system_notifications[:notifications] } %>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
|
|
|
@ -1297,10 +1297,10 @@ en:
|
||||||
intro_paragraph: "Hi %{user_name}, you've received What's new notification in SciNote:"
|
intro_paragraph: "Hi %{user_name}, you've received What's new notification in SciNote:"
|
||||||
index:
|
index:
|
||||||
whats_new: "What's New"
|
whats_new: "What's New"
|
||||||
more_notifications: "More system notifications"
|
more_notifications: "Show more notifications"
|
||||||
no_notifications: "No more system notifications"
|
no_notifications: "No more notifications"
|
||||||
settings: "Settings"
|
settings: "Settings"
|
||||||
see_all: "See all"
|
see_all: "show all"
|
||||||
activities:
|
activities:
|
||||||
index:
|
index:
|
||||||
today: "Today"
|
today: "Today"
|
||||||
|
|
|
@ -41,14 +41,6 @@ describe SystemNotificationsController, type: :controller do
|
||||||
expect(user.user_system_notifications.where(seen_at: nil).count).to eq 0
|
expect(user.user_system_notifications.where(seen_at: nil).count).to eq 0
|
||||||
end
|
end
|
||||||
|
|
||||||
it '#mark_as_seen response failed on wrong id\'s format' do
|
|
||||||
params = { notifications: 'wrong format' }
|
|
||||||
get :mark_as_seen, format: :json, params: params
|
|
||||||
expect(response).to have_http_status(:ok)
|
|
||||||
body = JSON.parse(response.body)
|
|
||||||
expect(body['result']).to eq 'failed'
|
|
||||||
end
|
|
||||||
|
|
||||||
it '#mark_as_read correctly set read_at' do
|
it '#mark_as_read correctly set read_at' do
|
||||||
params = {
|
params = {
|
||||||
id: user.user_system_notifications.first.system_notification_id
|
id: user.user_system_notifications.first.system_notification_id
|
||||||
|
|
|
@ -55,7 +55,7 @@ describe UserSystemNotification do
|
||||||
user: user,
|
user: user,
|
||||||
system_notification: notifcation_one
|
system_notification: notifcation_one
|
||||||
notifications_to_update = [usn.system_notification_id]
|
notifications_to_update = [usn.system_notification_id]
|
||||||
user.user_system_notifications.mark_as_seen(notifications_to_update)
|
user.user_system_notifications.mark_as_seen
|
||||||
expect(UserSystemNotification.find(usn.id).seen_at).not_to be_nil
|
expect(UserSystemNotification.find(usn.id).seen_at).not_to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue