Skip to content

Commit 853d1f9

Browse files
authored
Merge pull request #483 from timeoff-management/tom-xxx-notification-bell
Expose notification bell in the header
2 parents edc4ce4 + 0839c2b commit 853d1f9

File tree

4 files changed

+100
-2
lines changed

4 files changed

+100
-2
lines changed

app.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ app.use(
117117
require('./lib/route/dashboard')
118118
);
119119

120+
app.use('/api/v1/', require('./lib/route/api'));
121+
120122
app.use(
121123
'/calendar/',
122124
require('./lib/route/calendar')

lib/route/api/index.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
2+
"use strict";
3+
4+
const
5+
express = require('express'),
6+
router = express.Router();
7+
8+
9+
const NOTIFICATION_TYPE_PENDING_REQUESTS = 'pending_request';
10+
11+
/**
12+
* Factory method that created a notification of given type
13+
*/
14+
const newNotification = ({type, value}) => {
15+
16+
if (type === NOTIFICATION_TYPE_PENDING_REQUESTS) {
17+
return {
18+
type,
19+
numberOfRequests: value,
20+
label: (value === 1 ? 'A leave request to process' : `${value} leave requests to process`),
21+
link: '/requests/',
22+
}
23+
}
24+
25+
return null;
26+
};
27+
28+
router.get('/notifications/', async (req, res) => {
29+
const actingUser = req.user;
30+
31+
const data = [];
32+
33+
try {
34+
const leaves = await actingUser.promise_leaves_to_be_processed();
35+
36+
if (leaves.length > 0) {
37+
data.push(newNotification({type: NOTIFICATION_TYPE_PENDING_REQUESTS, value: leaves.length}));
38+
}
39+
40+
res.json({data});
41+
} catch (error) {
42+
console.log(`Failed to fetch notifications for user [${actingUser.id}]: ${error} at ${error.stack}`);
43+
res.json({ error: 'Failed to fetch notifications.' });
44+
}
45+
});
46+
47+
module.exports = router;

public/js/global.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ $(document).ready(function(){
189189
$('#'+divId).html(response);
190190
}
191191
});
192+
192193
return '<div id="'+ divId +'">Loading...</div>';
193194
}
194195
});
@@ -216,3 +217,42 @@ $(document).ready(function(){
216217
return '<div id="'+ divId +'">Loading...</div>';
217218
}
218219
});
220+
221+
$(document).ready(function() {
222+
if (typeof($.ajax) === 'function') {
223+
$.ajax({
224+
url: '/api/v1/notifications/',
225+
success: function(args){
226+
const error = args.error;
227+
const data = args.data;
228+
229+
if (error) {
230+
console.log('Failed to fetch notifications');
231+
return;
232+
}
233+
234+
if (!data || !data.length) {
235+
return;
236+
}
237+
238+
$('#header-notification-dropdown .notification-badge')
239+
.removeClass('hidden')
240+
.html(
241+
data
242+
.map(function(d) {return d.numberOfRequests})
243+
.reduce(function(acc, it){ return acc + it}, 0)
244+
);
245+
246+
const dropDown = $('#header-notification-dropdown ul.dropdown-menu');
247+
dropDown.empty();
248+
249+
for (var i=0; i<data.length; i++) {
250+
const notification = data[i];
251+
dropDown.append(
252+
'<li><a href="'+notification.link+'">'+notification.label+'</a></li>'
253+
);
254+
}
255+
}
256+
});
257+
}
258+
});

views/partials/header.hbs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,17 @@
3333
</ul>
3434
<ul class="nav navbar-nav navbar-right">
3535
<li>
36-
{{# if logged_user }}
37-
{{# if logged_user.admin }}
36+
{{#if logged_user }}
37+
<li class="dropdown" id="header-notification-dropdown">
38+
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
39+
<span class="fa fa-bell-o"></span>
40+
<span class="label label-info notification-badge hidden"></span>
41+
</a>
42+
<ul class="dropdown-menu" role="menu">
43+
<li class="dropdown-header">No notifications</li>
44+
</ul>
45+
</li>
46+
{{#if logged_user.admin }}
3847
<li class="dropdown hidden-xs">
3948
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><span class="fa fa-gears"></span> <span class="caret"></span></a>
4049
<ul class="dropdown-menu" role="menu">

0 commit comments

Comments
 (0)