UNPKG

lisa-api

Version:

Lisa Javascript XMPP Library =============

375 lines (292 loc) 8.7 kB
var conn; var model; // update every 5 seconds, max 300 points = 25 minutes var GRAPH_MAX_POINTS = 300; var GRAPH_REFRESH_INTERVAL = 5*1000; $(document).ready(function() { // Default server (SpeakUp NL production) $('#login_server').val('uc.pbx.speakup-telecom.com'); $('#login_form').submit(function() { login(); return false; }); var username = localStorage ? localStorage.getItem('username') : null; if (username) { $('#login_username').val(username); $('#login_server').val(localStorage.getItem('server')); } }); function login() { $('#login').hide(); $('#loading').show(); $('#login_error').hide(); var username = $('#login_username').val(); var password = $('#login_password').val(); var server = $('#login_server').val(); localStorage.setItem('username', username); localStorage.setItem('server', server); conn = new Lisa.Connection(); // Setup logging and status messages. conn.logging.setCallback(function(msg) { console.log(msg); }); conn.logging.setStatusCallback(function(msg) { $('#status').text(msg); }); // Setup connection-status callback. conn.connectionStatusObservable.addObserver(connectionStatusCallback); $('#status').text('Connecting...'); var jid = username; // either username or username@domain if (jid.indexOf('@') == -1) { jid = username + '@' + server; } /* * Get the correct https://bosh.<basedomain> bosh-proxy server */ boshServer = getEnvWithPrefix("bosh", server); conn.connect(boshServer, jid, password); // Get the company-model conn.getModel().done(gotModel); conn.getModel().fail(function() { connectionStatusCallback("INITFAIL"); }); } function connectionStatusCallback(status) { console.log("Strophe: status is ", status); if (status == Strophe.Status.CONNFAIL) { $('#connect').get(0).value = 'connect'; } else if (status == Strophe.Status.DISCONNECTED) { $('#connect').get(0).value = 'connect'; } else if (status == Strophe.Status.CONNECTED) { $('#status').text('Loading...'); } else if (status == Strophe.Status.AUTHFAIL) { $('#loading').hide(); $('#login').show(); $('#login_error').show(); $('#login_error').text('Authentication failed.'); } else if (status == "INITFAIL") { $('#loading').hide(); $('#login').show(); $('#login_error').show(); $('#login_error').text("Authentication successfull, but server not responding as expected. Try again later, or contact support."); } } function gotModel(newModel) { // Show interface $('#loading').hide(); $('#container').show(); model = newModel; refreshModel(model); initGraph(); // Listen for added or removed users or queues, which requires to redraw the whole structure. model.userListObservable.addObserver(refreshModel); model.queueListObservable.addObserver(refreshModel); model.callListObservable.addObserver(updateCalls); setInterval(updateGraph, GRAPH_REFRESH_INTERVAL); } function refreshModel(model) { console.log("Refreshing interface.") $('#queue-list').empty(); // Add queues to interface. for ( var queueId in model.queues) { addQueue(model.queues[queueId]); } // Add users to interface. for ( var userId in model.users) { // We're only listening for changes in the logged-on user. Remove if to listen for all users. if (userId == Lisa.Connection.myUserId) { var user = model.getUser(userId); var entry = $('#tpl_own_user').clone().attr('id', 'myuser'); user.observable.addObserver(function(changedUser) { updateUser(changedUser, entry); }); user.observable.notify(user); $('#myuser').html(user.name + ' [' + user.extension + ']'); } } } function updateUser(user, entry) { entry.find('.user_name').text(user.name); var status_entry = entry.find('.user_status'); if (_.size(user.calls) > 0) { status_entry.text('Calling...'); $(entry).animate({backgroundColor: "#CCCCCC"}, 1000); } else { status_entry.text('Extension: ' + user.extension); $(entry).animate({backgroundColor: "transparant"}, 1000); } } /* Add / Update the page-elements for queues */ function addQueue(queue) { var entry = $('#tpl_queue').clone().attr('id', 'queue_' + queue.id); entry.find('.queue_name').text(queue.name); $('#queue-list').append(entry); updateQueue(queue); queue.observable.addObserver(function(queue) { updateQueue(queue); }); } function updateQueue(queue) { var entry = $('#queue_' + queue.id); var agents = 0; for ( var userId in queue.users) { var user = queue.users[userId]; if (user.loggedIn) { ++agents; } } var calls = _.size(queue.calls); entry.find('.queue_agents').text('Agents: ' + agents); entry.find('.queue_calls').text('Calls in queue: ' + calls); entry.find('.queue_waiting').text( 'Total calls today: ' + queue.totalCalls); if (calls == 0) { entry.css('background-color', "lightblue"); $(entry).animate({ backgroundColor : "transparant" }, 1000); } else if (calls < 5) { entry.css('background-color', "00FF00"); $(entry).animate({ backgroundColor : "#85FF5C" }, 1000); } else { entry.css('background-color', "FF0000"); $(entry).animate({ backgroundColor : "#FF5050" }, 1000); } } // http://learn.jquery.com/using-jquery-core/faq/how-do-i-select-an-element-by-an-id-that-has-characters-used-in-css-notation/ function safeId(myid) { return myid.replace(/(:|\.|\[|\]|\@|\/)/g, "\\$1"); } /* Add / Update the page-elements for calls */ function updateCalls(call, type) { if (type == 'remove') { var elem = $('#call_' + safeId(call.id)); var txt = elem.text(); elem.text(txt + ' ... ENDED'); elem.css('background-color', '#FA5858'); setTimeout(function() { elem.remove(); }, 500); // add to history var historyElem = $('#tpl_call').clone(); historyElem.text('Ended at ' + ((new Date()).toLocaleTimeString()) + ': ' + txt); $('#call-history').append(historyElem); } else if (type == 'add') { var elem = $('#tpl_call').clone().attr('id', 'call_' + call.id); updateCall(call, elem); $('#current-calls').append(elem); call.observable.addObserver(function(call) { updateCall(call); }); } } function updateCall(call, elem) { if (!elem) { elem = $('#call_' + safeId(call.id)); } elem.text(callToString(call)); } function callToString(call) { if (call == null) return ""; var str = 'Call from '; str += endpointToString(call.source); str += ' to '; str += endpointToString(call.destination); str += '.'; return str; } function endpointToString(endpoint) { if (endpoint == null) return ""; switch (endpoint.attr('type')) { case 'User': var userId = endpoint.find('userId').text(); var user = model.getUser(userId); return user.name + " [" + user.extension + "]"; case 'Dialplan': var txt = endpoint.find('description').text(); if (txt != '' ) return txt; return endpoint.find('exten').text(); case 'Queue': var queueId = endpoint.find('queueId').text(); var queue = model.getQueue(queueId); return "queue '" + queue.name + "'"; case 'External': return endpoint.find('number').text(); default: console.log('Cannot represent endpointType ' + endpoint.attr('type')); return '[unknown]'; } } /* Graph */ var graphSeries = []; var jqPlot; var maxYvalue = 0; function initGraph() { for(var queueId in model.queues) { graphSeries.push([]); } updateGraph(); } function updateGraph() { var i=0; var timestamp = Math.round(new Date().getTime()); // TODO: account for dynamically adding/removing queues for(queueId in model.queues) { var queue = model.queues[queueId]; var val = _.size(queue.calls); var point = [timestamp, val]; if (val > maxYvalue) maxYvalue = val; graphSeries[i].push(point); // limit amount of data points while(graphSeries[i].length > GRAPH_MAX_POINTS) { graphSeries[i].shift(); } i++; } // jqPlot cannot draw an empty graph if (graphSeries.length == 0) return; if (!jqPlot) { var labels = []; for(queueId in model.queues) { var queue = model.queues[queueId]; labels.push(queue.name); } console.log('plotting: ' + graphSeries); jqPlot = $.jqplot('chartdiv', graphSeries, { title: 'Number of Calls', axes:{ xaxis:{ renderer:$.jqplot.DateAxisRenderer, tickOptions:{formatString:'%H:%M'}, }, yaxis:{ min: 0, max: maxYvalue, }, }, legend: { show: true, labels: labels, location: 'nw', }, seriesDefaults: { showMarker: false, }, }); } else { for (i in jqPlot.series) { jqPlot.series[i].data = graphSeries[i] } jqPlot.resetAxesScale(); // no negative values jqPlot.axes.yaxis.min = 0; jqPlot.replot(); } }