Merge pull request #3819 from alchemy-fr/PHRAS-3471_notifications-ux

PHRAS-3471 Merge clean notifications ux and design
This commit is contained in:
Nicolas Maillat
2021-06-30 10:20:33 +02:00
committed by GitHub
27 changed files with 381 additions and 544 deletions

View File

@@ -13,5 +13,5 @@ module.exports = {
setupDir: _root + 'tests/setup/node.js',
karmaConf: _root + 'config/karma.conf.js',
// change this version when you change JS file for lazy loading
jsFileVersion: 21
jsFileVersion: 22
};

View File

@@ -96,7 +96,7 @@ return /******/ (function(modules) { // webpackBootstrap
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=21";
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=22";
/******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() {

View File

@@ -96,7 +96,7 @@ return /******/ (function(modules) { // webpackBootstrap
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=21";
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=22";
/******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() {

View File

@@ -91,7 +91,7 @@
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=21";
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=22";
/******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() {

View File

@@ -91,7 +91,7 @@
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=21";
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=22";
/******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() {

View File

@@ -4177,108 +4177,6 @@ input.checkbox {
color: red !important;
}
#notification_trigger {
cursor: pointer;
}
#notification_trigger .counter {
border: 1px solid white;
background: red;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
font-size: 10px;
font-weight: bold;
display: inline-block;
line-height: 12px;
margin: 0;
padding: 2px 4px;
}
#notification_trigger.open a span {
color: black;
}
#notification_trigger.open {
background-color: white;
border-bottom: 1px solid white;
}
#notification_box {
background-color: white;
border: 1px solid black;
border-top: none;
position: absolute;
height: 150px;
top: 30px;
overflow-y: auto;
overflow-x: hidden;
z-index: 668;
right: 20px;
color: black;
}
#notification_box div.notification span.time {
color: #414141;
font-size: 11px;
white-space: nowrap;
margin-left: 0;
}
#notification_box div.notification a {
color: #999999;
text-decoration: none;
}
#notification_box div.notification a:hover {
text-decoration: underline;
}
#notification_box div.notification {
padding: 5px 10px;
}
#notification_box div.notification.hover {
background-color: #E1E1E1;
}
#notification_box div.notification.unread {
background-color: #E1E1E1;
}
#notification_box div.notification_title a {
font-size: 13px;
font-weight: bold;
color: blue;
}
#notification_box div.notification_title {
text-align: center;
padding: 10px 0;
}
#notifications-dialog a {
color: #999999;
}
#notifications-dialog a:hover {
color: #D9D9D9;
text-decoration: underline;
}
#notifications-dialog .time {
font-size: 10px;
color: #666666;
}
#notifications-dialog .notification_title {
padding: 10px 0 5px;
}
#notifications-dialog .notification_next {
text-align: center;
padding: 15px 0;
}
.styled-checkbox {
position: absolute;
opacity: 0;

View File

@@ -18909,6 +18909,11 @@ var notifyLayout = function notifyLayout(services) {
var $navigation = (0, _jquery2.default)('.navigation', $notificationDialog);
var initialize = function initialize() {
// the dialog MUST be created during print_notifications(), else the first clik on a "read" button
// is badly interpreted (no action, but scrolls the content ???
// $notificationDialog.dialog({});
/**
* 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
@@ -18922,7 +18927,6 @@ var notifyLayout = function notifyLayout(services) {
} else {
$notificationTrigger.addClass('open'); // highlight background in menubar
$notificationBoxContainer.show();
commonModule.fixNotificationsHeight();
}
});
@@ -18982,6 +18986,11 @@ var notifyLayout = function notifyLayout(services) {
var print_notifications = function print_notifications(offset) {
offset = parseInt(offset, 10);
if (offset == 0) {
$notifications.empty();
}
var buttons = {};
buttons[localeService.t('fermer')] = function () {
@@ -19004,6 +19013,7 @@ var notifyLayout = function notifyLayout(services) {
opacity: 0.7
},
close: function close(event, ui) {
// destroy so it will be "fresh" on next open (scrollbar on top)
$notificationDialog.dialog('destroy').remove();
}
}).dialog('option', 'buttons', buttons).dialog('open');
@@ -19035,7 +19045,8 @@ var notifyLayout = function notifyLayout(services) {
var notifications = data.notifications.notifications;
var i = 0;
for (i in notifications) {
var _loop = function _loop() {
var notification = notifications[i];
// group notifs by day
@@ -19051,22 +19062,27 @@ var notifyLayout = function notifyLayout(services) {
}
// add pre-formatted notif
var $z = date_cont.append(notification.html);
(0, _jquery2.default)('.notification_' + notification.id + '_unread', $z).tooltip().click(notification.id, function (event) {
mark_read(event.data);
var $z = (0, _jquery2.default)(notification.html);
// the "unread" icon is clickable to mark as read
(0, _jquery2.default)('.icon_unread', $z).tooltip().click({ 'z': $z, 'id': notification.id }, function (event) {
markNotificationRead(event.data['id'], $z);
});
date_cont.append($z);
};
for (i in notifications) {
_loop();
}
// handle "show more" button
//
if (data.notifications.next_offset) {
// update the "more" button
$navigation.off('click', '.notification__print-action');
$navigation.on('click', '.notification__print-action', function (event) {
$navigation.off('click', '.notification__print-action') // remove previous, else we load 10, 20, 40...
.on('click', '.notification__print-action', function (event) {
event.preventDefault();
print_notifications(data.notifications.next_offset);
});
$navigation.show();
}).show();
} else {
// no more ? no button
$navigation.hide();
@@ -19075,11 +19091,10 @@ var notifyLayout = function notifyLayout(services) {
});
};
var mark_read = function mark_read(notification_id) {
var markNotificationRead = function markNotificationRead(notification_id, $notification) {
commonModule.markNotificationRead(notification_id).success(function (data) {
// xhttp ok : update button
(0, _jquery2.default)('.notification_' + notification_id + '_unread', $notifications).hide();
(0, _jquery2.default)('.notification_' + notification_id + '_read', $notifications).show();
// xhttp ok : update notif
$notification.removeClass('unread');
});
};

File diff suppressed because one or more lines are too long

View File

@@ -18909,6 +18909,11 @@ var notifyLayout = function notifyLayout(services) {
var $navigation = (0, _jquery2.default)('.navigation', $notificationDialog);
var initialize = function initialize() {
// the dialog MUST be created during print_notifications(), else the first clik on a "read" button
// is badly interpreted (no action, but scrolls the content ???
// $notificationDialog.dialog({});
/**
* 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
@@ -18922,7 +18927,6 @@ var notifyLayout = function notifyLayout(services) {
} else {
$notificationTrigger.addClass('open'); // highlight background in menubar
$notificationBoxContainer.show();
commonModule.fixNotificationsHeight();
}
});
@@ -18982,6 +18986,11 @@ var notifyLayout = function notifyLayout(services) {
var print_notifications = function print_notifications(offset) {
offset = parseInt(offset, 10);
if (offset == 0) {
$notifications.empty();
}
var buttons = {};
buttons[localeService.t('fermer')] = function () {
@@ -19004,6 +19013,7 @@ var notifyLayout = function notifyLayout(services) {
opacity: 0.7
},
close: function close(event, ui) {
// destroy so it will be "fresh" on next open (scrollbar on top)
$notificationDialog.dialog('destroy').remove();
}
}).dialog('option', 'buttons', buttons).dialog('open');
@@ -19035,7 +19045,8 @@ var notifyLayout = function notifyLayout(services) {
var notifications = data.notifications.notifications;
var i = 0;
for (i in notifications) {
var _loop = function _loop() {
var notification = notifications[i];
// group notifs by day
@@ -19051,22 +19062,27 @@ var notifyLayout = function notifyLayout(services) {
}
// add pre-formatted notif
var $z = date_cont.append(notification.html);
(0, _jquery2.default)('.notification_' + notification.id + '_unread', $z).tooltip().click(notification.id, function (event) {
mark_read(event.data);
var $z = (0, _jquery2.default)(notification.html);
// the "unread" icon is clickable to mark as read
(0, _jquery2.default)('.icon_unread', $z).tooltip().click({ 'z': $z, 'id': notification.id }, function (event) {
markNotificationRead(event.data['id'], $z);
});
date_cont.append($z);
};
for (i in notifications) {
_loop();
}
// handle "show more" button
//
if (data.notifications.next_offset) {
// update the "more" button
$navigation.off('click', '.notification__print-action');
$navigation.on('click', '.notification__print-action', function (event) {
$navigation.off('click', '.notification__print-action') // remove previous, else we load 10, 20, 40...
.on('click', '.notification__print-action', function (event) {
event.preventDefault();
print_notifications(data.notifications.next_offset);
});
$navigation.show();
}).show();
} else {
// no more ? no button
$navigation.hide();
@@ -19075,11 +19091,10 @@ var notifyLayout = function notifyLayout(services) {
});
};
var mark_read = function mark_read(notification_id) {
var markNotificationRead = function markNotificationRead(notification_id, $notification) {
commonModule.markNotificationRead(notification_id).success(function (data) {
// xhttp ok : update button
(0, _jquery2.default)('.notification_' + notification_id + '_unread', $notifications).hide();
(0, _jquery2.default)('.notification_' + notification_id + '_read', $notifications).show();
// xhttp ok : update notif
$notification.removeClass('unread');
});
};

View File

@@ -7703,7 +7703,7 @@ dans l'onglet thesaurus : arbres, menus contextuels
font-weight: bold;
font-size: 13px;
display: none;
z-index: 5000;
z-index: 500;
}
#idFrameC #baskets .insidebloc {

File diff suppressed because one or more lines are too long

View File

@@ -7718,7 +7718,7 @@ dans l'onglet thesaurus : arbres, menus contextuels
font-weight: bold;
font-size: 13px;
display: none;
z-index: 5000;
z-index: 500;
}
#idFrameC #baskets .insidebloc {

File diff suppressed because one or more lines are too long

View File

@@ -7720,7 +7720,7 @@ dans l'onglet thesaurus : arbres, menus contextuels
font-weight: bold;
font-size: 13px;
display: none;
z-index: 5000;
z-index: 500;
}
#idFrameC #baskets .insidebloc {

File diff suppressed because one or more lines are too long

View File

@@ -1,95 +1,91 @@
// import user from '../user/index.js';
import notifyLayout from './notifyLayout';
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;
const defaultPollingTime = 60000; // pull every 60 seconds
const defaultConfig = {
url: null,
moduleId: null,
userId: null,
_isValid: false
};
const initialize = () => {
notifyLayout(services).initialize();
};
const createNotifier = (state) => {
if (state === undefined) {
return defaultConfig;
}
if (state.url === undefined) {
return defaultConfig;
}
return merge({}, defaultConfig, {
url: state.url,
moduleId: state.moduleId,
userId: state.userId,
_isValid: true
});
};
//const appendNotifications = (content) => notifyUiComponent().addNotifications(content);
const isValid = (notificationInstance) => notificationInstance._isValid || false;
const poll = (notificationInstance) => {
let notificationSource = Rx.Observable
.fromPromise(notifyService({
configService: configService
}).getNotification({
module: notificationInstance.moduleId,
usr: notificationInstance.userId
}));
notificationSource.subscribe(
x => onPollSuccess(x, notificationInstance),
e => onPollError(e, notificationInstance),
() => {}
);
};
const onPollSuccess = (data, notificationInstance) => {
// broadcast session refresh event
appEvents.emit('session.refresh', data);
// broadcast notification refresh event
if (data.changed.length > 0) {
appEvents.emit('notification.refresh', data);
}
// append notification content
// notifyLayout(services).addNotifications(data.notifications);
// window.setTimeout(poll, defaultPollingTime, notificationInstance);
return true;
};
const onPollError = (data, notificationInstance) => {
if (data.status === 'disconnected' || data.status === 'session') {
appEvents.emit('user.disconnected', data);
return false;
}
window.setTimeout(poll, defaultPollingTime, notificationInstance);
};
return {
initialize,
/*appendNotifications: (content) => {
notifyLayout().addNotifications(content)
},*/
createNotifier,
isValid,
poll
};
};
export default notify;
// const notify = (services) => {
//
// const { configService, localeService, appEvents } = services;
// const defaultPollingTime = 60000; // pull every 60 seconds
// const defaultConfig = {
// url: null,
// moduleId: null,
// userId: null,
// _isValid: false
// };
//
// const initialize = () => {
// notifyLayout(services).initialize();
// };
//
// const createNotifier = (state) => {
// if (state === undefined) {
// return defaultConfig;
// }
// if (state.url === undefined) {
// return defaultConfig;
// }
//
// return merge({}, defaultConfig, {
// url: state.url,
// moduleId: state.moduleId,
// userId: state.userId,
// _isValid: true
// });
// };
//
// //const appendNotifications = (content) => notifyUiComponent().addNotifications(content);
//
// const isValid = (notificationInstance) => notificationInstance._isValid || false;
//
// const poll = (notificationInstance) => {
//
// let notificationSource = Rx.Observable
// .fromPromise(notifyService({
// configService: configService
// }).getNotification({
// module: notificationInstance.moduleId,
// usr: notificationInstance.userId
// }));
//
// notificationSource.subscribe(
// x => onPollSuccess(x, notificationInstance),
// e => onPollError(e, notificationInstance),
// () => {}
// );
// };
// const onPollSuccess = (data, notificationInstance) => {
// // broadcast session refresh event
// appEvents.emit('session.refresh', data);
// // broadcast notification refresh event
// if (data.changed.length > 0) {
// appEvents.emit('notification.refresh', data);
// }
// // append notification content
// // notifyLayout(services).addNotifications(data.notifications);
//
// // window.setTimeout(poll, defaultPollingTime, notificationInstance);
//
// return true;
// };
//
// const onPollError = (data, notificationInstance) => {
// if (data.status === 'disconnected' || data.status === 'session') {
// appEvents.emit('user.disconnected', data);
// return false;
// }
// window.setTimeout(poll, defaultPollingTime, notificationInstance);
// };
//
//
// return {
// initialize,
// /*appendNotifications: (content) => {
// notifyLayout().addNotifications(content)
// },*/
// createNotifier,
// isValid,
// poll
// };
// };
//
// export default notify;

View File

@@ -11,6 +11,11 @@ const notifyLayout = (services) => {
let $navigation = $('.navigation', $notificationDialog);
const initialize = () => {
// the dialog MUST be created during print_notifications(), else the first clik on a "read" button
// is badly interpreted (no action, but scrolls the content ???
// $notificationDialog.dialog({});
/**
* 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
@@ -25,7 +30,6 @@ const notifyLayout = (services) => {
else {
$notificationTrigger.addClass('open'); // highlight background in menubar
$notificationBoxContainer.show();
commonModule.fixNotificationsHeight();
}
});
@@ -88,6 +92,11 @@ const notifyLayout = (services) => {
const print_notifications = (offset) => {
offset = parseInt(offset, 10);
if(offset == 0) {
$notifications.empty();
}
var buttons = {};
buttons[localeService.t('fermer')] = function () {
@@ -97,23 +106,26 @@ const notifyLayout = (services) => {
// open the dlg (even if it is already opened when "load more")
//
$notificationDialog
.dialog({
title: $('#notification-title').val(),
autoOpen: false,
closeOnEscape: true,
resizable: false,
draggable: false,
modal: true,
width: 500,
height: 400,
overlay: {
backgroundColor: '#000',
opacity: 0.7
},
close: function (event, ui) {
$notificationDialog.dialog('destroy').remove();
.dialog(
{
title: $('#notification-title').val(),
autoOpen: false,
closeOnEscape: true,
resizable: false,
draggable: false,
modal: true,
width: 500,
height: 400,
overlay: {
backgroundColor: '#000',
opacity: 0.7
},
close: function (event, ui) {
// destroy so it will be "fresh" on next open (scrollbar on top)
$notificationDialog.dialog('destroy').remove();
}
}
})
)
.dialog('option', 'buttons', buttons)
.dialog('open');
@@ -160,12 +172,14 @@ const notifyLayout = (services) => {
}
// add pre-formatted notif
const $z = date_cont.append(notification.html);
$('.notification_' + notification.id + '_unread', $z).tooltip().click(
notification.id,
const $z = $(notification.html);
// the "unread" icon is clickable to mark as read
$('.icon_unread', $z).tooltip().click(
{'z':$z, 'id':notification.id},
function (event) {
mark_read(event.data);
markNotificationRead(event.data['id'], $z);
});
date_cont.append($z);
}
// handle "show more" button
@@ -173,13 +187,12 @@ const notifyLayout = (services) => {
if(data.notifications.next_offset) {
// update the "more" button
$navigation
.off('click', '.notification__print-action');
$navigation
.off('click', '.notification__print-action') // remove previous, else we load 10, 20, 40...
.on('click', '.notification__print-action', function (event) {
event.preventDefault();
print_notifications(data.notifications.next_offset);
});
$navigation.show();
})
.show();
}
else {
// no more ? no button
@@ -189,12 +202,11 @@ const notifyLayout = (services) => {
});
};
const mark_read = (notification_id) => {
commonModule.markNotificationRead(notification_id,)
const markNotificationRead = (notification_id, $notification) => {
commonModule.markNotificationRead(notification_id)
.success(function (data) {
// xhttp ok : update button
$('.notification_' + notification_id + '_unread', $notifications).hide();
$('.notification_' + notification_id + '_read', $notifications).show();
// xhttp ok : update notif
$notification.removeClass('unread');
})
};

View File

@@ -1,46 +1,46 @@
import {Observable} from 'rx';
// import {ajax} from 'jquery';
import $ from 'jquery';
let notifyService = (services) => {
const {configService} = services;
const url = configService.get('baseUrl');
const notificationEndPoint = 'session/notifications/';
let initialize = () => {
};
let getNotification = (data) => {
/*return ajax({
type: 'POST',
url: `${notificationEndPoint}`,
data: data,
dataType: 'json'
}).promise();*/
let notificationPromise = $.Deferred();
$.ajax({
type: 'POST',
url: `${url}${notificationEndPoint}`,
data: data,
dataType: 'json'
}).done((data) => {
data.status = data.status || false;
if (data.status === 'ok') {
notificationPromise.resolve(data);
} else {
notificationPromise.reject(data);
}
})
.fail((data) => {
notificationPromise.reject(data);
});
return notificationPromise.promise();
};
let stream = Observable.fromPromise(getNotification);
return {
initialize,
getNotification,
stream
};
};
export default notifyService;
// import {Observable} from 'rx';
// // import {ajax} from 'jquery';
// import $ from 'jquery';
// let notifyService = (services) => {
// const {configService} = services;
// const url = configService.get('baseUrl');
// const notificationEndPoint = 'session/notifications/';
// let initialize = () => {
// };
//
// let getNotification = (data) => {
// /*return ajax({
// type: 'POST',
// url: `${notificationEndPoint}`,
// data: data,
// dataType: 'json'
// }).promise();*/
// let notificationPromise = $.Deferred();
//
// $.ajax({
// type: 'POST',
// url: `${url}${notificationEndPoint}`,
// data: data,
// dataType: 'json'
// }).done((data) => {
// data.status = data.status || false;
// if (data.status === 'ok') {
// notificationPromise.resolve(data);
// } else {
// notificationPromise.reject(data);
// }
// })
// .fail((data) => {
// notificationPromise.reject(data);
// });
// return notificationPromise.promise();
// };
//
// let stream = Observable.fromPromise(getNotification);
// return {
// initialize,
// getNotification,
// stream
// };
// };
// export default notifyService;

View File

@@ -69,7 +69,7 @@
font-weight: bold;
font-size: $mediumFontSize;
display: none;
z-index: 5000;
z-index: 500;
}
.insidebloc {
top: 0;

View File

@@ -1,104 +1 @@
@import 'variables';
#notification_trigger{
cursor:pointer;
}
#notification_trigger .counter{
border:1px solid white;
background:red;
-moz-border-radius:8px;
-webkit-border-radius:8px;
font-size:10px;
font-weight:bold;
display:inline-block;
line-height:12px;
margin:0;
padding:2px 4px;
}
#notification_trigger.open a span{
color:black;
}
#notification_trigger.open{
background-color:white;
border-bottom:1px solid white;
}
#notification_trigger.unread{
}
#notification_box{
background-color:white;
border:1px solid black;
border-top:none;
position:absolute;
height:150px;
top:30px;
overflow-y:auto;
overflow-x:hidden;
z-index:668;
right:20px;
color:black;
}
#notification_box div.notification span.time{
color:#414141;
font-size:11px;
white-space:nowrap;
margin-left:0;
}
#notification_box div.notification a{
color:#999999;
text-decoration:none;
}
#notification_box div.notification a:hover{
text-decoration:underline;
}
#notification_box div.notification{
padding:5px 10px;
}
#notification_box div.notification.hover{
background-color:#E1E1E1;
}
#notification_box div.notification.unread{
background-color:#E1E1E1;
}
#notification_box div.notification_title a{
font-size:13px;
font-weight:bold;
color:blue;
}
#notification_box div.notification_title{
text-align:center;
padding:10px 0;
}
#notifications-dialog a{
color:#999999;
}
#notifications-dialog a:hover{
color:#D9D9D9;
text-decoration:underline
}
#notifications-dialog .time{
font-size:10px;
color:#666666;
}
#notifications-dialog .notification_title{
padding:10px 0 5px;
}
#notifications-dialog .notification_next{
text-align:center;
padding:15px 0;
}
// moved to resources/www/_shared/styles/_notification.scss

View File

@@ -59,7 +59,7 @@ class PhraseanetExtension extends \Twig_Extension
{
return [
// change this version when you change JS file to force the navigation to reload js file
'jsFileVersion' => 21
'jsFileVersion' => 22
];
}

View File

@@ -1,104 +1,130 @@
// compiled to common.css
@import 'variables';
.notification_trigger {
cursor:pointer;
}
cursor: pointer;
.notification_trigger .counter {
border:1px solid white;
background:red;
-moz-border-radius:8px;
-webkit-border-radius:8px;
font-size:10px;
font-weight:bold;
display:inline-block;
line-height:12px;
margin:0;
padding:2px 4px;
}
.counter {
border: 1px solid white;
background: red;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
font-size: 10px;
font-weight: bold;
display: inline-block;
line-height: 12px;
margin: 0;
padding: 2px 4px;
}
.notification_trigger.open a span {
color:black;
}
.notification_trigger.open {
background-color:white;
border-bottom:1px solid white;
}
.notification_trigger.unread {
&.open {
background-color: white;
border-bottom: 1px solid white;
a span {
color: black;
}
}
}
#notification_box{
background-color:white;
border:1px solid black;
border-top:none;
position:absolute;
height:150px;
top: 42px !important;
overflow-y:auto;
overflow-x:hidden;
z-index:668;
right:20px;
color:black;
#notification_box {
background-color: white;
border: 1px solid black;
border-top: none;
position: absolute;
max-height: 400px;
top: 42px;
overflow-y: auto;
overflow-x: hidden;
z-index: 668;
right: 20px;
color: black;
.time {
color: #414141;
}
a {
color: #414141;
}
}
#notification_box div.notification span.time{
color:#414141;
font-size:11px;
white-space:nowrap;
margin-left:0;
#notifications-dialog {
// .notification_title : date group title
.notification_title {
padding: 10px 0 5px;
}
.time {
color: #666666;
}
a {
color: #999999;
}
}
#notification_box div.notification a{
color:#999999;
text-decoration:none;
#notification_box, #notifications-dialog {
a {
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
.notification {
border-bottom: 1px grey solid;
padding: 5px 10px;
.time {
font-size: 11px;
white-space: nowrap;
margin-left: 0;
}
// spot to show the notif as unread or read
//
// if read, the notif has no "unread" class
.icon_read {
// --- no need sign for the read notif ---
//display: inherit;
//color: green;
//&::before {
// content: '\02714' // checked
//}
display: none;
}
.icon_unread {
// --- clickable red spot for the unread notif (to mark it as read) ---
display: none;
cursor: pointer;
color:red;
&::before {
content: '\02B24'; // large bullet
}
}
&.unread {
.icon_read {
display: none;
}
// if unread, the notif shows the clickable spot
.icon_unread {
display: inherit;
}
}
}
.navigation {
margin-top: 15px;
margin-bottom: 5px;
text-align: center;
font-size: large;
}
}
#notification_box div.notification a:hover{
text-decoration:underline;
}
#notification_box div.notification{
padding:5px 10px;
}
#notification_box div.notification.hover{
background-color:#E1E1E1;
}
#notification_box div.notification.unread{
background-color:#E1E1E1;
}
#notification_box div.notification_title a{
font-size:13px;
font-weight:bold;
color:blue;
}
#notification_box div.notification_title{
text-align:center;
padding:10px 0;
}
#notifications-dialog a{
color:#999999;
}
#notifications-dialog a:hover{
color:#D9D9D9;
text-decoration:underline
}
#notifications-dialog .time{
font-size:10px;
color:#666666;
}
#notifications-dialog .notification_title{
padding:10px 0 5px;
}
#notifications-dialog .notification_next{
text-align:center;
padding:15px 0;
}

View File

@@ -193,26 +193,22 @@ var commonModule = (function ($, p4) {
$box_notifications.empty();
if(data.notifications.notifications.length === 0) {
// no notification
// $('.show_all', $box).hide(); // the "show in dlg" is alway visible since it's the only way to see already read notifs.
$('.no_notifications', $box).show();
}
else {
$('.no_notifications', $box).hide();
for (var n in data.notifications.notifications) {
var notification = data.notifications.notifications[n];
var $z = $box_notifications.append(notification.html);
$('.notification_' + notification.id + '_unread', $z).click(
// add pre-formatted notif
var $z = $(notification.html)
// the "unread" icon is clickable to mark as read
$('.icon_unread', $z).click(
notification.id,
function (event) {
markNotificationRead(event.data);
});
$box_notifications.append($z);
}
// $('.show_all', $box).show();
}
if ($box.is(':visible')) {
fixNotificationsHeight();
}
// fill the count of uread (red button)
@@ -229,7 +225,7 @@ var commonModule = (function ($, p4) {
.empty();
}
// diplay notification about unread baskets
// display notification about unread baskets
//
if (data.unread_basket_ids.length > 0) {
var current_open = $('.SSTT.ui-state-active');
@@ -294,28 +290,11 @@ var commonModule = (function ($, p4) {
return true;
}
/**
* duplicated from production_client::notifyLayout.js
*/
function fixNotificationsHeight() {
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,
markNotificationRead: markNotificationRead,
pollNotifications: pollNotifications,
fixNotificationsHeight: fixNotificationsHeight
}
})(jQuery, p4);

View File

@@ -1,18 +1,17 @@
<div style="position:relative;" class="notification {% if notification['unread'] == '1' %}unread{% endif %}">
{# css from resources/www/_shared/styles/_notification.scss #}
<div class="notification {% if notification['unread'] == '1' %}unread{% endif %}" data-notification_id="{{notification['id']}}">
<table style="width:100%;" cellspacing="0" cellpadding="0" border="0">
<tr style="border-top: 1px grey solid">
<tr>
<td style="width:25px; vertical-align: top;">
<img src="{{notification['icon']}}" style="vertical-align:middle;width:16px;margin:2px;" />
</td>
<td>
<p style="margin:0;padding:0;" class="{{notification['class']}}">
{{notification['text']|raw}}
<span class="time">{{notification['created_on']}}</span>
</p>
<td class="{{notification['class']}}">
{{notification['text']|raw}}
<span class="time">{{notification['created_on']}}</span>
</td>
<td style="width:25px; vertical-align: bottom;">
<span class="notification_{{notification['id']}}_read" title="{{ 'notification::read:tooltip' | trans }}" style="display: {{ notification['unread'] == '1' ? 'none' : 'inherit' }}">&#9989;</span>
<span class="notification_{{notification['id']}}_unread" title="{{ 'notification::unread:tooltip' | trans }}" style="cursor: pointer; display: {{ notification['unread'] == '1' ? 'inherit' : 'none' }}">&#x1F441;</span>
<span class="icon_read" title="{{ 'notification::read:tooltip' | trans }}"></span>
<span class="icon_unread" title="{{ 'notification::unread:tooltip' | trans }}"></span>
</td>
</tr>
</table>

View File

@@ -1,4 +1,5 @@
<div id="notifications-dialog">
{# css from resources/www/_shared/styles/_notification.scss #}
<div id="notifications-dialog" style="display: none">
<div class="notifications">
</div>
<div class="navigation">

View File

@@ -1,12 +1,11 @@
<div style="display:none;z-index:30000;" id="notification_box">
<div style="margin-right:16px;">
{# css from resources/www/_shared/styles/_notification.scss #}
<div style="display:none;" id="notification_box">
<div class="no_notifications">
<span>{{ 'Aucune notification' | trans }}</span>
</div>
<div class="notifications">
</div>
<div class="show_all">
<div class="navigation show_all">
<a href="#" class="notification__print-action">{{ 'toutes les notifications' | trans }}</a>
</div>
</div>
</div>

View File

@@ -126,7 +126,7 @@ define([
AdminApp.LeftView.activeTree();
AdminApp.LeftView.clickSelected();
window.setTimeout(function() {pullNotifications();}, 15000);
// window.setTimeout(function() {pullNotifications();}, 15000);
};
return {