Merge pull request #1164 from zklosko/export
Return of Playout History Exporting!
This commit is contained in:
commit
617e548db0
|
@ -72,7 +72,6 @@ class ListenerstatController extends Zend_Controller_Action
|
||||||
|
|
||||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/ColVis.css?'.$CC_CONFIG['airtime_version']);
|
$this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/ColVis.css?'.$CC_CONFIG['airtime_version']);
|
||||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/dataTables.colReorder.min.css?'.$CC_CONFIG['airtime_version']);
|
$this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/dataTables.colReorder.min.css?'.$CC_CONFIG['airtime_version']);
|
||||||
$this->view->headLink()->appendStylesheet($baseUrl.'js/datatables/plugin/TableTools-2.1.5/css/TableTools.css?'.$CC_CONFIG['airtime_version']);
|
|
||||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.ui.timepicker.css?'.$CC_CONFIG['airtime_version']);
|
$this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.ui.timepicker.css?'.$CC_CONFIG['airtime_version']);
|
||||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/show_analytics.css'.$CC_CONFIG['airtime_version']);
|
$this->view->headLink()->appendStylesheet($baseUrl.'css/show_analytics.css'.$CC_CONFIG['airtime_version']);
|
||||||
|
|
||||||
|
|
|
@ -46,17 +46,17 @@ class PlayouthistoryController extends Zend_Controller_Action
|
||||||
$this->view->headScript()->appendFile($baseUrl.'js/datatables/js/jquery.dataTables.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
$this->view->headScript()->appendFile($baseUrl.'js/datatables/js/jquery.dataTables.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||||
$this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.pluginAPI.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
$this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.pluginAPI.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||||
$this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.fnSetFilteringDelay.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
$this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.fnSetFilteringDelay.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||||
$this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/TableTools-2.1.5/js/ZeroClipboard.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
|
||||||
$this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/TableTools-2.1.5/js/TableTools.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
|
||||||
|
|
||||||
$this->view->headScript()->appendFile($baseUrl.'js/timepicker/jquery.ui.timepicker.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
$this->view->headScript()->appendFile($baseUrl.'js/timepicker/jquery.ui.timepicker.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||||
$this->view->headScript()->appendFile($baseUrl.'js/bootstrap-datetime/bootstrap-datetimepicker.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
$this->view->headScript()->appendFile($baseUrl.'js/bootstrap-datetime/bootstrap-datetimepicker.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/buttons/buttons.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
$this->view->headScript()->appendFile($baseUrl.'js/airtime/buttons/buttons.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/utilities/utilities.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
$this->view->headScript()->appendFile($baseUrl.'js/airtime/utilities/utilities.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||||
|
$this->view->headScript()->appendFile($baseUrl.'js/libs/CSVexport.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||||
|
$this->view->headScript()->appendFile($baseUrl.'js/libs/pdfmake.min.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||||
|
$this->view->headScript()->appendFile($baseUrl.'js/libs/vfs_fonts.min.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/playouthistory/historytable.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
$this->view->headScript()->appendFile($baseUrl.'js/airtime/playouthistory/historytable.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||||
|
|
||||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/bootstrap-datetimepicker.min.css?'.$CC_CONFIG['airtime_version']);
|
$this->view->headLink()->appendStylesheet($baseUrl.'css/bootstrap-datetimepicker.min.css?'.$CC_CONFIG['airtime_version']);
|
||||||
$this->view->headLink()->appendStylesheet($baseUrl.'js/datatables/plugin/TableTools-2.1.5/css/TableTools.css?'.$CC_CONFIG['airtime_version']);
|
|
||||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.ui.timepicker.css?'.$CC_CONFIG['airtime_version']);
|
$this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.ui.timepicker.css?'.$CC_CONFIG['airtime_version']);
|
||||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/playouthistory.css?'.$CC_CONFIG['airtime_version']);
|
$this->view->headLink()->appendStylesheet($baseUrl.'css/playouthistory.css?'.$CC_CONFIG['airtime_version']);
|
||||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/history_styles.css?'.$CC_CONFIG['airtime_version']);
|
$this->view->headLink()->appendStylesheet($baseUrl.'css/history_styles.css?'.$CC_CONFIG['airtime_version']);
|
||||||
|
|
|
@ -243,7 +243,6 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
"</button>" +
|
"</button>" +
|
||||||
"</div>");
|
"</div>");
|
||||||
|
|
||||||
|
|
||||||
$menu.append("<div class='btn-group'>" +
|
$menu.append("<div class='btn-group'>" +
|
||||||
"<button class='btn btn-small dropdown-toggle' data-toggle='dropdown'>" +
|
"<button class='btn btn-small dropdown-toggle' data-toggle='dropdown'>" +
|
||||||
$.i18n._("Select")+" <span class='caret'></span>" +
|
$.i18n._("Select")+" <span class='caret'></span>" +
|
||||||
|
@ -253,13 +252,23 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
"<li class='his-dselect-page'><a href='#'>"+$.i18n._("Deselect this page")+"</a></li>" +
|
"<li class='his-dselect-page'><a href='#'>"+$.i18n._("Deselect this page")+"</a></li>" +
|
||||||
"<li class='his-dselect-all'><a href='#'>"+$.i18n._("Deselect all")+"</a></li>" +
|
"<li class='his-dselect-all'><a href='#'>"+$.i18n._("Deselect all")+"</a></li>" +
|
||||||
"</ul>" +
|
"</ul>" +
|
||||||
"</div>");
|
"</div>");
|
||||||
|
|
||||||
|
$menu.append("<div class='btn-group'>" +
|
||||||
|
"<button class='btn btn-small dropdown-toggle' data-toggle='dropdown'>" +
|
||||||
|
$.i18n._("Export")+" <span class='caret'></span>" +
|
||||||
|
"</button>" +
|
||||||
|
"<ul class='dropdown-menu'>" +
|
||||||
|
"<li id='csv_export'><a href='#'>"+$.i18n._("Export as CSV")+"</a></li>" +
|
||||||
|
"<li id='pdf_export'><a href='#'>"+$.i18n._("Export as PDF")+"</a></li>" +
|
||||||
|
"</ul>" +
|
||||||
|
"</div>");
|
||||||
|
|
||||||
$menu.append("<div class='btn-group'>" +
|
$menu.append("<div class='btn-group'>" +
|
||||||
"<button class='btn btn-small' id='his_trash'>" +
|
"<button class='btn btn-small' id='his_trash'>" +
|
||||||
"<i class='icon-white icon-trash'></i>" +
|
"<i class='icon-white icon-trash'></i>" +
|
||||||
"</button>" +
|
"</button>" +
|
||||||
"</div>");
|
"</div>");
|
||||||
|
|
||||||
$el.append($menu);
|
$el.append($menu);
|
||||||
}
|
}
|
||||||
|
@ -508,7 +517,9 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
removeHistoryDialog();
|
removeHistoryDialog();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hisSubmit(); // Fixes display bug
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Icon hover states for search.
|
* Icon hover states for search.
|
||||||
|
@ -568,7 +579,114 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
makeHistoryDialog(json.dialog);
|
makeHistoryDialog(json.dialog);
|
||||||
|
|
||||||
}, "json");
|
}, "json");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$historyContentDiv.on("click", "#pdf_export", async function(){
|
||||||
|
// Get date/time from pickers
|
||||||
|
var startDay = document.querySelector('#his_date_start').value;
|
||||||
|
var startTime = document.querySelector('#his_time_start').value;
|
||||||
|
var endDay = document.querySelector('#his_date_end').value;
|
||||||
|
var endTime = document.querySelector('#his_time_end').value;
|
||||||
|
|
||||||
|
var url = baseUrl + "api/item-history-feed?start=" + startDay + " " + startTime + "&end=" + endDay + " " + endTime;
|
||||||
|
var requestData = await fetch(url);
|
||||||
|
var hisData = await requestData.json();
|
||||||
|
|
||||||
|
if (!hisData.length) {
|
||||||
|
alert("The date range selected doesn't have any items to export.");
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
// Generate PDF template
|
||||||
|
var dd = {
|
||||||
|
content: [
|
||||||
|
{text: 'Libretime', style: 'subheader'},
|
||||||
|
{text: 'Playout History from ' + startDay + ' ' + startTime + ' to ' + endDay + ' ' + endTime, style: 'header'},
|
||||||
|
{
|
||||||
|
style: 'mainTable',
|
||||||
|
table: {
|
||||||
|
headerRows: 1,
|
||||||
|
body: [
|
||||||
|
[{text: 'Start Time', style: 'tableHeader'}, {text: 'End Time', style: 'tableHeader'}, {text: 'Song', style: 'tableHeader'}, {text: 'Artist', style: 'tableHeader'}],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
styles: {
|
||||||
|
header: {
|
||||||
|
fontSize: 18,
|
||||||
|
bold: true,
|
||||||
|
margin: [0, 0, 0, 10]
|
||||||
|
},
|
||||||
|
subheader: {
|
||||||
|
fontSize: 14,
|
||||||
|
bold: true,
|
||||||
|
margin: [0, 10, 0, 5]
|
||||||
|
},
|
||||||
|
mainTable: {
|
||||||
|
margin: [0, 5, 0, 15]
|
||||||
|
},
|
||||||
|
tableHeader: {
|
||||||
|
bold: true,
|
||||||
|
fontSize: 13,
|
||||||
|
color: 'black'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaultStyle: {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
hisData.forEach(element => {
|
||||||
|
// Removing extra fields
|
||||||
|
delete element.checkbox;
|
||||||
|
delete element.history_id;
|
||||||
|
delete element.instance_id;
|
||||||
|
dd.content[2].table.body.push(Object.values(element));
|
||||||
|
});
|
||||||
|
// Make PDF and start download
|
||||||
|
pdfMake.createPdf(dd).download();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
$historyContentDiv.on("click", "#csv_export", async function(){
|
||||||
|
// Get date/time from pickers
|
||||||
|
var startDay = document.querySelector('#his_date_start').value;
|
||||||
|
var startTime = document.querySelector('#his_time_start').value;
|
||||||
|
var endDay = document.querySelector('#his_date_end').value;
|
||||||
|
var endTime = document.querySelector('#his_time_end').value;
|
||||||
|
|
||||||
|
var url = baseUrl + "api/item-history-feed?start=" + startDay + " " + startTime + "&end=" + endDay + " " + endTime;
|
||||||
|
var requestData = await fetch(url);
|
||||||
|
var hisData = await requestData.json();
|
||||||
|
|
||||||
|
if (!hisData.length) {
|
||||||
|
alert("The date range selected doesn't have any items to export.");
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
// Clean returned data
|
||||||
|
hisData.forEach(element => {
|
||||||
|
// Start date/time
|
||||||
|
element.startDate = element.starts.split(" ")[0];
|
||||||
|
element.startTime = element.starts.split(" ")[1];
|
||||||
|
// End date/time
|
||||||
|
element.endDate = element.ends.split(" ")[0];
|
||||||
|
element.endTime = element.ends.split(" ")[1];
|
||||||
|
// Moving Title and Artist fields to the end
|
||||||
|
element.title = element.track_title;
|
||||||
|
element.artist = element.artist_name;
|
||||||
|
// Removing extra fields
|
||||||
|
delete element.checkbox;
|
||||||
|
delete element.history_id;
|
||||||
|
delete element.instance_id;
|
||||||
|
delete element.starts; // we already converted these, so we don't need them anymore
|
||||||
|
delete element.ends;
|
||||||
|
delete element.track_title;
|
||||||
|
delete element.artist_name;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var csvX = new CSVExport(hisData); // Actual export function
|
||||||
|
return false // Was part of the demo. Please leave as is.
|
||||||
|
});
|
||||||
|
|
||||||
$('body').on("click", ".his_file_cancel, .his_item_cancel", function(e) {
|
$('body').on("click", ".his_file_cancel, .his_item_cancel", function(e) {
|
||||||
removeHistoryDialog();
|
removeHistoryDialog();
|
||||||
|
@ -709,23 +827,26 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
|
|
||||||
return AIRTIME.utilities.fnGetScheduleRange(dateStartId, timeStartId, dateEndId, timeEndId);
|
return AIRTIME.utilities.fnGetScheduleRange(dateStartId, timeStartId, dateEndId, timeEndId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hisSubmit(){
|
||||||
|
var fn, info;
|
||||||
|
|
||||||
|
info = getStartEnd();
|
||||||
|
|
||||||
|
fn = fnServerData;
|
||||||
|
fn.start = info.start;
|
||||||
|
fn.end = info.end;
|
||||||
|
|
||||||
|
if (inShowsTab) {
|
||||||
|
showSummaryList(info.start, info.end);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
redrawTables();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
$historyContentDiv.find("#his_submit").click(function(ev){
|
$historyContentDiv.find("#his_submit").click(function(ev){
|
||||||
var fn,
|
hisSubmit();
|
||||||
info;
|
|
||||||
|
|
||||||
info = getStartEnd();
|
|
||||||
|
|
||||||
fn = fnServerData;
|
|
||||||
fn.start = info.start;
|
|
||||||
fn.end = info.end;
|
|
||||||
|
|
||||||
if (inShowsTab) {
|
|
||||||
showSummaryList(info.start, info.end);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
redrawTables();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$historyContentDiv.on("click", ".his-select-page", selectCurrentPage);
|
$historyContentDiv.on("click", ".his-select-page", selectCurrentPage);
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
/**
|
||||||
|
@namespace Converts JSON to CSV.
|
||||||
|
|
||||||
|
Compress with: http://jscompress.com/
|
||||||
|
*/
|
||||||
|
(function (window) {
|
||||||
|
"use strict";
|
||||||
|
/**
|
||||||
|
Default constructor
|
||||||
|
*/
|
||||||
|
var _CSV = function (JSONData) {
|
||||||
|
if (typeof JSONData === 'undefined')
|
||||||
|
return;
|
||||||
|
|
||||||
|
var csvData = typeof JSONData != 'object' ? JSON.parse(settings.JSONData) : JSONData,
|
||||||
|
csvHeaders,
|
||||||
|
csvEncoding = 'data:text/csv;charset=utf-8,',
|
||||||
|
csvOutput = "",
|
||||||
|
csvRows = [],
|
||||||
|
BREAK = '\r\n',
|
||||||
|
DELIMITER = ',',
|
||||||
|
FILENAME = "export.csv";
|
||||||
|
|
||||||
|
// Get and Write the headers
|
||||||
|
csvHeaders = Object.keys(csvData[0]);
|
||||||
|
csvOutput += csvHeaders.join(',') + BREAK;
|
||||||
|
|
||||||
|
for (var i = 0; i < csvData.length; i++) {
|
||||||
|
var rowElements = [];
|
||||||
|
for(var k = 0; k < csvHeaders.length; k++) {
|
||||||
|
rowElements.push(csvData[i][csvHeaders[k]]);
|
||||||
|
} // Write the row array based on the headers
|
||||||
|
csvRows.push(rowElements.join(DELIMITER));
|
||||||
|
}
|
||||||
|
|
||||||
|
csvOutput += csvRows.join(BREAK);
|
||||||
|
|
||||||
|
// Initiate Download
|
||||||
|
var a = document.createElement("a");
|
||||||
|
|
||||||
|
if (navigator.msSaveBlob) { // IE10
|
||||||
|
navigator.msSaveBlob(new Blob([csvOutput], { type: "text/csv" }), FILENAME);
|
||||||
|
} else if ('download' in a) { //html5 A[download]
|
||||||
|
a.href = csvEncoding + encodeURIComponent(csvOutput);
|
||||||
|
a.download = FILENAME;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
setTimeout(function() {
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
}, 66);
|
||||||
|
} else if (document.execCommand) { // Other version of IE
|
||||||
|
var oWin = window.open("about:blank", "_blank");
|
||||||
|
oWin.document.write(csvOutput);
|
||||||
|
oWin.document.close();
|
||||||
|
oWin.document.execCommand('SaveAs', true, FILENAME);
|
||||||
|
oWin.close();
|
||||||
|
} else {
|
||||||
|
alert("Support for your specific browser hasn't been created yet, please check back later.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.CSVExport = _CSV;
|
||||||
|
|
||||||
|
})(window);
|
||||||
|
|
||||||
|
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
|
||||||
|
if (!Object.keys) {
|
||||||
|
Object.keys = (function() {
|
||||||
|
'use strict';
|
||||||
|
var hasOwnProperty = Object.prototype.hasOwnProperty,
|
||||||
|
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
|
||||||
|
dontEnums = [
|
||||||
|
'toString',
|
||||||
|
'toLocaleString',
|
||||||
|
'valueOf',
|
||||||
|
'hasOwnProperty',
|
||||||
|
'isPrototypeOf',
|
||||||
|
'propertyIsEnumerable',
|
||||||
|
'constructor'
|
||||||
|
],
|
||||||
|
dontEnumsLength = dontEnums.length;
|
||||||
|
|
||||||
|
return function(obj) {
|
||||||
|
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
|
||||||
|
throw new TypeError('Object.keys called on non-object');
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = [], prop, i;
|
||||||
|
|
||||||
|
for (prop in obj) {
|
||||||
|
if (hasOwnProperty.call(obj, prop)) {
|
||||||
|
result.push(prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasDontEnumBug) {
|
||||||
|
for (i = 0; i < dontEnumsLength; i++) {
|
||||||
|
if (hasOwnProperty.call(obj, dontEnums[i])) {
|
||||||
|
result.push(dontEnums[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue