mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-12 04:23:19 +00:00
PHRAS-3442_optimize-list-notifications_4.1-bis
WIP poll only from menubar (Aina) back : only one method/route to fetch notifs front : fix exponential pagination big refacto todo : mark read notifications (button ? click ?)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import $ from 'jquery';
|
||||
import ui from '../ui';
|
||||
import notify from '../notify';
|
||||
|
||||
// poll notification is now from menu bar
|
||||
// so this is never called
|
||||
const basket = () => {
|
||||
|
||||
const onUpdatedContent = (data) => {
|
||||
|
@@ -4,6 +4,8 @@ import notifyService from './notifyService';
|
||||
import * as Rx from 'rx';
|
||||
import merge from 'lodash.merge';
|
||||
|
||||
|
||||
// this module is now unused, poll notification is from menu bar
|
||||
const notify = (services) => {
|
||||
|
||||
const { configService, localeService, appEvents } = services;
|
||||
@@ -63,9 +65,9 @@ const notify = (services) => {
|
||||
appEvents.emit('notification.refresh', data);
|
||||
}
|
||||
// append notification content
|
||||
notifyLayout(services).addNotifications(data.notifications);
|
||||
// notifyLayout(services).addNotifications(data.notifications);
|
||||
|
||||
window.setTimeout(poll, defaultPollingTime, notificationInstance);
|
||||
// window.setTimeout(poll, defaultPollingTime, notificationInstance);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import $ from 'jquery';
|
||||
import dialog from './../../phraseanet-common/components/dialog';
|
||||
// import user from '../user/index.js';
|
||||
|
||||
|
||||
@@ -8,34 +7,34 @@ const notifyLayout = (services) => {
|
||||
const $notificationBoxContainer = $('#notification_box');
|
||||
const $notificationTrigger = $('.notification_trigger');
|
||||
let $notificationDialog = $('#notifications-dialog');
|
||||
let $notificationsContent = null;
|
||||
let $notificationsNavigation = null;
|
||||
|
||||
const initialize = () => {
|
||||
/**
|
||||
* click on menubar/notifications : drop a box with last 10 notification, and a button "see all"
|
||||
* the box content is already set by poll notifications
|
||||
*/
|
||||
$notificationTrigger.on('mousedown', (event) => {
|
||||
event.stopPropagation();
|
||||
const $target = $(event.currentTarget);
|
||||
if ($target.hasClass('open')) {
|
||||
$notificationBoxContainer.hide();
|
||||
$target.removeClass('open');
|
||||
clear_notifications();
|
||||
} else {
|
||||
$notificationBoxContainer.show();
|
||||
|
||||
setBoxHeight();
|
||||
|
||||
$target.addClass('open');
|
||||
read_notifications();
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('mousedown', () => {
|
||||
if ($notificationTrigger.hasClass('open')) {
|
||||
$notificationTrigger.trigger('click');
|
||||
}
|
||||
|
||||
// toggle
|
||||
if ($notificationTrigger.hasClass('open')) {
|
||||
$notificationBoxContainer.hide();
|
||||
$notificationTrigger.removeClass('open');
|
||||
clear_notifications();
|
||||
}
|
||||
else {
|
||||
$notificationTrigger.addClass('open');
|
||||
$notificationBoxContainer.show();
|
||||
setBoxHeight();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* close on every mousedown
|
||||
*/
|
||||
$(document).on('mousedown', () => {
|
||||
$notificationBoxContainer.hide();
|
||||
$notificationTrigger.removeClass('open');
|
||||
});
|
||||
|
||||
$notificationBoxContainer
|
||||
@@ -48,11 +47,14 @@ const notifyLayout = (services) => {
|
||||
.on('mouseout', '.notification', (event) => {
|
||||
$(event.currentTarget).removeClass('hover');
|
||||
})
|
||||
/**
|
||||
* click on "see all notification"
|
||||
*/
|
||||
.on('click', '.notification__print-action', (event) => {
|
||||
event.preventDefault();
|
||||
const $el = $(event.currentTarget);
|
||||
const page = $el.data('page');
|
||||
print_notifications(page);
|
||||
$notificationBoxContainer.hide();
|
||||
$notificationTrigger.removeClass('open');
|
||||
print_notifications(0);
|
||||
});
|
||||
|
||||
$(window).bind('resize', function () {
|
||||
@@ -62,24 +64,24 @@ const notifyLayout = (services) => {
|
||||
|
||||
};
|
||||
|
||||
const addNotifications = (notificationContent) => {
|
||||
// var box = $('#notification_box');
|
||||
$notificationBoxContainer.empty().append(notificationContent);
|
||||
|
||||
if ($notificationBoxContainer.is(':visible')) {
|
||||
setBoxHeight();
|
||||
}
|
||||
|
||||
if ($('.notification.unread', $notificationBoxContainer).length > 0) {
|
||||
$('.counter', $notificationTrigger)
|
||||
.empty()
|
||||
.append($('.notification.unread', $notificationBoxContainer).length);
|
||||
$('.counter', $notificationTrigger).css('visibility', 'visible');
|
||||
|
||||
} else {
|
||||
$('.notification_trigger .counter').css('visibility', 'hidden').empty();
|
||||
}
|
||||
};
|
||||
// const addNotifications = (notificationContent) => {
|
||||
// // var box = $('#notification_box');
|
||||
// $notificationBoxContainer.empty().append(notificationContent);
|
||||
//
|
||||
// if ($notificationBoxContainer.is(':visible')) {
|
||||
// setBoxHeight();
|
||||
// }
|
||||
//
|
||||
// if ($('.notification.unread', $notificationBoxContainer).length > 0) {
|
||||
// $('.counter', $notificationTrigger)
|
||||
// .empty()
|
||||
// .append($('.notification.unread', $notificationBoxContainer).length);
|
||||
// $('.counter', $notificationTrigger).css('visibility', 'visible');
|
||||
//
|
||||
// } else {
|
||||
// $('.notification_trigger .counter').css('visibility', 'hidden').empty();
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
const setBoxHeight = () => {
|
||||
@@ -110,20 +112,32 @@ const notifyLayout = (services) => {
|
||||
}
|
||||
};
|
||||
|
||||
const print_notifications = (page) => {
|
||||
/**
|
||||
* add 10 notifications into the dlgbox
|
||||
* display the button "load more" while relevant
|
||||
*
|
||||
* @param offset
|
||||
*/
|
||||
const print_notifications = (offset) => {
|
||||
|
||||
page = parseInt(page, 10);
|
||||
offset = parseInt(offset, 10);
|
||||
var buttons = {};
|
||||
|
||||
buttons[localeService.t('fermer')] = function () {
|
||||
$notificationDialog.dialog('close');
|
||||
};
|
||||
|
||||
// create the dlg div if it does not exists
|
||||
//
|
||||
if ($notificationDialog.length === 0) {
|
||||
$('body').append('<div id="notifications-dialog" class="loading"></div>');
|
||||
$('body').append('<div id="notifications-dialog"><div class="content"></div><div class="navigation"></div></div>');
|
||||
$notificationDialog = $('#notifications-dialog');
|
||||
$notificationsContent = $('.content', $notificationDialog);
|
||||
$notificationsNavigation = $('.navigation', $notificationDialog);
|
||||
}
|
||||
|
||||
// open the dlg (even if it is already opened when "load more")
|
||||
//
|
||||
$notificationDialog
|
||||
.dialog({
|
||||
title: $('#notification-title').val(),
|
||||
@@ -141,20 +155,22 @@ const notifyLayout = (services) => {
|
||||
close: function (event, ui) {
|
||||
$notificationDialog.dialog('destroy').remove();
|
||||
}
|
||||
}).dialog('option', 'buttons', buttons).dialog('open').on('click','.notification_next .notification__print-action', function (event) {
|
||||
event.preventDefault();
|
||||
var $el = $(event.currentTarget);
|
||||
var page = $el.data('page');
|
||||
print_notifications(page);
|
||||
});
|
||||
|
||||
})
|
||||
.dialog('option', 'buttons', buttons)
|
||||
.dialog('open');
|
||||
|
||||
// load 10 (more) notifications
|
||||
//
|
||||
$notificationDialog.addClass('loading');
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: '/user/notifications/',
|
||||
type: 'POST',
|
||||
// url: '/user/notifications/',
|
||||
url: '/session/notifications/',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
page: page
|
||||
'offset': offset,
|
||||
'limit': 10,
|
||||
'what': 3, // 3 = read | unread
|
||||
},
|
||||
error: function (data) {
|
||||
$notificationDialog.removeClass('loading');
|
||||
@@ -165,47 +181,55 @@ const notifyLayout = (services) => {
|
||||
success: function (data) {
|
||||
$notificationDialog.removeClass('loading');
|
||||
|
||||
|
||||
if (page === 0) {
|
||||
$notificationDialog.empty();
|
||||
} else {
|
||||
$('.notification_next', $notificationDialog).remove();
|
||||
if (offset === 0) {
|
||||
$notificationsContent.empty();
|
||||
}
|
||||
|
||||
const notifications = data.notifications.notifications;
|
||||
let i = 0;
|
||||
for (i in data.notifications) {
|
||||
var id = 'notif_date_' + i;
|
||||
var date_cont = $('#' + id);
|
||||
if (date_cont.length === 0) {
|
||||
$notificationDialog.append('<div id="' + id + '"><div class="notification_title">' + data.notifications[i].display + '</div></div>');
|
||||
date_cont = $('#' + id);
|
||||
}
|
||||
for (i in notifications) {
|
||||
const notification = notifications[i];
|
||||
|
||||
let j = 0;
|
||||
for (j in data.notifications[i].notifications) {
|
||||
var loc_dat = data.notifications[i].notifications[j];
|
||||
var html = '<div style="position:relative;" id="notification_' + loc_dat.id + '" class="notification">' +
|
||||
'<table style="width:100%;" cellspacing="0" cellpadding="0" border="0"><tr><td style="width:25px;">' +
|
||||
loc_dat.icon +
|
||||
'</td><td>' +
|
||||
'<div style="position:relative;" class="' + loc_dat.classname + '">' +
|
||||
loc_dat.text + ' <span class="time">' + loc_dat.time + '</span></div>' +
|
||||
'</td></tr></table>' +
|
||||
'</div>';
|
||||
date_cont.append(html);
|
||||
// group notifs by day
|
||||
//
|
||||
const date = notification.created_on_day;
|
||||
const id = 'notif_date_' + date;
|
||||
let date_cont = $('#' + id, $notificationsContent);
|
||||
if (date_cont.length === 0) {
|
||||
$notificationsContent.append('<div id="' + id + '"><div class="notification_title">' + notifications[i].created_on + '</div></div>');
|
||||
date_cont = $('#' + id, $notificationsContent);
|
||||
}
|
||||
// write notif
|
||||
let html = '<div style="position:relative;" id="notification_' + notification.id + '" class="notification">' +
|
||||
'<table style="width:100%;" cellspacing="0" cellpadding="0" border="0"><tr style="border-top: 1px grey solid"><td style="width:25px; vertical-align: top;">' +
|
||||
'<img src="' + notification.icon + '" style="vertical-align:middle;width:16px;margin:2px;" />' +
|
||||
'</td><td style="vertical-align: top;">' +
|
||||
'<div style="position:relative;" class="' + notification.classname + '">' +
|
||||
notification.text + ' <span class="time">' + notification.time + '</span></div>' +
|
||||
'</td></tr></table>' +
|
||||
'</div>';
|
||||
date_cont.append(html);
|
||||
}
|
||||
|
||||
var next_ln = $.trim(data.next);
|
||||
|
||||
if (next_ln !== '') {
|
||||
$notificationDialog.append('<div class="notification_next">' + next_ln + '</div>');
|
||||
if (data.notifications.next_page_html) {
|
||||
$notificationsNavigation
|
||||
.off('click', '.notification__print-action');
|
||||
$notificationsNavigation.empty().show().append(data.notifications.next_page_html);
|
||||
$notificationsNavigation
|
||||
.on('click', '.notification__print-action', function (event) {
|
||||
event.preventDefault();
|
||||
let $el = $(event.currentTarget);
|
||||
let offset = $el.data('offset');
|
||||
print_notifications(offset);
|
||||
});
|
||||
}
|
||||
else {
|
||||
$notificationsNavigation.empty().hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/* remove in favor of existing /session/ route
|
||||
const read_notifications = () => {
|
||||
var notifications = [];
|
||||
|
||||
@@ -236,9 +260,10 @@ const notifyLayout = (services) => {
|
||||
$('.notification_trigger .counter').css('visibility', 'hidden').empty();
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
return {
|
||||
initialize,
|
||||
addNotifications
|
||||
initialize
|
||||
};
|
||||
};
|
||||
|
||||
|
@@ -2,6 +2,7 @@ import {Observable} from 'rx';
|
||||
// import {ajax} from 'jquery';
|
||||
import $ from 'jquery';
|
||||
|
||||
// module unused now 06-2021
|
||||
let recordService = (services) => {
|
||||
const {configService} = services;
|
||||
const url = configService.get('baseUrl');
|
||||
|
@@ -1,7 +1,4 @@
|
||||
import $ from 'jquery';
|
||||
import ui from '../ui';
|
||||
import notify from '../notify';
|
||||
import * as appCommons from './../../phraseanet-common';
|
||||
|
||||
const user = (services) => {
|
||||
const { configService, localeService, appEvents } = services;
|
||||
@@ -19,53 +16,43 @@ const user = (services) => {
|
||||
'user.disconnected': onUserDisconnect
|
||||
});
|
||||
|
||||
const manageSession = (...params) => {
|
||||
let [data, showMessages] = params;
|
||||
// const manageSession = (...params) => {
|
||||
// let [data, showMessages] = params;
|
||||
//
|
||||
// if (typeof (showMessages) === 'undefined') {
|
||||
// showMessages = false;
|
||||
// }
|
||||
//
|
||||
// if (showMessages) {
|
||||
// // @todo: to be moved
|
||||
// if ($.trim(data.message) !== '') {
|
||||
// if ($('#MESSAGE').length === 0) {
|
||||
// $('body').append('<div id="#MESSAGE"></div>');
|
||||
// }
|
||||
// $('#MESSAGE')
|
||||
// .empty()
|
||||
// .append(data.message + '<div style="margin:20px;"><input type="checkbox" class="dialog_remove" />' + localeService.t('hideMessage') + '</div>')
|
||||
// .attr('title', 'Global Message')
|
||||
// .dialog({
|
||||
// autoOpen: false,
|
||||
// closeOnEscape: true,
|
||||
// resizable: false,
|
||||
// draggable: false,
|
||||
// modal: true,
|
||||
// close: function () {
|
||||
// if ($('.dialog_remove:checked', $(this)).length > 0) {
|
||||
// // @TODO get from module
|
||||
// appCommons.userModule.setTemporaryPref('message', 0);
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .dialog('open');
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
// };
|
||||
|
||||
if (typeof (showMessages) === 'undefined') {
|
||||
showMessages = false;
|
||||
}
|
||||
|
||||
if (showMessages) {
|
||||
// @todo: to be moved
|
||||
if ($.trim(data.message) !== '') {
|
||||
if ($('#MESSAGE').length === 0) {
|
||||
$('body').append('<div id="#MESSAGE"></div>');
|
||||
}
|
||||
$('#MESSAGE')
|
||||
.empty()
|
||||
.append(data.message + '<div style="margin:20px;"><input style="margin-right:10px;" type="checkbox" class="dialog_remove" />' + localeService.t('hideMessage') + '</div>')
|
||||
.attr('title', 'Global Message')
|
||||
.dialog({
|
||||
autoOpen: false,
|
||||
closeOnEscape: true,
|
||||
resizable: false,
|
||||
draggable: false,
|
||||
modal: true,
|
||||
close: function () {
|
||||
if ($('.dialog_remove:checked', $(this)).length > 0) {
|
||||
// setTemporaryPref
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/user/preferences/temporary/",
|
||||
data: {
|
||||
prop: 'message',
|
||||
value: 0
|
||||
},
|
||||
success: function (data) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.dialog('open');
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
return {initialize, manageSession};
|
||||
return {initialize};
|
||||
};
|
||||
|
||||
export default user;
|
||||
|
@@ -36,7 +36,7 @@
|
||||
/* eslint-disable no-loop-func*/
|
||||
|
||||
import $ from 'jquery';
|
||||
import dialog from './dialog';
|
||||
|
||||
let cookie = require('js-cookie');
|
||||
|
||||
const initialize = () => {
|
||||
@@ -56,93 +56,92 @@ const initialize = () => {
|
||||
};
|
||||
|
||||
// @deprecated
|
||||
function manageSession(data, showMessages) {
|
||||
if (typeof (showMessages) === 'undefined')
|
||||
showMessages = false;
|
||||
|
||||
if (data.status === 'disconnected' || data.status === 'session') {
|
||||
disconnected();
|
||||
return false;
|
||||
}
|
||||
if (showMessages) {
|
||||
let box = $('#notification_box');
|
||||
box.empty().append(data.notifications);
|
||||
|
||||
if (box.is(':visible'))
|
||||
fix_notification_height();
|
||||
|
||||
if ($('.notification.unread', box).length > 0) {
|
||||
let trigger = $('#notification_trigger');
|
||||
$('.counter', trigger)
|
||||
.empty()
|
||||
.append($('.notification.unread', box).length);
|
||||
$('.counter', trigger).css('visibility', 'visible');
|
||||
|
||||
}
|
||||
else
|
||||
$('#notification_trigger .counter').css('visibility', 'hidden').empty();
|
||||
|
||||
if (data.changed.length > 0) {
|
||||
let current_open = $('.SSTT.ui-state-active');
|
||||
let current_sstt = current_open.length > 0 ? current_open.attr('id').split('_').pop() : false;
|
||||
|
||||
let main_open = false;
|
||||
for (let i = 0; i !== data.changed.length; i++) {
|
||||
let sstt = $('#SSTT_' + data.changed[i]);
|
||||
if (sstt.size() === 0) {
|
||||
if (main_open === false) {
|
||||
$('#baskets .bloc').animate({'top': 30}, function () {
|
||||
$('#baskets .alert_datas_changed:first').show();
|
||||
});
|
||||
main_open = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!sstt.hasClass('active'))
|
||||
sstt.addClass('unread');
|
||||
else {
|
||||
$('.alert_datas_changed', $('#SSTT_content_' + data.changed[i])).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($.trim(data.message) !== '') {
|
||||
if ($('#MESSAGE').length === 0)
|
||||
$('body').append('<div id="#MESSAGE"></div>');
|
||||
$('#MESSAGE')
|
||||
.empty()
|
||||
.append('<div style="margin:30px 10px;"><h4><b>' + data.message + '</b></h4></div><div style="margin:20px 0px 10px;"><label class="checkbox"><input type="checkbox" class="dialog_remove" />' + language.hideMessage + '</label></div>')
|
||||
.attr('title', 'Global Message')
|
||||
.dialog({
|
||||
autoOpen: false,
|
||||
closeOnEscape: true,
|
||||
resizable: false,
|
||||
draggable: false,
|
||||
modal: true,
|
||||
close: function () {
|
||||
if ($('.dialog_remove:checked', $(this)).length > 0) {
|
||||
// setTemporaryPref
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '/user/preferences/temporary/',
|
||||
data: {
|
||||
prop: 'message',
|
||||
value: 0
|
||||
},
|
||||
success: function (data) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.dialog('open');
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// function manageSession(data, showMessages) {
|
||||
// if (typeof (showMessages) === 'undefined')
|
||||
// showMessages = false;
|
||||
//
|
||||
// if (data.status === 'disconnected' || data.status === 'session') {
|
||||
// disconnected();
|
||||
// return false;
|
||||
// }
|
||||
// if (showMessages) {
|
||||
// let box = $('#notification_box');
|
||||
// box.empty().append(data.notifications);
|
||||
//
|
||||
// if (box.is(':visible'))
|
||||
// fix_notification_height();
|
||||
//
|
||||
// if ($('.notification.unread', box).length > 0) {
|
||||
// let trigger = $('#notification_trigger');
|
||||
// $('.counter', trigger)
|
||||
// .empty()
|
||||
// .append($('.notification.unread', box).length);
|
||||
// $('.counter', trigger).css('visibility', 'visible');
|
||||
//
|
||||
// }
|
||||
// else
|
||||
// $('#notification_trigger .counter').css('visibility', 'hidden').empty();
|
||||
//
|
||||
// if (data.changed.length > 0) {
|
||||
// let current_open = $('.SSTT.ui-state-active');
|
||||
// let current_sstt = current_open.length > 0 ? current_open.attr('id').split('_').pop() : false;
|
||||
//
|
||||
// let main_open = false;
|
||||
// for (let i = 0; i !== data.changed.length; i++) {
|
||||
// let sstt = $('#SSTT_' + data.changed[i]);
|
||||
// if (sstt.size() === 0) {
|
||||
// if (main_open === false) {
|
||||
// $('#baskets .bloc').animate({'top': 30}, function () {
|
||||
// $('#baskets .alert_datas_changed:first').show();
|
||||
// });
|
||||
// main_open = true;
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// if (!sstt.hasClass('active'))
|
||||
// sstt.addClass('unread');
|
||||
// else {
|
||||
// $('.alert_datas_changed', $('#SSTT_content_' + data.changed[i])).show();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if ($.trim(data.message) !== '') {
|
||||
// if ($('#MESSAGE').length === 0)
|
||||
// $('body').append('<div id="#MESSAGE"></div>');
|
||||
// $('#MESSAGE')
|
||||
// .empty()
|
||||
// .append('<div style="margin:30px 10px;"><h4><b>' + data.message + '</b></h4></div><div style="margin:20px 0px 10px;"><label class="checkbox"><input type="checkbox" class="dialog_remove" />' + language.hideMessage + '</label></div>')
|
||||
// .attr('title', 'Global Message')
|
||||
// .dialog({
|
||||
// autoOpen: false,
|
||||
// closeOnEscape: true,
|
||||
// resizable: false,
|
||||
// draggable: false,
|
||||
// modal: true,
|
||||
// close: function () {
|
||||
// if ($('.dialog_remove:checked', $(this)).length > 0) {
|
||||
// // setTemporaryPref
|
||||
// $.ajax({
|
||||
// type: 'POST',
|
||||
// url: '/user/preferences/temporary/',
|
||||
// data: {
|
||||
// prop: 'message',
|
||||
// value: 0
|
||||
// },
|
||||
// success: function (data) {
|
||||
// return;
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .dialog('open');
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
export default {
|
||||
initialize,
|
||||
manageSession
|
||||
initialize
|
||||
};
|
||||
|
@@ -1,15 +1,11 @@
|
||||
import $ from 'jquery';
|
||||
const humane = require('humane-js');
|
||||
require('imports-loader?define=>false&exports=>false!./../components/utils/jquery-plugins/colorAnimation');
|
||||
import * as AppCommons from './../phraseanet-common';
|
||||
import publication from '../components/publication';
|
||||
import workzone from '../components/ui/workzone';
|
||||
import notify from '../components/notify/index';
|
||||
import Locale from '../components/locale';
|
||||
import notifyLayout from '../components/notify/notifyLayout';
|
||||
import LocaleService from '../components/locale';
|
||||
import ui from '../components/ui';
|
||||
import ConfigService from './../components/core/configService';
|
||||
import LocaleService from '../components/locale';
|
||||
import i18next from 'i18next';
|
||||
import defaultConfig from './config';
|
||||
import Emitter from '../components/core/emitter';
|
||||
import user from '../components/user';
|
||||
@@ -18,6 +14,10 @@ import search from '../components/search';
|
||||
import utils from './../components/utils/utils';
|
||||
import dialog from './../phraseanet-common/components/dialog';
|
||||
import merge from 'lodash.merge';
|
||||
|
||||
const humane = require('humane-js');
|
||||
require('imports-loader?define=>false&exports=>false!./../components/utils/jquery-plugins/colorAnimation');
|
||||
|
||||
class Bootstrap {
|
||||
|
||||
app;
|
||||
@@ -69,27 +69,28 @@ class Bootstrap {
|
||||
|
||||
const userSession = user(this.appServices);
|
||||
|
||||
let appProdNotification = {
|
||||
url: this.configService.get('notify.url'),
|
||||
moduleId: this.configService.get('notify.moduleId'),
|
||||
userId: this.configService.get('notify.userId')
|
||||
};
|
||||
// let appProdNotification = {
|
||||
// url: this.configService.get('notify.url'),
|
||||
// moduleId: this.configService.get('notify.moduleId'),
|
||||
// userId: this.configService.get('notify.userId')
|
||||
// };
|
||||
|
||||
notifyLayout(this.appServices).initialize();
|
||||
|
||||
/**
|
||||
* Initialize notifier
|
||||
* @type {{bindEvents, createNotifier, isValid, poll}}
|
||||
* Poll just in menu_bar
|
||||
*/
|
||||
const notifier = notify(this.appServices);
|
||||
notifier.initialize();
|
||||
|
||||
// create a new notification poll:
|
||||
appProdNotification = notifier.createNotifier(appProdNotification);
|
||||
|
||||
if (notifier.isValid(appProdNotification)) {
|
||||
notifier.poll(appProdNotification);
|
||||
} else {
|
||||
throw new Error('implementation error: failed to configure new notifier');
|
||||
}
|
||||
// const notifier = notify(this.appServices);
|
||||
// notifier.initialize();
|
||||
//
|
||||
// // create a new notification poll:
|
||||
// appProdNotification = notifier.createNotifier(appProdNotification);
|
||||
//
|
||||
// if (notifier.isValid(appProdNotification)) {
|
||||
// notifier.poll(appProdNotification);
|
||||
// } else {
|
||||
// throw new Error('implementation error: failed to configure new notifier');
|
||||
// }
|
||||
|
||||
// @TODO remove global variables
|
||||
// register some global variables,
|
||||
|
@@ -11,10 +11,10 @@ namespace Alchemy\Phrasea\Controller\Root;
|
||||
|
||||
use Alchemy\Phrasea\Application\Helper\EntityManagerAware;
|
||||
use Alchemy\Phrasea\Controller\Controller;
|
||||
use Alchemy\Phrasea\Model\Entities\SessionModule;
|
||||
use Alchemy\Phrasea\Model\Repositories\BasketRepository;
|
||||
use Alchemy\Phrasea\Model\Repositories\SessionRepository;
|
||||
use Alchemy\Phrasea\Utilities\Stopwatch;
|
||||
use eventsmanager_broker;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@@ -42,10 +42,14 @@ class SessionController extends Controller
|
||||
'status' => 'unknown',
|
||||
'message' => '',
|
||||
'notifications' => false,
|
||||
'changed' => []
|
||||
'notifications_html' => false,
|
||||
'unread_basket_ids' => []
|
||||
];
|
||||
|
||||
$authenticator = $this->getAuthenticator();
|
||||
// every request is catched by SessionManagerSubscriber, which handles disconnect
|
||||
// so this code is probably useless
|
||||
/*
|
||||
if ($authenticator->isAuthenticated()) {
|
||||
$usr_id = $authenticator->getUser()->getId();
|
||||
if ($usr_id != $request->request->get('usr')) { // I logged with another user
|
||||
@@ -58,29 +62,39 @@ class SessionController extends Controller
|
||||
|
||||
return $this->app->json($ret);
|
||||
}
|
||||
*/
|
||||
|
||||
try {
|
||||
$this->getApplicationBox()->get_connection();
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
return $this->app->json($ret);
|
||||
}
|
||||
|
||||
// module id is only used to track apps, its done in SessioManagerSubscriber (parsing url)
|
||||
/*
|
||||
if (1 > $moduleId = (int) $request->request->get('module')) {
|
||||
$ret['message'] = 'Missing or Invalid `module` parameter';
|
||||
|
||||
return $this->app->json($ret);
|
||||
}
|
||||
*/
|
||||
|
||||
$ret['status'] = 'ok';
|
||||
|
||||
$stopwatch->lap("start");
|
||||
|
||||
$notifs = $this->getEventsManager()->get_notifications($stopwatch);
|
||||
$offset = (int)$request->get('offset', 0);
|
||||
$limit = (int)$request->get('limit', 10);
|
||||
$what = (int)$request->get('what', eventsmanager_broker::UNREAD | eventsmanager_broker::READ);
|
||||
|
||||
$notifications = $this->getEventsManager()->get_notifications($offset, $limit, $what, $stopwatch);
|
||||
|
||||
$stopwatch->lap("get_notifications done");
|
||||
|
||||
$ret['notifications'] = $this->render('prod/notifications.html.twig', [
|
||||
'notifications' => $notifs
|
||||
$ret['notifications'] = $notifications;
|
||||
$ret['notifications_html'] = $this->render('prod/notifications.html.twig', [
|
||||
'notifications' => $notifications['notifications']
|
||||
]);
|
||||
|
||||
$stopwatch->lap("render done");
|
||||
@@ -90,7 +104,7 @@ class SessionController extends Controller
|
||||
$stopwatch->lap("baskets::findUnreadActiveByUser done");
|
||||
|
||||
foreach ($baskets as $basket) {
|
||||
$ret['changed'][] = $basket->getId();
|
||||
$ret['unread_basket_ids'][] = $basket->getId();
|
||||
}
|
||||
|
||||
if (in_array($this->getSession()->get('phraseanet.message'), ['1', null])) {
|
||||
@@ -121,96 +135,6 @@ class SessionController extends Controller
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \Exception in case "new \DateTime()" fails ?
|
||||
*/
|
||||
public function updateSession(Request $request)
|
||||
{
|
||||
if (!$request->isXmlHttpRequest()) {
|
||||
$this->app->abort(400);
|
||||
}
|
||||
|
||||
$ret = [
|
||||
'status' => 'unknown',
|
||||
'message' => '',
|
||||
'notifications' => false,
|
||||
'changed' => []
|
||||
];
|
||||
|
||||
$authenticator = $this->getAuthenticator();
|
||||
if ($authenticator->isAuthenticated()) {
|
||||
$usr_id = $authenticator->getUser()->getId();
|
||||
if ($usr_id != $request->request->get('usr')) { // I logged with another user
|
||||
$ret['status'] = 'disconnected';
|
||||
|
||||
return $this->app->json($ret);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$ret['status'] = 'disconnected';
|
||||
|
||||
return $this->app->json($ret);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->getApplicationBox()->get_connection();
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
return $this->app->json($ret);
|
||||
}
|
||||
|
||||
if (1 > $moduleId = (int) $request->request->get('module')) {
|
||||
$ret['message'] = 'Missing or Invalid `module` parameter';
|
||||
|
||||
return $this->app->json($ret);
|
||||
}
|
||||
|
||||
/** @var \Alchemy\Phrasea\Model\Entities\Session $session */
|
||||
$session = $this->getSessionRepository()->find($this->getSession()->get('session_id'));
|
||||
$session->setUpdated(new \DateTime());
|
||||
|
||||
$manager = $this->getEntityManager();
|
||||
if (!$session->hasModuleId($moduleId)) {
|
||||
$module = new SessionModule();
|
||||
$module->setModuleId($moduleId);
|
||||
$module->setSession($session);
|
||||
$manager->persist($module);
|
||||
}
|
||||
else {
|
||||
$manager->persist($session->getModuleById($moduleId)->setUpdated($now));
|
||||
}
|
||||
|
||||
$manager->persist($session);
|
||||
$manager->flush();
|
||||
|
||||
$ret['status'] = 'ok';
|
||||
|
||||
$ret['notifications'] = $this->render('prod/notifications.html.twig', [
|
||||
'notifications' => $this->getEventsManager()->get_notifications()
|
||||
]);
|
||||
|
||||
$baskets = $this->getBasketRepository()->findUnreadActiveByUser($authenticator->getUser());
|
||||
|
||||
foreach ($baskets as $basket) {
|
||||
$ret['changed'][] = $basket->getId();
|
||||
}
|
||||
|
||||
if (in_array($this->getSession()->get('phraseanet.message'), ['1', null])) {
|
||||
$conf = $this->getConf();
|
||||
if ($conf->get(['main', 'maintenance'])) {
|
||||
$ret['message'] .= $this->app->trans('The application is going down for maintenance, please logout.');
|
||||
}
|
||||
|
||||
if ($conf->get(['registry', 'maintenance', 'enabled'])) {
|
||||
$ret['message'] .= strip_tags($conf->get(['registry', 'maintenance', 'message']));
|
||||
}
|
||||
}
|
||||
|
||||
return $this->app->json($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes identified session
|
||||
*
|
||||
|
@@ -21,6 +21,7 @@ class UserNotificationController extends Controller
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
/* remove in favor of existing /session/ route
|
||||
public function readNotifications(Request $request)
|
||||
{
|
||||
if (!$request->isXmlHttpRequest()) {
|
||||
@@ -38,6 +39,7 @@ class UserNotificationController extends Controller
|
||||
return $this->app->json(['success' => false, 'message' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get all notifications
|
||||
@@ -45,6 +47,7 @@ class UserNotificationController extends Controller
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
/* remove in favor of existing /session/ route
|
||||
public function listNotifications(Request $request)
|
||||
{
|
||||
if (!$request->isXmlHttpRequest()) {
|
||||
@@ -55,12 +58,15 @@ class UserNotificationController extends Controller
|
||||
|
||||
return $this->app->json($this->getEventsManager()->get_notifications_as_array(($page < 0 ? 0 : $page)));
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return \eventsmanager_broker
|
||||
*/
|
||||
/* remove in favor of existing /session/ route
|
||||
private function getEventsManager()
|
||||
{
|
||||
return $this->app['events-manager'];
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@@ -13,9 +13,8 @@ namespace Alchemy\Phrasea\ControllerProvider\Admin;
|
||||
|
||||
use Alchemy\Phrasea\Application as PhraseaApplication;
|
||||
use Alchemy\Phrasea\Controller\Admin\DataboxController;
|
||||
use Alchemy\Phrasea\Core\LazyLocator;
|
||||
use Alchemy\Phrasea\ControllerProvider\ControllerProviderTrait;
|
||||
use Alchemy\Phrasea\Security\Firewall;
|
||||
use Alchemy\Phrasea\Core\LazyLocator;
|
||||
use Silex\Application;
|
||||
use Silex\ControllerProviderInterface;
|
||||
use Silex\ServiceProviderInterface;
|
||||
@@ -89,6 +88,7 @@ class Databox implements ControllerProviderInterface, ServiceProviderInterface
|
||||
->before([$this, 'requireChangeSbasStructureRight'])
|
||||
->bind('admin_database_submit_cgus');
|
||||
|
||||
// polled by admin/databox to display indexation progress bar
|
||||
$controllers->get('/{databox_id}/informations/documents/', 'controller.admin.databox:progressBarInfos')
|
||||
->before([$this, 'requireManageRightOnSbas'])
|
||||
->bind('admin_database_display_document_information');
|
||||
|
@@ -12,9 +12,9 @@
|
||||
namespace Alchemy\Phrasea\ControllerProvider\Root;
|
||||
|
||||
use Alchemy\Phrasea\Application as PhraseaApplication;
|
||||
use Alchemy\Phrasea\Core\LazyLocator;
|
||||
use Alchemy\Phrasea\Controller\Root\SessionController;
|
||||
use Alchemy\Phrasea\ControllerProvider\ControllerProviderTrait;
|
||||
use Alchemy\Phrasea\Core\LazyLocator;
|
||||
use Silex\Application;
|
||||
use Silex\ControllerProviderInterface;
|
||||
use Silex\ServiceProviderInterface;
|
||||
@@ -41,12 +41,12 @@ class Session implements ControllerProviderInterface, ServiceProviderInterface
|
||||
{
|
||||
$controllers = $this->createCollection($app);
|
||||
|
||||
$controllers->post('/update/', 'controller.session:updateSession')
|
||||
->bind('update_session');
|
||||
|
||||
/** @uses SessionController::getNotifications() */
|
||||
$controllers->post('/notifications/', 'controller.session:getNotifications')
|
||||
->bind('list_notifications');
|
||||
|
||||
/** @uses SessionController::deleteSession() */
|
||||
// used in admin/connected_users to kill a session
|
||||
$controller = $controllers->post('/delete/{id}', 'controller.session:deleteSession')
|
||||
->bind('delete_session');
|
||||
|
||||
|
@@ -11,8 +11,6 @@
|
||||
|
||||
namespace Alchemy\Phrasea\ControllerProvider\User;
|
||||
|
||||
use Alchemy\Phrasea\Application as PhraseaApplication;
|
||||
use Alchemy\Phrasea\Controller\User\UserNotificationController;
|
||||
use Alchemy\Phrasea\ControllerProvider\ControllerProviderTrait;
|
||||
use Silex\Application;
|
||||
use Silex\ControllerProviderInterface;
|
||||
@@ -24,9 +22,12 @@ class Notifications implements ControllerProviderInterface, ServiceProviderInter
|
||||
|
||||
public function register(Application $app)
|
||||
{
|
||||
/* remove in favor of existing /session/ route
|
||||
*
|
||||
$app['controller.user.notifications'] = $app->share(function (PhraseaApplication $app) {
|
||||
return (new UserNotificationController($app));
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
@@ -46,11 +47,16 @@ class Notifications implements ControllerProviderInterface, ServiceProviderInter
|
||||
$firewall->requireNotGuest();
|
||||
});
|
||||
|
||||
/* remove in favor of existing /session/ route
|
||||
*
|
||||
/** @uses UserNotificationController::listNotifications * /
|
||||
$controllers->get('/', 'controller.user.notifications:listNotifications')
|
||||
->bind('get_notifications');
|
||||
|
||||
/** @uses UserNotificationController::readNotifications() * /
|
||||
$controllers->post('/read/', 'controller.user.notifications:readNotifications')
|
||||
->bind('set_notifications_readed');
|
||||
*/
|
||||
|
||||
return $controllers;
|
||||
}
|
||||
|
@@ -13,13 +13,12 @@ namespace Alchemy\Phrasea\Core\Event\Subscriber;
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Model\Entities\Session;
|
||||
use Alchemy\Phrasea\Model\Entities\SessionModule;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
class SessionManagerSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
@@ -43,56 +42,52 @@ class SessionManagerSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
return [
|
||||
KernelEvents::REQUEST => [
|
||||
['initSession', Application::EARLY_EVENT],
|
||||
/** @uses SessionManagerSubscriber::checkSessionActivity */
|
||||
['checkSessionActivity', Application::LATE_EVENT]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function initSession(GetResponseEvent $event)
|
||||
{
|
||||
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$request = $event->getRequest();
|
||||
|
||||
if ($this->isFlashUploadRequest($request) && null !== $sessionId = $request->request->get('php_session_id')) {
|
||||
$request->cookies->set($this->app['session']->getName(), $sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* log real human activity on application, to keep session alive
|
||||
*
|
||||
* to "auto-disconnect" when idle duration is passed, we use the "poll" requests.
|
||||
* nb : the route "/sessions/notifications" is not considered as comming from a "module" (prod, admin, ...)
|
||||
* so it will not update session
|
||||
*
|
||||
* @param GetResponseEvent $event
|
||||
*/
|
||||
public function checkSessionActivity(GetResponseEvent $event)
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
|
||||
// ignore routes that comes from api (?) : todo : check if usefull since "api" is not a "module"
|
||||
// todo : "LOG" ???
|
||||
if ($request->request->has('oauth_token')
|
||||
|| $request->query->has('oauth_token')
|
||||
|| $request->query->has('LOG')
|
||||
|| null === $moduleId = $this->getModuleId($request->getPathInfo())
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->isAdminJsPolledRoute($moduleId, $request)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($moduleId === self::$modulesIds['prod'] && $this->isFlashUploadRequest($request)) {
|
||||
return;
|
||||
}
|
||||
$moduleId = $this->getModuleId($request->getPathInfo());
|
||||
|
||||
// if we are already disconnected (ex. from another window), quit immediately
|
||||
//
|
||||
if (!($this->app->getAuthenticator()->isAuthenticated())) {
|
||||
$this->setDisconnectResponse($event);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// we must still ignore some "polling" (js) routes
|
||||
//
|
||||
if ($this->isJsPollingRoute($moduleId, $request)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ANY route can disconnect the user if idle duration is over
|
||||
//
|
||||
/** @var Session $session */
|
||||
$session = $this->app['repo.sessions']->find($this->app['session']->get('session_id'));
|
||||
|
||||
@@ -112,6 +107,14 @@ class SessionManagerSubscriber implements EventSubscriberInterface
|
||||
return;
|
||||
}
|
||||
|
||||
// only routes from "modules" (prod, admin, ...) are considered as "user activity"
|
||||
//
|
||||
if(is_null($moduleId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// here the route is considered as "user activity" : update session
|
||||
//
|
||||
$entityManager = $this->app['orm.em'];
|
||||
|
||||
$module = $this->addOrUpdateSessionModule($session, $moduleId, $now);
|
||||
@@ -121,11 +124,6 @@ class SessionManagerSubscriber implements EventSubscriberInterface
|
||||
$entityManager->flush();
|
||||
}
|
||||
|
||||
private function isFlashUploadRequest(Request $request)
|
||||
{
|
||||
return false !== stripos($request->server->get('HTTP_USER_AGENT'), 'flash') && $request->getRequestUri() === '/prod/upload/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GetResponseEvent $event
|
||||
*/
|
||||
@@ -133,9 +131,10 @@ class SessionManagerSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
|
||||
$response = $request->isXmlHttpRequest() ? $this->getXmlHttpResponse() : $this->getRedirectResponse($request);
|
||||
|
||||
$event->setResponse($response);
|
||||
if($this->getModuleName($request->getPathInfo()) !== 'login') { // prevent infinite redirections
|
||||
$response = $request->isXmlHttpRequest() ? $this->getXmlHttpResponse() : $this->getRedirectResponse($request);
|
||||
$event->setResponse($response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,7 +162,7 @@ class SessionManagerSubscriber implements EventSubscriberInterface
|
||||
* @param string $pathInfo
|
||||
* @return int|null
|
||||
*/
|
||||
private function getModuleId($pathInfo)
|
||||
private function getModuleName($pathInfo)
|
||||
{
|
||||
$parts = array_filter(explode('/', $pathInfo));
|
||||
|
||||
@@ -171,7 +170,16 @@ class SessionManagerSubscriber implements EventSubscriberInterface
|
||||
return null;
|
||||
}
|
||||
|
||||
$moduleName = strtolower($parts[1]);
|
||||
return strtolower($parts[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pathInfo
|
||||
* @return int|null
|
||||
*/
|
||||
private function getModuleId($pathInfo)
|
||||
{
|
||||
$moduleName = $this->getModuleName($pathInfo);
|
||||
|
||||
if (!isset(self::$modulesIds[$moduleName])) {
|
||||
return null;
|
||||
@@ -181,23 +189,39 @@ class SessionManagerSubscriber implements EventSubscriberInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true is the route match a "polling" route (databox progressionbar, task manager, notifications, ...)
|
||||
* polling routes (sent every n seconds with no user action) must not update the session
|
||||
*
|
||||
* the request should contain a "update-session=0" header, but for now we still test hardcoded routes
|
||||
*
|
||||
* @param int $moduleId
|
||||
* @param Request $request
|
||||
* @return bool
|
||||
*/
|
||||
private function isAdminJsPolledRoute($moduleId, Request $request)
|
||||
private function isJsPollingRoute($moduleId, Request $request)
|
||||
{
|
||||
if ($moduleId !== self::$modulesIds['admin']) {
|
||||
return false;
|
||||
if($request->headers->get('update-session', '1') === '0') {
|
||||
return true;
|
||||
}
|
||||
|
||||
$pathInfo = $request->getPathInfo();
|
||||
|
||||
// admin/task managers poll tasks
|
||||
if ($pathInfo === '/admin/task-manager/tasks/' && $request->getContentType() === 'json') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return preg_match('#^/admin/databox/\d+/informations/documents/#', $pathInfo) === 1;
|
||||
// admin/databox poll to update the indexation progress bar (header "update-session=0") sent
|
||||
if(preg_match('#^/admin/databox/\d+/informations/documents/#', $pathInfo)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// admin/databox poll to update the indexation progress bar
|
||||
if(preg_match('#^/.*/notifications/#', $pathInfo)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -96,15 +96,29 @@ class eventsmanager_broker
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
public function get_notifications_as_array($page = 0)
|
||||
{
|
||||
$r = $this->get_notifications($page * 10, 10);
|
||||
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!! FAKE USER FOR TESTING !!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
// $usr_id = $this->app->getAuthenticatedUser()->getId();
|
||||
|
||||
$usr_id = 15826;
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
$total = 0;
|
||||
|
||||
$sql = 'SELECT count(id) as total, sum(unread) as unread
|
||||
FROM notifications WHERE usr_id = :usr_id';
|
||||
|
||||
$stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql);
|
||||
$stmt->execute([':usr_id' => $this->app->getAuthenticatedUser()->getId()]);
|
||||
$stmt->execute([':usr_id' => $usr_id]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
@@ -122,7 +136,7 @@ class eventsmanager_broker
|
||||
$data = ['notifications' => [], 'next' => ''];
|
||||
|
||||
$stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql);
|
||||
$stmt->execute([':usr_id' => $this->app->getAuthenticatedUser()->getId()]);
|
||||
$stmt->execute([':usr_id' => $usr_id]);
|
||||
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
@@ -134,7 +148,9 @@ class eventsmanager_broker
|
||||
continue;
|
||||
}
|
||||
|
||||
$content = $this->pool_classes[$type]->datas($json, $row['unread']);
|
||||
/** @var eventsmanager_notifyAbstract $obj * /
|
||||
$obj = $this->pool_classes[$type];
|
||||
$content = $obj->datas($json, $row['unread']);
|
||||
|
||||
if ( ! isset($this->pool_classes[$type]) || count($content) === 0) {
|
||||
$sql = 'DELETE FROM notifications WHERE id = :id';
|
||||
@@ -169,7 +185,8 @@ class eventsmanager_broker
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
*/
|
||||
/*
|
||||
public function get_unread_notifications_number()
|
||||
{
|
||||
$total = 0;
|
||||
@@ -188,92 +205,152 @@ class eventsmanager_broker
|
||||
|
||||
return $total;
|
||||
}
|
||||
*/
|
||||
const READ = 1;
|
||||
const UNREAD = 2;
|
||||
|
||||
public function get_notifications(\Alchemy\Phrasea\Utilities\Stopwatch $stopwatch = null)
|
||||
public function get_notifications(int $offset=0, int $limit=10, $readFilter = self::READ | self::UNREAD, \Alchemy\Phrasea\Utilities\Stopwatch $stopwatch = null)
|
||||
{
|
||||
$unread = 0;
|
||||
|
||||
$sql = 'SELECT count(id) as total, sum(unread) as unread
|
||||
FROM notifications WHERE usr_id = :usr_id';
|
||||
if($stopwatch) $stopwatch->lap("broker start");
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!! FAKE USER FOR TESTING !!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
// $usr_id = $this->app->getAuthenticatedUser()->getId();
|
||||
$usr_id = $this->app->getAuthenticatedUser()->getId();
|
||||
|
||||
$usr_id = 29882;
|
||||
// $usr_id = 29882;
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
if($stopwatch) $stopwatch->lap("broker start");
|
||||
|
||||
|
||||
|
||||
// delete old already read notifs (nb: we do this for everybody - not only the current user -)
|
||||
// todo: for now we use "created_on" since there is no timestamp set when reading.
|
||||
//
|
||||
$sql = "DELETE FROM `notifications` WHERE `unread`=0 AND TIMESTAMPDIFF(HOUR, `created_on`, NOW()) > 10";
|
||||
$this->app->getApplicationBox()->get_connection()->exec($sql);
|
||||
|
||||
// get count of unread notifications (to be displayed on navbar)
|
||||
//
|
||||
$total = 0;
|
||||
$unread = 0;
|
||||
$sql = 'SELECT COUNT(`id`) AS `total`, SUM(`unread`) AS `unread` FROM `notifications` WHERE `usr_id` = :usr_id';
|
||||
$stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql);
|
||||
$stmt->execute([':usr_id' => $usr_id]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if( ($row = $stmt->fetch(PDO::FETCH_ASSOC)) ) {
|
||||
$total = (int)$row['total'];
|
||||
$unread = (int)$row['unread'];
|
||||
}
|
||||
$stmt->closeCursor();
|
||||
|
||||
if($stopwatch) $stopwatch->lap("sql 1");
|
||||
if($stopwatch) $stopwatch->lap("sql count unread");
|
||||
|
||||
if ($row) {
|
||||
$unread = $row['unread'];
|
||||
$notifications = [];
|
||||
|
||||
// fetch notifications
|
||||
//
|
||||
$sql = "SELECT * FROM `notifications` WHERE `usr_id` = :usr_id";
|
||||
switch ($readFilter) {
|
||||
case self::READ:
|
||||
$sql .= " AND `unread`=0";
|
||||
$total -= $unread; // fix total to match the filter
|
||||
break;
|
||||
case self::UNREAD:
|
||||
$sql .= " AND `unread`=1";
|
||||
$total = $unread; // fix total to match the filter
|
||||
break;
|
||||
default:
|
||||
// any other case : fetch both ; no need to fix total
|
||||
break;
|
||||
}
|
||||
$sql .= " ORDER BY created_on DESC LIMIT " . $offset . ", " . $limit;
|
||||
|
||||
if ($unread < 3) {
|
||||
$sql = 'SELECT * FROM notifications
|
||||
WHERE usr_id = :usr_id ORDER BY created_on DESC LIMIT 0,4';
|
||||
} else {
|
||||
$sql = 'SELECT * FROM notifications
|
||||
WHERE usr_id = :usr_id AND unread="1" ORDER BY created_on DESC';
|
||||
}
|
||||
|
||||
$ret = [];
|
||||
$stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql);
|
||||
$stmt->execute([':usr_id' => $usr_id]);
|
||||
// $rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
//$stmt->closeCursor();
|
||||
$stmt->execute([':usr_id' => $usr_id]); // , ':offset' => $offset, ':limit' => $limit]);
|
||||
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
if($stopwatch) $stopwatch->lap("sql 2");
|
||||
|
||||
// foreach ($rs as $row) {
|
||||
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$bad_ids = [];
|
||||
// nb : we asked for a "page" of notifs (limit), but since some notifications may be ignored (bad type, bad json, ...)
|
||||
// the result array may contain less than expected.
|
||||
foreach ($rs as $row) {
|
||||
$type = 'eventsmanager_' . $row['type'];
|
||||
if ( ! isset($this->pool_classes[$type])) {
|
||||
$bad_ids[] = $row['id'];
|
||||
continue;
|
||||
}
|
||||
|
||||
$data = @json_decode($row['datas'], true);
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
$bad_ids[] = $row['id'];
|
||||
continue;
|
||||
}
|
||||
|
||||
$datas = $this->pool_classes[$type]->datas($data, $row['unread']);
|
||||
/** @var eventsmanager_notifyAbstract $obj */
|
||||
$obj = $this->pool_classes[$type];
|
||||
$datas = $obj->datas($data, $row['unread']);
|
||||
// $datas = [
|
||||
// 'text' => "blabla"
|
||||
// 'class' => "" | "relaod_baskets"
|
||||
// ]
|
||||
|
||||
// if ( ! isset($this->pool_classes[$type]) || count($datas) === 0) {
|
||||
// $sql = 'DELETE FROM notifications WHERE id = :id';
|
||||
// $stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql);
|
||||
// $stmt->execute([':id' => $row['id']]);
|
||||
// $stmt->closeCursor();
|
||||
// continue;
|
||||
// }
|
||||
if (count($datas) === 0) {
|
||||
$bad_ids[] = $row['id'];
|
||||
continue;
|
||||
}
|
||||
|
||||
$ret[] = array_merge(
|
||||
$datas
|
||||
, [
|
||||
'created_on' => $this->app['date-formatter']->getPrettyString(new DateTime($row['created_on']))
|
||||
, 'icon' => $this->pool_classes[$type]->icon_url()
|
||||
, 'id' => $row['id']
|
||||
, 'unread' => $row['unread']
|
||||
// add infos to the notification and add to list
|
||||
//
|
||||
$created_on = new DateTime($row['created_on']);
|
||||
$notifications[] = array_merge(
|
||||
$datas,
|
||||
[
|
||||
'created_on_day' => $created_on->format('Ymd'),
|
||||
'created_on' => $this->app['date-formatter']->getPrettyString($created_on),
|
||||
'time' => $this->app['date-formatter']->getTime($created_on),
|
||||
//, 'icon' => '<img src="' . $this->pool_classes[$type]->icon_url() . '" style="vertical-align:middle;width:16px;margin:2px;" />'
|
||||
'icon' => $this->pool_classes[$type]->icon_url(),
|
||||
'id' => $row['id'],
|
||||
'unread' => $row['unread']
|
||||
]
|
||||
);
|
||||
}
|
||||
$stmt->closeCursor();
|
||||
|
||||
if($stopwatch) $stopwatch->lap("broker ret");
|
||||
if($stopwatch) $stopwatch->lap("fetch");
|
||||
|
||||
if(!empty($bad_ids)) {
|
||||
// delete broken notifs
|
||||
$sql = 'DELETE FROM `notifications` WHERE `id` IN (' . join(',', $bad_ids) . ')';
|
||||
$stmt = $this->app->getApplicationBox()->get_connection()->exec($sql);
|
||||
}
|
||||
|
||||
$next_offset = $offset+$limit;
|
||||
$ret = [
|
||||
'unread_count' => $unread,
|
||||
'offset' => $offset,
|
||||
'limit' => $limit,
|
||||
// 'prev_offset' => $offset === 0 ? null : max(0, $offset-$limit),
|
||||
'next_offset' => $next_offset < $total ? $next_offset : null,
|
||||
'next_page_html' => $next_offset < $total ? '<a href="#" class="notification__print-action" data-offset="' . $next_offset . '">' . $this->app->trans('charger d\'avantages de notifications') . '</a>' : null,
|
||||
'notifications' => $notifications
|
||||
];
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* mark a notification as read
|
||||
* todo : add a "read_on" datetime so we can delete read notifs after N days. For now we use "created_on"
|
||||
*
|
||||
* @param array $notifications
|
||||
* @param $usr_id
|
||||
* @return $this|false
|
||||
*/
|
||||
public function read(Array $notifications, $usr_id)
|
||||
{
|
||||
if (count($notifications) == 0) {
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// import notifyLayout from "../../../../../Phraseanet-production-client/src/components/notify/notifyLayout";
|
||||
|
||||
var p4 = p4 || {};
|
||||
var datepickerLang = [];
|
||||
@@ -32,7 +33,6 @@ var commonModule = (function ($, p4) {
|
||||
$(this).removeClass('context-menu-item-hover');
|
||||
});
|
||||
|
||||
|
||||
$('body').on('click', '.infoDialog', function (event) {
|
||||
infoDialog($(this));
|
||||
});
|
||||
@@ -42,11 +42,13 @@ var commonModule = (function ($, p4) {
|
||||
function showOverlay(n, appendto, callback, zIndex) {
|
||||
|
||||
var div = "OVERLAY";
|
||||
if (typeof(n) != "undefined")
|
||||
if (typeof(n) != "undefined") {
|
||||
div += n;
|
||||
}
|
||||
if ($('#' + div).length === 0) {
|
||||
if (typeof(appendto) == 'undefined')
|
||||
if (typeof(appendto) == 'undefined') {
|
||||
appendto = 'body';
|
||||
}
|
||||
$(appendto).append('<div id="' + div + '" style="display:none;"> </div>');
|
||||
}
|
||||
|
||||
@@ -61,12 +63,13 @@ var commonModule = (function ($, p4) {
|
||||
left: 0
|
||||
};
|
||||
|
||||
if (parseInt(zIndex) > 0)
|
||||
if (parseInt(zIndex) > 0) {
|
||||
css['zIndex'] = parseInt(zIndex);
|
||||
}
|
||||
|
||||
if (typeof(callback) != 'function')
|
||||
callback = function () {
|
||||
};
|
||||
if (typeof(callback) != 'function') {
|
||||
callback = function () {};
|
||||
}
|
||||
$('#' + div).css(css).addClass('overlay').fadeTo(500, 0.7).bind('click', function () {
|
||||
(callback)();
|
||||
});
|
||||
@@ -85,8 +88,9 @@ var commonModule = (function ($, p4) {
|
||||
});
|
||||
}
|
||||
var div = "OVERLAY";
|
||||
if (typeof(n) != "undefined")
|
||||
if (typeof(n) != "undefined") {
|
||||
div += n;
|
||||
}
|
||||
$('#' + div).hide().remove();
|
||||
}
|
||||
|
||||
@@ -110,92 +114,118 @@ var commonModule = (function ($, p4) {
|
||||
}).dialog('open').css({'overflow-x': 'auto', 'overflow-y': 'hidden', 'padding': '0'});
|
||||
}
|
||||
|
||||
|
||||
// @deprecated
|
||||
function manageSession(data, showMessages) {
|
||||
if (typeof(showMessages) == "undefined")
|
||||
showMessages = false;
|
||||
|
||||
function manageSession(data)
|
||||
{
|
||||
if (data.status == 'disconnected' || data.status == 'session') {
|
||||
self.location.replace(self.location.href);
|
||||
}
|
||||
if (showMessages) {
|
||||
var box = $('#notification_box');
|
||||
box.empty().append(data.notifications);
|
||||
|
||||
if (box.is(':visible'))
|
||||
fix_notification_height();
|
||||
// add notification in bar
|
||||
|
||||
if ($('.notification.unread', box).length > 0) {
|
||||
var trigger = $('.notification_trigger');
|
||||
$('.counter', trigger)
|
||||
.empty()
|
||||
.append($('.notification.unread', box).length);
|
||||
$('.counter', trigger).css('visibility', 'visible');
|
||||
// fill the pseudo-dropdown with pre-formatted list of notifs (10 unread)
|
||||
//
|
||||
var box = $('#notification_box');
|
||||
box.empty().append(data.notifications_html);
|
||||
|
||||
}
|
||||
else
|
||||
$('.notification_trigger .counter').css('visibility', 'hidden').empty();
|
||||
if (box.is(':visible')) {
|
||||
fix_notification_height(); // duplicated, better call notifyLayout.setBoxHeight();
|
||||
}
|
||||
|
||||
if (data.changed.length > 0) {
|
||||
var current_open = $('.SSTT.ui-state-active');
|
||||
var current_sstt = current_open.length > 0 ? current_open.attr('id').split('_').pop() : false;
|
||||
// fill the count of uread (red button)
|
||||
//
|
||||
var trigger = $('.notification_trigger');
|
||||
if(data.notifications.unread_count > 0) {
|
||||
$('.counter', trigger)
|
||||
.empty()
|
||||
.append(data.notifications.unread_count).show();
|
||||
}
|
||||
else {
|
||||
$('.counter', trigger)
|
||||
.hide()
|
||||
.empty();
|
||||
}
|
||||
|
||||
var main_open = false;
|
||||
for (var i = 0; i != data.changed.length; i++) {
|
||||
var sstt = $('#SSTT_' + data.changed[i]);
|
||||
if (sstt.size() === 0) {
|
||||
if (main_open === false) {
|
||||
$('#baskets .bloc').animate({'top': 30}, function () {
|
||||
$('#baskets .alert_datas_changed:first').show()
|
||||
});
|
||||
main_open = true;
|
||||
}
|
||||
// diplay notification about unread baskets
|
||||
//
|
||||
if (data.unread_basket_ids.length > 0) {
|
||||
var current_open = $('.SSTT.ui-state-active');
|
||||
var current_sstt = current_open.length > 0 ? current_open.attr('id').split('_').pop() : false;
|
||||
|
||||
var main_open = false;
|
||||
for (var i = 0; i != data.unread_basket_ids.length; i++) {
|
||||
var sstt = $('#SSTT_' + data.unread_basket_ids[i]);
|
||||
if (sstt.size() === 0) {
|
||||
if (main_open === false) {
|
||||
$('#baskets .bloc').animate({'top': 30}, function () {
|
||||
$('#baskets .alert_datas_changed:first').show()
|
||||
});
|
||||
main_open = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!sstt.hasClass('active')) {
|
||||
sstt.addClass('unread');
|
||||
}
|
||||
else {
|
||||
if (!sstt.hasClass('active'))
|
||||
sstt.addClass('unread');
|
||||
else {
|
||||
$('.alert_datas_changed', $('#SSTT_content_' + data.changed[i])).show();
|
||||
}
|
||||
$('.alert_datas_changed', $('#SSTT_content_' + data.unread_basket_ids[i])).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
if ('' !== $.trim(data.message)) {
|
||||
if ($('#MESSAGE').length === 0)
|
||||
$('body').append('<div id="#MESSAGE"></div>');
|
||||
$('#MESSAGE')
|
||||
.empty()
|
||||
.append('<div style="margin:30px 10px;"><h4><b>' + data.message + '</b></h4></div><div style="margin:20px 0px 10px;"><label class="checkbox"><input type="checkbox" class="dialog_remove" />' + language.hideMessage + '</label></div>')
|
||||
.attr('title', 'Global Message')
|
||||
.dialog({
|
||||
autoOpen: false,
|
||||
closeOnEscape: true,
|
||||
resizable: false,
|
||||
draggable: false,
|
||||
modal: true,
|
||||
close: function () {
|
||||
if ($('.dialog_remove:checked', $(this)).length > 0) {
|
||||
// setTemporaryPref
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/user/preferences/temporary/",
|
||||
data: {
|
||||
prop: 'message',
|
||||
value: 0
|
||||
},
|
||||
success: function (data) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.dialog('open');
|
||||
}
|
||||
}
|
||||
|
||||
if ('' !== $.trim(data.message)) {
|
||||
if ($('#MESSAGE').length === 0) {
|
||||
$('body').append('<div id="#MESSAGE"></div>');
|
||||
}
|
||||
$('#MESSAGE')
|
||||
.empty()
|
||||
.append('<div style="margin:30px 10px;"><h4><b>' + data.message + '</b></h4></div><div style="margin:20px 0px 10px;"><label class="checkbox"><input type="checkbox" class="dialog_remove" />' + language.hideMessage + '</label></div>')
|
||||
.attr('title', 'Global Message')
|
||||
.dialog({
|
||||
autoOpen: false,
|
||||
closeOnEscape: true,
|
||||
resizable: false,
|
||||
draggable: false,
|
||||
modal: true,
|
||||
close: function () {
|
||||
if ($('.dialog_remove:checked', $(this)).length > 0) {
|
||||
// setTemporaryPref
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/user/preferences/temporary/",
|
||||
data: {
|
||||
prop: 'message',
|
||||
value: 0
|
||||
},
|
||||
success: function (data) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.dialog('open');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* duplicated from production_client::notifyLayout.js
|
||||
*/
|
||||
function fix_notification_height() {
|
||||
const $notificationBoxContainer = $('#notification_box');
|
||||
const not = $('.notification', $notificationBoxContainer);
|
||||
const n = not.length;
|
||||
const not_t = $('.notification_title', $notificationBoxContainer);
|
||||
const n_t = not_t.length;
|
||||
|
||||
var h = not.outerHeight() * n + not_t.outerHeight() * n_t;
|
||||
h = h > 350 ? 350 : h;
|
||||
|
||||
$notificationBoxContainer.stop().animate({height: h});
|
||||
}
|
||||
|
||||
return {
|
||||
showOverlay: showOverlay,
|
||||
hideOverlay: hideOverlay,
|
||||
|
@@ -201,34 +201,35 @@ function reportDatePicker() {
|
||||
});
|
||||
}
|
||||
|
||||
// poll only from menu bar
|
||||
|
||||
function pollNotifications() {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/session/notifications/",
|
||||
dataType: 'json',
|
||||
data: {
|
||||
module: 10,
|
||||
usr: usrId
|
||||
},
|
||||
error: function () {
|
||||
window.setTimeout("pollNotifications();", 10000);
|
||||
},
|
||||
timeout: function () {
|
||||
window.setTimeout("pollNotifications();", 10000);
|
||||
},
|
||||
success: function (data) {
|
||||
if (data) {
|
||||
commonModule.manageSession(data);
|
||||
}
|
||||
var t = 120000;
|
||||
if (data.apps && parseInt(data.apps) > 1) {
|
||||
t = Math.round((Math.sqrt(parseInt(data.apps) - 1) * 1.3 * 120000));
|
||||
}
|
||||
window.setTimeout("pollNotifications();", t);
|
||||
return;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
window.setTimeout("pollNotifications();", 10000);
|
||||
// function pollNotifications() {
|
||||
// $.ajax({
|
||||
// type: "POST",
|
||||
// url: "/session/notifications/",
|
||||
// dataType: 'json',
|
||||
// data: {
|
||||
// module: 10,
|
||||
// usr: usrId
|
||||
// },
|
||||
// error: function () {
|
||||
// window.setTimeout("pollNotifications();", 10000);
|
||||
// },
|
||||
// timeout: function () {
|
||||
// window.setTimeout("pollNotifications();", 10000);
|
||||
// },
|
||||
// success: function (data) {
|
||||
// if (data) {
|
||||
// commonModule.manageSession(data);
|
||||
// }
|
||||
// var t = 120000;
|
||||
// if (data.apps && parseInt(data.apps) > 1) {
|
||||
// t = Math.round((Math.sqrt(parseInt(data.apps) - 1) * 1.3 * 120000));
|
||||
// }
|
||||
// window.setTimeout("pollNotifications();", t);
|
||||
// return;
|
||||
// }
|
||||
// });
|
||||
// };
|
||||
//
|
||||
// window.setTimeout("pollNotifications();", 10000);
|
||||
|
@@ -242,7 +242,12 @@
|
||||
type: "GET",
|
||||
url: "/admin/databox/{{ databox.get_sbas_id() }}/informations/documents/",
|
||||
dataType: 'json',
|
||||
data: {},
|
||||
headers: {
|
||||
'update-session': '0' // polling should not maintain the session alive
|
||||
// also : use lowercase as recomended / normalized
|
||||
},
|
||||
data: {
|
||||
},
|
||||
success: function (data) {
|
||||
try {
|
||||
if (data.viewname === '') {
|
||||
|
@@ -202,19 +202,13 @@
|
||||
<div class="PNB right desktopmenu" style="left:auto;overflow:hidden;">
|
||||
<ol>
|
||||
{% if app.getAuthenticator().isAuthenticated() and module == "prod" %}
|
||||
<li class="notification_trigger">
|
||||
<a href="#" style="font-weight:bold;text-decoration:none;">
|
||||
<span>
|
||||
<button class="counter btn btn-danger"
|
||||
style="visibility:{% if app['events-manager'].get_unread_notifications_number > 0 %}visible{% else %}hidden{% endif %};">
|
||||
{% if app['events-manager'].get_unread_notifications_number > 0 %}
|
||||
{{ app['events-manager'].get_unread_notifications_number }}
|
||||
{% endif %}
|
||||
</button>
|
||||
{{ 'Notifications' | trans }}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="notification_trigger">
|
||||
<a href="#" style="font-weight:bold;text-decoration:none;">
|
||||
<span>
|
||||
<button class="counter btn btn-danger"></button> {{ 'Notifications' | trans }}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="user">
|
||||
{% if app.getAuthenticator().isAuthenticated() %}
|
||||
@@ -274,26 +268,19 @@
|
||||
|
||||
<div class="mobilemenu" style="float: right;margin-right: 50px;">
|
||||
{% if app.getAuthenticator().isAuthenticated() and module == "prod" %}
|
||||
<li class="notification_trigger">
|
||||
<a href="#" style="font-weight:bold;text-decoration:none;">
|
||||
<span>
|
||||
<button class="counter btn btn-danger"
|
||||
style="visibility:{% if app['events-manager'].get_unread_notifications_number > 0 %}visible{% else %}hidden{% endif %};">
|
||||
{% if app['events-manager'].get_unread_notifications_number > 0 %}
|
||||
{{ app['events-manager'].get_unread_notifications_number }}
|
||||
{% endif %}
|
||||
</button>
|
||||
{{ 'Notifications' | trans }}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="notification_trigger">
|
||||
<a href="#" style="font-weight:bold;text-decoration:none;">
|
||||
<span>
|
||||
<button class="counter btn btn-danger"></button> {{ 'Notifications' | trans }}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if app.getAuthenticator().isAuthenticated() and module == "prod" %}
|
||||
<div style="display:none;z-index:30000;" id="notification_box">
|
||||
{% set notifications = app['events-manager'].get_notifications %}
|
||||
{% include 'prod/notifications.html.twig' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -430,31 +417,36 @@
|
||||
});
|
||||
});
|
||||
/**manage session and redirect to login page**/
|
||||
var usrId = '{{ app.getAuthenticator().user.getId }}' ;
|
||||
// var usrId = '{{ app.getAuthenticator().user.getId }}' ;
|
||||
var module = '{{ module }}';
|
||||
|
||||
function pollNotifications() {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/session/notifications/",
|
||||
dataType: 'json',
|
||||
data: {
|
||||
module: 10,
|
||||
usr: usrId
|
||||
'offset': 0,
|
||||
'limit': 10,
|
||||
'what': 2, // 2 : only unread
|
||||
},
|
||||
error: function () {
|
||||
window.setTimeout("pollNotifications();", 10000);
|
||||
error: function (data) {
|
||||
if(data.getResponseHeader('x-phraseanet-end-session')) {
|
||||
self.location.replace(self.location.href); // refresh will redirect to login
|
||||
}
|
||||
},
|
||||
timeout: function () {
|
||||
window.setTimeout("pollNotifications();", 10000);
|
||||
},
|
||||
success: function (data) {
|
||||
if (data) {
|
||||
// there is no notification bar nor a basket notification if not on prod module
|
||||
if (module === 'prod' && data) {
|
||||
commonModule.manageSession(data);
|
||||
}
|
||||
window.setTimeout("pollNotifications();", 60000);
|
||||
return;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
window.setTimeout("pollNotifications();", 10000);
|
||||
window.setTimeout("pollNotifications();", 2000);
|
||||
</script>
|
||||
|
@@ -99,7 +99,7 @@
|
||||
{% if basket.getValidation is null %}
|
||||
{% set basket_length = basket.getElements().count() %}
|
||||
{% set counter = ( counter | default(0) ) + 1 %}
|
||||
{% set counter_length = baskets_collection.length() %}
|
||||
{% set counter_length = baskets_collection | length %}
|
||||
|
||||
<tr class="{% if counter >=4 %}other_basket hidden{% endif %}">
|
||||
<td colspan="2">
|
||||
|
@@ -101,11 +101,11 @@
|
||||
lang: "{{ app.locale }}",
|
||||
baseUrl: '{{ app['request'].getUriForPath('/') }}',
|
||||
basePath: '{{ app.request.basePath|e('js') }}',
|
||||
notify: {
|
||||
url: "{{ path('list_notifications') }}",
|
||||
moduleId: 1,
|
||||
userId: {{app.getAuthenticatedUser().getId()}}
|
||||
},
|
||||
{#notify: {#}
|
||||
{# url: "{{ path('list_notifications') }}",#}
|
||||
{# moduleId: 1,#}
|
||||
{# userId: {{app.getAuthenticatedUser().getId()}}#}
|
||||
{#},#}
|
||||
debug: {% if app.debug %}true{% else %}false{% endif %},
|
||||
initialState: "{{ initialAppState }}",
|
||||
geonameServerUrl: '{{ app['geonames.server-uri'] }}',
|
||||
|
@@ -6,7 +6,7 @@
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="notification_title">
|
||||
<a href="#" class="notification__print-action" data-page="0">{{ 'toutes les notifications' | trans }}</a>
|
||||
<a href="#" class="notification__print-action">{{ 'toutes les notifications' | trans }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
@@ -150,7 +150,7 @@
|
||||
alert("{{ 'phraseanet::erreur: Votre session est fermee, veuillez vous re-authentifier' | trans }}");
|
||||
self.location.replace(self.location.href);
|
||||
}
|
||||
window.setTimeout("pollNotifications();", 10000);
|
||||
window.setTimeout("pollNotifications();", 60000);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@@ -21,35 +21,37 @@ define([
|
||||
eventManager: _.extend({}, Backbone.Events)
|
||||
};
|
||||
|
||||
window.pullNotifications = function (){
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: AdminApp.$scope.data("notif-url"),
|
||||
dataType: 'json',
|
||||
data: {
|
||||
module : 3,
|
||||
usr : AdminApp.$scope.data("usr")
|
||||
},
|
||||
error: function(){
|
||||
window.setTimeout("pullNotifications();", 10000);
|
||||
},
|
||||
timeout: function(){
|
||||
window.setTimeout("pullNotifications();", 10000);
|
||||
},
|
||||
success: function(data){
|
||||
if (data) {
|
||||
if (data.status == 'disconnected' || data.status == 'session') {
|
||||
self.location.replace(self.location.href);
|
||||
}
|
||||
}
|
||||
var t = 120000;
|
||||
if (data.apps && parseInt(data.apps) > 1) {
|
||||
t = Math.round((Math.sqrt(parseInt(data.apps)-1) * 1.3 * 120000));
|
||||
}
|
||||
window.setTimeout("pullNotifications();", t);
|
||||
}
|
||||
});
|
||||
};
|
||||
// pull notification is called from menu bar
|
||||
|
||||
// window.pullNotifications = function (){
|
||||
// $.ajax({
|
||||
// type: "POST",
|
||||
// url: AdminApp.$scope.data("notif-url"),
|
||||
// dataType: 'json',
|
||||
// data: {
|
||||
// module : 3,
|
||||
// usr : AdminApp.$scope.data("usr")
|
||||
// },
|
||||
// error: function(){
|
||||
// window.setTimeout("pullNotifications();", 10000);
|
||||
// },
|
||||
// timeout: function(){
|
||||
// window.setTimeout("pullNotifications();", 10000);
|
||||
// },
|
||||
// success: function(data){
|
||||
// if (data) {
|
||||
// if (data.status == 'disconnected' || data.status == 'session') {
|
||||
// self.location.replace(self.location.href);
|
||||
// }
|
||||
// }
|
||||
// var t = 120000;
|
||||
// if (data.apps && parseInt(data.apps) > 1) {
|
||||
// t = Math.round((Math.sqrt(parseInt(data.apps)-1) * 1.3 * 120000));
|
||||
// }
|
||||
// window.setTimeout("pullNotifications();", t);
|
||||
// }
|
||||
// });
|
||||
// };
|
||||
window.enableForms = function (forms) {
|
||||
forms.bind('submit', function(event){
|
||||
var method = $(this).attr('method');
|
||||
|
@@ -15,7 +15,7 @@ define([
|
||||
var TaskCollection = Backbone.Collection.extend({
|
||||
model: TaskModel,
|
||||
url: function () {
|
||||
return "/admin/task-manager/tasks";
|
||||
return "/admin/task-manager/tasks?update_session=0";
|
||||
}
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user