WIP - Notifications explorer (#2071)
This commit is contained in:
parent
03b4da1286
commit
2f04ffcc4a
|
@ -92,6 +92,38 @@ sub get {
|
|||
return $result;
|
||||
}
|
||||
|
||||
# Returns accepted notifications corresponding to the user $uid.
|
||||
# If $ref is set, returns only notification corresponding to this reference.
|
||||
sub getAccepted {
|
||||
my ( $self, $uid, $ref ) = @_;
|
||||
return () unless ($uid);
|
||||
$self->_execute(
|
||||
"SELECT * FROM "
|
||||
. $self->dbiTable
|
||||
. " WHERE done IS NOT NULL AND uid=?"
|
||||
. ( $ref ? " AND ref=?" : '' )
|
||||
. " ORDER BY date",
|
||||
$uid,
|
||||
( $ref ? $ref : () )
|
||||
) or return ();
|
||||
my $result;
|
||||
while ( my $h = $self->sth->fetchrow_hashref() ) {
|
||||
|
||||
# Get XML message
|
||||
my $xml = $h->{xml};
|
||||
|
||||
# Decode it to get the correct uncoded string
|
||||
Encode::from_to( $xml, "utf8", "iso-8859-1", Encode::FB_CROAK );
|
||||
|
||||
# Store message in result
|
||||
my $identifier =
|
||||
&getIdentifier( $self, $h->{uid}, $h->{ref}, $h->{date} );
|
||||
$result->{$identifier} = $xml;
|
||||
}
|
||||
$self->logger->warn( $self->sth->err() ) if ( $self->sth->err() );
|
||||
return $result;
|
||||
}
|
||||
|
||||
## @method hashref getAll()
|
||||
# Return all pending notifications.
|
||||
# @return hashref where keys are internal reference and values are hashref with
|
||||
|
|
|
@ -58,6 +58,30 @@ sub get {
|
|||
return $files;
|
||||
}
|
||||
|
||||
# Returns accepted notification corresponding to the user $uid.
|
||||
# If $ref is set, returns only notification corresponding to this reference.
|
||||
sub getAccepted {
|
||||
my ( $self, $uid, $ref ) = @_;
|
||||
return () unless ($uid);
|
||||
my $fns = $self->{fileNameSeparator};
|
||||
my $identifier = &getIdentifier( $self, $uid, $ref );
|
||||
|
||||
opendir D, $self->{dirName};
|
||||
my @notif = grep /^\d{8}${fns}${identifier}\S*\.done$/, readdir(D);
|
||||
closedir D;
|
||||
|
||||
my $files;
|
||||
foreach my $file (@notif) {
|
||||
unless ( open F, '<', $self->{dirName} . "/$file" ) {
|
||||
$self->logger->error(
|
||||
"Unable to read notification $self->{dirName}/$file");
|
||||
next;
|
||||
}
|
||||
$files->{$file} = join( '', <F> );
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
## @method hashref getAll()
|
||||
# Return all pending notifications.
|
||||
# @return hashref where keys are internal reference and values are hashref with
|
||||
|
|
|
@ -87,6 +87,38 @@ sub get {
|
|||
return $result;
|
||||
}
|
||||
|
||||
# Returns accepted notifications corresponding to the user $uid.
|
||||
# If $ref is set, returns only notification corresponding to this reference.
|
||||
sub getAccepted {
|
||||
my ( $self, $uid, $ref ) = @_;
|
||||
return () unless ($uid);
|
||||
|
||||
my $filter =
|
||||
'(&(objectClass=applicationProcess)(description={done}*)'
|
||||
. "(description={uid}$uid)"
|
||||
. ( $ref ? '(description={ref}' . $ref . ')' : '' ) . ')';
|
||||
my @entries = _search( $self, $filter );
|
||||
|
||||
my $result;
|
||||
foreach my $entry (@entries) {
|
||||
my @notifValues = $entry->get_value('description');
|
||||
my $f = {};
|
||||
foreach (@notifValues) {
|
||||
my ( $k, $v ) = ( $_ =~ /\{(.*?)\}(.*)/smg );
|
||||
$v = decodeLdapValue($v);
|
||||
$f->{$k} = $v;
|
||||
}
|
||||
my $xml = $f->{xml};
|
||||
utf8::encode($xml);
|
||||
my $identifier =
|
||||
&getIdentifier( $self, $f->{uid}, $f->{ref}, $f->{date} );
|
||||
$result->{$identifier} = "$xml";
|
||||
$self->logger->info("notification $identifier found");
|
||||
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
## @method hashref getAll()
|
||||
# Return all pending notifications.
|
||||
# @return hashref where keys are internal reference and values are hashref with
|
||||
|
|
|
@ -1884,6 +1884,10 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
|
|||
'default' => 'uid reference date title subtitle text check',
|
||||
'type' => 'text'
|
||||
},
|
||||
'notificationsExplorer' => {
|
||||
'default' => 1,
|
||||
'type' => 'bool'
|
||||
},
|
||||
'notificationStorage' => {
|
||||
'default' => 'File',
|
||||
'type' => 'PerlModule'
|
||||
|
|
|
@ -1135,6 +1135,11 @@ sub attributes {
|
|||
type => 'bool',
|
||||
documentation => 'Notification activation',
|
||||
},
|
||||
notificationsExplorer => {
|
||||
default => 1,
|
||||
type => 'bool',
|
||||
documentation => 'Notifications explorer activation',
|
||||
},
|
||||
notificationServer => {
|
||||
default => 0,
|
||||
type => 'bool',
|
||||
|
|
|
@ -608,6 +608,7 @@ sub tree {
|
|||
help => 'notifications.html',
|
||||
nodes => [
|
||||
'notification',
|
||||
'notificationsExplorer',
|
||||
'oldNotifFormat',
|
||||
'notificationStorage',
|
||||
'notificationStorageOptions',
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -110,6 +110,63 @@ sub checkForNotifications {
|
|||
return $form;
|
||||
}
|
||||
|
||||
# Search for accepted notification and if any, returns HTML fragment.
|
||||
sub viewNotification {
|
||||
my ( $self, $req, $ref, $epoch ) = @_;
|
||||
|
||||
# Look for accepted notifications in database
|
||||
my $uid = $req->userData->{ $self->notifObject->notifField };
|
||||
my ( $notifs, $forUser ) =
|
||||
$self->notifObject->getAcceptedNotifs( $uid, $ref );
|
||||
my $form;
|
||||
return 0 unless ($notifs);
|
||||
|
||||
# Transform notifications
|
||||
my $i = 0; # Files count
|
||||
my @res;
|
||||
|
||||
foreach my $file ( values %$notifs ) {
|
||||
my $json = eval { from_json( $file, { allow_nonref => 1 } ) };
|
||||
$self->userLogger->warn(
|
||||
"Bad JSON file: a notification for $uid was not done ($@)")
|
||||
if ($@);
|
||||
my $j = 0; # Notifications count
|
||||
$json = [$json] unless ( ref $json eq 'ARRAY' );
|
||||
LOOP: foreach my $notif ( @{$json} ) {
|
||||
|
||||
# Get the reference
|
||||
my $reference = $notif->{reference};
|
||||
$self->logger->debug("Get reference: $reference");
|
||||
|
||||
# Check it in session
|
||||
unless (exists $req->{userData}->{"notification_$reference"}
|
||||
and $req->{userData}->{"notification_$reference"} eq $epoch
|
||||
and $reference eq $ref )
|
||||
{
|
||||
|
||||
# The notification is not already accepted
|
||||
$self->logger->debug(
|
||||
"Notification $reference is not already accepted");
|
||||
next LOOP;
|
||||
}
|
||||
push @res, $notif;
|
||||
$j++;
|
||||
}
|
||||
|
||||
# Go to next file if no notification found
|
||||
next unless $j;
|
||||
$i++;
|
||||
}
|
||||
$form .= $self->toForm( $req, @res );
|
||||
|
||||
# Stop here if nothing to display
|
||||
return 0 unless $i;
|
||||
$self->userLogger->info("$i accepted notification(s) found for $uid");
|
||||
|
||||
# Returns HTML fragment
|
||||
return $form;
|
||||
}
|
||||
|
||||
sub getNotifBack {
|
||||
my ( $self, $req, $name ) = @_;
|
||||
|
||||
|
|
|
@ -158,6 +158,73 @@ sub checkForNotifications {
|
|||
return $form;
|
||||
}
|
||||
|
||||
# Search for accepted notification and if any, returns HTML fragment.
|
||||
sub viewNotification {
|
||||
my ( $self, $req, $ref, $epoch ) = @_;
|
||||
|
||||
# Look for pending notifications in database
|
||||
my $uid = $req->sessionInfo->{ $self->notifObject->notifField };
|
||||
my ( $notifs, $forUser ) =
|
||||
$self->notifObject->getAcceptedNotifs( $uid, $ref );
|
||||
my $form;
|
||||
return 0 unless ($notifs);
|
||||
|
||||
# Transform notifications
|
||||
my $i = 0; # Files count
|
||||
|
||||
foreach my $file ( values %$notifs ) {
|
||||
my $xml = $self->parser->parse_string($file);
|
||||
my $j = 0; # Notifications count
|
||||
LOOP: foreach my $notif (
|
||||
eval {
|
||||
$xml->documentElement->getElementsByTagName('notification');
|
||||
}
|
||||
)
|
||||
{
|
||||
|
||||
# Get the reference
|
||||
my $reference = $notif->getAttribute('reference');
|
||||
$self->logger->debug("Get reference $reference");
|
||||
|
||||
# Check it in session
|
||||
unless (exists $req->{sessionInfo}->{"notification_$reference"}
|
||||
and $req->{userData}->{"notification_$reference"} eq $epoch
|
||||
and $reference eq $ref )
|
||||
{
|
||||
|
||||
# The notification is not already accepted
|
||||
$self->logger->debug(
|
||||
"Notification $reference was already accepted");
|
||||
|
||||
# Remove it from XML
|
||||
$notif->unbindNode();
|
||||
next LOOP;
|
||||
}
|
||||
$j++;
|
||||
}
|
||||
|
||||
# Go to next file if no notification found
|
||||
next unless $j;
|
||||
$i++;
|
||||
|
||||
# Transform XML into HTML
|
||||
my $results = $self->stylesheet->transform( $xml, start => $i );
|
||||
$form .= $self->stylesheet->output_string($results);
|
||||
}
|
||||
if ($@) {
|
||||
$self->userLogger->warn(
|
||||
"Bad XML file: a notification for $uid was not done ($@)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Stop here if nothing to display
|
||||
return 0 unless $i;
|
||||
$self->userLogger->info("$i accepted notification(s) found for $uid");
|
||||
|
||||
# Returns HTML fragment
|
||||
return $form;
|
||||
}
|
||||
|
||||
sub getNotifBack {
|
||||
my ( $self, $req, $name ) = @_;
|
||||
|
||||
|
|
|
@ -133,6 +133,15 @@ sub params {
|
|||
: '';
|
||||
$self->logger->debug("Display DecryptValue link") if $res{decryptValue};
|
||||
|
||||
# Display NotifsExplorer link if allowed
|
||||
my $notifsPlugin =
|
||||
$self->p->loadedModules->{'Lemonldap::NG::Portal::Plugins::Notifications'};
|
||||
$res{notifsExplorer} =
|
||||
$notifsPlugin
|
||||
? $notifsPlugin->displayLink( $req, $req->userData )
|
||||
: '';
|
||||
$self->logger->debug("Display NotifsExplorer link") if $res{notifsExplorer};
|
||||
|
||||
return %res;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,12 +15,12 @@ use strict;
|
|||
use Mouse;
|
||||
use MIME::Base64;
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||
PE_ERROR
|
||||
PE_NOTIFICATION
|
||||
PE_ERROR
|
||||
PE_OK
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.6';
|
||||
our $VERSION = '2.0.8';
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Main::Plugin';
|
||||
|
||||
|
@ -33,17 +33,16 @@ use constant endAuth => 'checkNotifDuringAuth';
|
|||
#sub forAuthUser { 'checkNotifForAuthUser' }
|
||||
|
||||
# PROPERTIES
|
||||
|
||||
has module => ( is => 'rw' );
|
||||
|
||||
# INITIALIZATION
|
||||
|
||||
sub init {
|
||||
my ($self) = @_;
|
||||
|
||||
# Declare new route
|
||||
$self->addUnauthRoute( 'notifback' => 'getNotifBack', [ 'POST', 'GET' ] );
|
||||
$self->addAuthRoute( 'notifback' => 'getNotifBack', ['POST'] );
|
||||
$self->addUnauthRoute( notifback => 'getNotifBack', [ 'POST', 'GET' ] );
|
||||
$self->addAuthRoute( notifback => 'getNotifBack', ['POST'] )
|
||||
->addAuthRoute( mynotifs => { '*' => 'myNotifs' }, ['GET'] );
|
||||
|
||||
if ( $self->conf->{notificationServer} ) {
|
||||
$self->logger->debug('Notification server enable');
|
||||
|
@ -160,4 +159,76 @@ sub notificationServer {
|
|||
return $self->module->notificationServer( $req, @args );
|
||||
}
|
||||
|
||||
sub myNotifs {
|
||||
my ( $self, $req, $ref ) = @_;
|
||||
|
||||
if ($ref) {
|
||||
return $self->sendJSONresponse( $req, { error => 'Missing parameter' } )
|
||||
unless $req->param('epoch');
|
||||
my $notif = $self->_viewNotif( $req, $ref, $req->param('epoch') );
|
||||
return $self->sendJSONresponse( $req,
|
||||
{ notification => $notif, result => ( $notif ? 1 : 0 ) } );
|
||||
}
|
||||
|
||||
my $_notifications = $self->retrieveNotifs($req);
|
||||
|
||||
# Display form
|
||||
my $params = {
|
||||
PORTAL => $self->conf->{portal},
|
||||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
SKIN => $self->p->getSkin($req),
|
||||
LANGS => $self->conf->{showLanguages},
|
||||
MSG => 'myNofifications',
|
||||
DISPLAY => 1,
|
||||
ACTION => 1,
|
||||
NOTIFICATIONS => $_notifications
|
||||
};
|
||||
|
||||
return $self->p->sendHtml( $req, 'notifications', params => $params );
|
||||
}
|
||||
|
||||
sub retrieveNotifs {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
# Retrieve user's accepted notifications
|
||||
my $_notifications = [
|
||||
map {
|
||||
/^notification_(.+)$/
|
||||
? { reference => $1, epoch => $req->{userData}->{$_} }
|
||||
: ()
|
||||
}
|
||||
keys %{ $req->{userData} }
|
||||
];
|
||||
|
||||
@$_notifications = sort {
|
||||
$a->{reference} cmp $b->{reference}
|
||||
or $a->{epoch} <=> $b->{epoch}
|
||||
} @$_notifications;
|
||||
|
||||
$self->logger->debug(
|
||||
scalar @$_notifications . " accepted notifications found" );
|
||||
|
||||
return $_notifications;
|
||||
}
|
||||
|
||||
sub _viewNotif {
|
||||
my ( $self, $req, $ref, $epoch ) = @_;
|
||||
eval {
|
||||
$req->{data}->{notification} =
|
||||
$self->module->viewNotification( $req, $ref, $epoch );
|
||||
};
|
||||
if ($@) {
|
||||
$self->logger->error($@);
|
||||
return '';
|
||||
}
|
||||
return $req->{data}->{notification};
|
||||
}
|
||||
|
||||
sub displayLink {
|
||||
my ( $self, $req ) = @_;
|
||||
my $_notifications = $self->retrieveNotifs($req);
|
||||
|
||||
return ( $self->conf->{notificationsExplorer} && scalar @$_notifications );
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
50
lemonldap-ng-portal/site/coffee/notifications.coffee
Normal file
50
lemonldap-ng-portal/site/coffee/notifications.coffee
Normal file
|
@ -0,0 +1,50 @@
|
|||
###
|
||||
LemonLDAP::NG Notifications script
|
||||
###
|
||||
|
||||
setMsg = (msg, level) ->
|
||||
$('#msg').html window.translate msg
|
||||
$('#color').removeClass 'message-positive message-warning alert-success alert-warning'
|
||||
$('#color').addClass "message-#{level}"
|
||||
level = 'success' if level == 'positive'
|
||||
$('#color').addClass "alert-#{level}"
|
||||
|
||||
displayError = (j, status, err) ->
|
||||
console.log 'Error', err
|
||||
res = JSON.parse j.responseText
|
||||
if res and res.error
|
||||
console.log 'Returned error', res
|
||||
setMsg res, 'warning'
|
||||
|
||||
# Delete function (launched by "view" button)
|
||||
viewNotif = (notif, epoch) ->
|
||||
console.log 'Ref:', notif, 'epoch:', epoch
|
||||
if notif and epoch
|
||||
console.log 'Send AJAX request'
|
||||
$.ajax
|
||||
type: "GET"
|
||||
url: "#{portal}mynotifs/#{notif}"
|
||||
data:
|
||||
epoch: epoch
|
||||
dataType: 'json'
|
||||
#error: displayError
|
||||
success: (resp) ->
|
||||
if resp.result
|
||||
console.log 'Notification:', resp.notification
|
||||
$('#displayNotif').html resp.notification
|
||||
$("#myNotification").removeAttr('hidden')
|
||||
$('#notifRef').text(notif)
|
||||
myDate = new Date(epoch * 1000)
|
||||
$('#notifEpoch').text(myDate.toLocaleString())
|
||||
else setMsg 'notifNotFound', 'warning'
|
||||
#error: displayError
|
||||
else setMsg 'retreiveNotifFailed', 'warning'
|
||||
|
||||
# Register "click" events
|
||||
$(document).ready ->
|
||||
#$("#myNotification").hide()
|
||||
$('body').on 'click', '.btn-success', () -> viewNotif ( $(this).attr 'notif' ), ( $(this).attr 'epoch' )
|
||||
$('#goback').attr 'href', portal
|
||||
$(".data-epoch").each ->
|
||||
myDate = new Date($(this).text() * 1000)
|
||||
$(this).text(myDate.toLocaleString())
|
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
|
@ -0,0 +1,72 @@
|
|||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
LemonLDAP::NG Notifications script
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var displayError, setMsg, viewNotif;
|
||||
|
||||
setMsg = function(msg, level) {
|
||||
$('#msg').html(window.translate(msg));
|
||||
$('#color').removeClass('message-positive message-warning alert-success alert-warning');
|
||||
$('#color').addClass("message-" + level);
|
||||
if (level === 'positive') {
|
||||
level = 'success';
|
||||
}
|
||||
return $('#color').addClass("alert-" + level);
|
||||
};
|
||||
|
||||
displayError = function(j, status, err) {
|
||||
var res;
|
||||
console.log('Error', err);
|
||||
res = JSON.parse(j.responseText);
|
||||
if (res && res.error) {
|
||||
console.log('Returned error', res);
|
||||
return setMsg(res, 'warning');
|
||||
}
|
||||
};
|
||||
|
||||
viewNotif = function(notif, epoch) {
|
||||
console.log('Ref:', notif, 'epoch:', epoch);
|
||||
if (notif && epoch) {
|
||||
console.log('Send AJAX request');
|
||||
return $.ajax({
|
||||
type: "GET",
|
||||
url: portal + "mynotifs/" + notif,
|
||||
data: {
|
||||
epoch: epoch
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(resp) {
|
||||
var myDate;
|
||||
if (resp.result) {
|
||||
console.log('Notification:', resp.notification);
|
||||
$('#displayNotif').html(resp.notification);
|
||||
$("#myNotification").removeAttr('hidden');
|
||||
$('#notifRef').text(notif);
|
||||
myDate = new Date(epoch * 1000);
|
||||
return $('#notifEpoch').text(myDate.toLocaleString());
|
||||
} else {
|
||||
return setMsg('notifNotFound', 'warning');
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return setMsg('retreiveNotifFailed', 'warning');
|
||||
}
|
||||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
$('body').on('click', '.btn-success', function() {
|
||||
return viewNotif($(this).attr('notif'), $(this).attr('epoch'));
|
||||
});
|
||||
$('#goback').attr('href', portal);
|
||||
return $(".data-epoch").each(function() {
|
||||
var myDate;
|
||||
myDate = new Date($(this).text() * 1000);
|
||||
return $(this).text(myDate.toLocaleString());
|
||||
});
|
||||
});
|
||||
|
||||
}).call(this);
|
1
lemonldap-ng-portal/site/htdocs/static/common/js/notifications.min.js
vendored
Normal file
1
lemonldap-ng-portal/site/htdocs/static/common/js/notifications.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
(function(){var a,t;a=function(t,e){return $("#msg").html(window.translate(t)),$("#color").removeClass("message-positive message-warning alert-success alert-warning"),$("#color").addClass("message-"+e),"positive"===e&&(e="success"),$("#color").addClass("alert-"+e)},t=function(o,n){return console.log("Ref:",o,"epoch:",n),o&&n?(console.log("Send AJAX request"),$.ajax({type:"GET",url:portal+"mynotifs/"+o,data:{epoch:n},dataType:"json",success:function(t){var e;return t.result?(console.log("Notification:",t.notification),$("#displayNotif").html(t.notification),$("#myNotification").removeAttr("hidden"),$("#notifRef").text(o),e=new Date(1e3*n),$("#notifEpoch").text(e.toLocaleString())):a("notifNotFound","warning")}})):a("retreiveNotifFailed","warning")},$(document).ready(function(){return $("body").on("click",".btn-success",function(){return t($(this).attr("notif"),$(this).attr("epoch"))}),$("#goback").attr("href",portal),$(".data-epoch").each(function(){var t;return t=new Date(1e3*$(this).text()),$(this).text(t.toLocaleString())})})}).call(this);
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["lemonldap-ng-portal/site/htdocs/static/common/js/notifications.js"],"names":["setMsg","viewNotif","msg","level","$","html","window","translate","removeClass","addClass","notif","epoch","console","log","ajax","type","url","portal","data","dataType","success","resp","myDate","result","notification","removeAttr","text","Date","toLocaleString","document","ready","on","this","attr","each","call"],"mappings":"CAMA,WACE,IAAkBA,EAAQC,EAE1BD,EAAS,SAASE,EAAKC,GAOrB,OANAC,EAAE,QAAQC,KAAKC,OAAOC,UAAUL,IAChCE,EAAE,UAAUI,YAAY,gEACxBJ,EAAE,UAAUK,SAAS,WAAaN,GACpB,aAAVA,IACFA,EAAQ,WAEHC,EAAE,UAAUK,SAAS,SAAWN,IAazCF,EAAY,SAASS,EAAOC,GAE1B,OADAC,QAAQC,IAAI,OAAQH,EAAO,SAAUC,GACjCD,GAASC,GACXC,QAAQC,IAAI,qBACLT,EAAEU,KAAK,CACZC,KAAM,MACNC,IAAKC,OAAS,YAAcP,EAC5BQ,KAAM,CACJP,MAAOA,GAETQ,SAAU,OACVC,QAAS,SAASC,GAChB,IAAIC,EACJ,OAAID,EAAKE,QACPX,QAAQC,IAAI,gBAAiBQ,EAAKG,cAClCpB,EAAE,iBAAiBC,KAAKgB,EAAKG,cAC7BpB,EAAE,mBAAmBqB,WAAW,UAChCrB,EAAE,aAAasB,KAAKhB,GACpBY,EAAS,IAAIK,KAAa,IAARhB,GACXP,EAAE,eAAesB,KAAKJ,EAAOM,mBAE7B5B,EAAO,gBAAiB,eAK9BA,EAAO,sBAAuB,YAIzCI,EAAEyB,UAAUC,MAAM,WAKhB,OAJA1B,EAAE,QAAQ2B,GAAG,QAAS,eAAgB,WACpC,OAAO9B,EAAUG,EAAE4B,MAAMC,KAAK,SAAU7B,EAAE4B,MAAMC,KAAK,YAEvD7B,EAAE,WAAW6B,KAAK,OAAQhB,QACnBb,EAAE,eAAe8B,KAAK,WAC3B,IAAIZ,EAEJ,OADAA,EAAS,IAAIK,KAAsB,IAAjBvB,EAAE4B,MAAMN,QACnBtB,EAAE4B,MAAMN,KAAKJ,EAAOM,wBAI9BO,KAAKH"}
|
|
@ -79,6 +79,12 @@
|
|||
<span trspan="decryptCipheredValue">decryptCipheredValue</span>
|
||||
</a></li>
|
||||
</TMPL_IF>
|
||||
<TMPL_IF NAME="notifsExplorer">
|
||||
<li class="dropdown-item"><a href="/mynotifs" class="nav-link">
|
||||
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/notifsExplorer.png" width="20" height="20" alt="notifsExplorer" />
|
||||
<span trspan="notifsExplorer">notifsExplorer</span>
|
||||
</a></li>
|
||||
</TMPL_IF>
|
||||
<li class="dropdown-item"><a href="/refresh" class="nav-link">
|
||||
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/arrow_refresh.png" width="16" height="16" alt="refresh" />
|
||||
<span trspan="refreshrights">Refresh</span>
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
<TMPL_INCLUDE NAME="header.tpl">
|
||||
|
||||
<div class="container">
|
||||
<div id="color" class="message message-positive alert">
|
||||
<span id="msg" trspan='<TMPL_VAR NAME="MSG">'></span>
|
||||
</div>
|
||||
<TMPL_IF NAME="NOTIFICATIONS">
|
||||
<div class="card mb-3 border-secondary">
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><span trspan="reference">Reference</span></th>
|
||||
<th><span trspan="date">Date</span></th>
|
||||
<th>
|
||||
<TMPL_IF NAME="ACTION">
|
||||
<span trspan="action">Action</span>
|
||||
</TMPL_IF>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<TMPL_LOOP NAME="NOTIFICATIONS">
|
||||
<tr id='delete-<TMPL_VAR NAME="epoch">'>
|
||||
<td class="align-middle"><TMPL_VAR NAME="reference"></td>
|
||||
<td class="data-epoch"><TMPL_VAR NAME="epoch"></td>
|
||||
<td>
|
||||
<TMPL_IF NAME="DISPLAY">
|
||||
<span notif='<TMPL_VAR NAME="reference">' epoch='<TMPL_VAR NAME="epoch">' class="btn btn-success" role="button">
|
||||
<span class="fa fa-eye"></span>
|
||||
<span trspan="view">View</span>
|
||||
</span>
|
||||
</TMPL_IF>
|
||||
</td>
|
||||
</tr>
|
||||
</TMPL_LOOP>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-3 border-info" id='myNotification' hidden>
|
||||
<div class="card-header text-white bg-info">
|
||||
<h3 class="card-title"><span trspan="reference">Reference</span>: <span id="notifRef"></span> / <span trspan="validationDate">Validation date</span>: <span id="notifEpoch"></span></h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="form">
|
||||
<span id='displayNotif'></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</TMPL_IF>
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<a href="<TMPL_VAR NAME="PORTAL_URL">?cancel=1&skin=<TMPL_VAR NAME="SKIN">" class="btn btn-primary" role="button">
|
||||
<span class="fa fa-home"></span>
|
||||
<span trspan="goToPortal">Go to portal</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- //if:jsminified
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">/common/js/notifications.min.js"></script>
|
||||
//else -->
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">/common/js/notifications.js"></script>
|
||||
<!-- //endif -->
|
||||
|
||||
<TMPL_INCLUDE NAME="footer.tpl">
|
||||
|
Loading…
Reference in New Issue
Block a user