', {
class: ['compact', 'stripe', 'order-column', 'row-border', 'pf-table-fixed'].join(' ')
});
logsElement.append(logTable);
let serverDate = Util.getServerTime();
let serverHours = serverDate.setHours(0,0,0,0);
let logDataTable = logTable.DataTable({
pageLength: 25,
paging: true,
lengthMenu: [[10, 25, 50, 100], [10, 25, 50, 100]],
pagingType: 'full_numbers',
ordering: false,
autoWidth: false,
searching: true,
hover: false,
data: [],
language: {
emptyTable: 'No logs available',
zeroRecords: 'No logs found',
lengthMenu: 'Show _MENU_ rows',
info: 'Showing _START_ to _END_ of _TOTAL_ rows'
},
columnDefs: [
{
targets: 0,
title: ' ',
width: 12,
data: 'context.tag',
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display'){
let className = 'txt-color-' + data;
value = '';
}
return value;
}
}
},{
targets: 1,
name: 'timestamp',
title: '',
width: 100,
className: ['text-right'].join(' '),
data: 'datetime',
render: {
_: function(data, type, row, meta){
let value = '';
let logDateString;
if(typeof data === 'string' && data.length){
// NEW: > v1.5.5 e.g: '2019-12-09T22:07:01.382455+00:00'
logDateString = data;
}else if(data && data.date){
// OLD: <= v1.5.5 object data.date: '2019-12-09 14:50:46.608484'
logDateString = data.date;
}
if(logDateString){
logDateString = logDateString
.substring(0, 19)
.replace(/-/g, '/')
.replace(/T/g, ' ');
let logDate = new Date(logDateString);
value = Util.convertDateToString(logDate, true);
// check whether log is new (today) ->
if(logDate.setHours(0,0,0,0) === serverHours){
// replace dd/mm/YYYY
value = 'today' + value.substring(10);
}
}
return value;
}
}
},{
targets: 2,
title: 'level',
width: 40,
data: 'level_name'
},{
targets: 3,
title: 'channel',
className: [config.tableCellEllipsisClass].join(' '),
width: 40,
data: 'channel'
},{
targets: 4,
title: 'message',
width: 115,
data: 'message',
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display'){
let className = 'txt-color-';
if(Util.getObjVal(row, 'context.tag')){
className += row.context.tag;
}
value = '' + value + '';
}
return value;
}
}
},{
targets: 5,
title: '',
width: 26,
searchable: false,
className: [config.tableCellImageClass].join(' '),
data: 'context.data.character.id' ,
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display'){
value = '
';
}
return value;
}
}
},{
targets: 6,
title: 'pilot',
width: 110,
className: [config.tableCellActionClass].join(' '),
data: 'context.data.character.name',
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display'){
value += ' ' + getIconForInformationWindow();
}
return value;
}
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
// open character information window (ingame)
$(cell).on('click', { tableApi: this.api(), rowIndex: rowIndex }, function(e){
let rowData = e.data.tableApi.row(e.data.rowIndex).data();
Util.openIngameWindow(rowData.context.data.character.id);
});
}
},{
targets: 7,
title: 'context',
className: [config.tableCellEllipsisClass].join(' '),
data: 'context.data.formatted'
},{
targets: 8,
title: '',
width: 12,
className: [config.tableCellActionClass].join(' '),
data: 'context.data',
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display'){
value = '';
}
return value;
}
},
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
// unset formatted string (to much content)
$(cell).on('mouseenter', function(e){
let cell = $(this);
if(!cell.data('bs.popover')){
if(cellData.formatted){
// clone data before delete() values
cellData = Object.assign({}, cellData);
delete(cellData.formatted);
}
let jsonHighlighted = Render.highlightJson(cellData);
let content = '' + jsonHighlighted + '
';
// open popover with raw log data
cell.popover({
placement: 'left',
html: true,
trigger: 'hover',
content: content,
container: 'body',
title: 'Raw data',
delay: {
show: 180,
hide: 0
}
});
cell.popover('show');
}
});
}
}
],
initComplete: function(settings){
let tableApi = this.api();
// empty table is ready -> load logs
getLogsData({
mapId: mapData.config.id
}, {
tableApi: tableApi,
callback: updateTableDataCallback,
logsElement: logsElement
});
},
drawCallback: function(settings){
let tableApi = this.api();
// en/disable "load more" button ----------------------------------------------------------------------
let tableInfo = tableApi.page.info();
let isLastPage = (tableInfo.pages === 0 || tableInfo.page === tableInfo.pages - 1);
tableApi.button(0).enable(isLastPage);
// adjust "timestamp" column width --------------------------------------------------------------------
let timestampColumn = tableApi.column('timestamp:name').header();
let timestampColumnCells = tableApi.cells(undefined, 'timestamp:name', {page: 'current', order:'current'});
let hasOldLogs = timestampColumnCells.render('display').reduce((hasOldLogs, cellValue) => {
return (hasOldLogs === false && !cellValue.startsWith('today')) ? true : hasOldLogs;
}, false);
if(hasOldLogs){
$(timestampColumn).css({width: '100px'});
}else{
$(timestampColumn).css({width: '80px'});
}
}
});
// ------------------------------------------------------------------------------------------------------------
// add dataTable buttons (extension)
logsElement.append($('', {
class: config.tableToolsClass
}));
let buttons = new $.fn.dataTable.Buttons(logDataTable, {
buttons: [
{
className: 'btn btn-sm btn-default',
text: ' load more',
enabled: false,
action: function(e, dt, node, config ){
let pageInfo = dt.page.info();
getLogsData({
mapId: mapData.config.id,
limit: pageInfo.length,
offset: pageInfo.recordsTotal
}, {
tableApi: dt,
callback: updateTableDataCallback,
logsElement: logsElement
});
}
}
]
} );
logDataTable.buttons().container().appendTo($(this).find('.' + config.tableToolsClass));
};
/**
* shows the map information modal dialog
* @param options
*/
$.fn.showMapInfoDialog = function(options){
let activeMap = Util.getMapModule().getActiveMap();
let mapData = activeMap ? activeMap.getMapDataFromClient(['hasId']) : false;
if(mapData !== false){
// "log" tab -> get "Origin", not all config options are set in mapData
let mapDataOrigin = Util.getCurrentMapData(mapData.config.id);
requirejs(['text!templates/dialog/map_info.html', 'mustache'], (template, Mustache) => {
let data = {
dialogSummaryContainerId: config.dialogMapInfoSummaryId,
dialogUsersContainerId: config.dialogMapInfoUsersId,
dialogLogsContainerId: config.dialogMapInfoLogsId,
dialogRefreshContainerId: config.dialogMapInfoRefreshId,
dialogNavigationClass: config.dialogNavigationClass,
mapInfoId: config.mapInfoId,
mapInfoSystemsId: config.mapInfoSystemsId,
mapInfoConnectionsId: config.mapInfoConnectionsId,
mapInfoUsersId: config.mapInfoUsersId,
mapInfoLogsId: config.mapInfoLogsId,
logHistoryEnabled: Boolean(Util.getObjVal(mapDataOrigin, 'config.logging.history')),
// default open tab ----------
openTabInformation: options.tab === 'information',
openTabActivity: options.tab === 'activity',
openTabLog: options.tab === 'log'
};
let content = Mustache.render(template, data);
let mapInfoDialog = bootbox.dialog({
title: 'Map information',
message: content,
size: 'large',
buttons: {
success: {
label: 'close',
className: 'btn-primary',
callback: function(){
$(mapInfoDialog).modal('hide');
}
}
}
});
mapInfoDialog.on('shown.bs.modal', function(e){
let mapInfoDialog = $(this);
let mapElement = $('#' + config.mapInfoId);
let systemsElement = $('#' + config.mapInfoSystemsId);
let connectionsElement = $('#' + config.mapInfoConnectionsId);
let usersElement = $('#' + config.mapInfoUsersId);
// set refresh button observer
$('#' + config.dialogMapInfoRefreshId).on('click', function(e){
let menuAction = $(this).attr('data-action');
if(menuAction === 'refresh'){
// get new map data
let mapData = activeMap.getMapDataFromClient(['hasId']);
// find active tab
let activeTabLink = $(this).parents('.navbar').find('.navbar-header.pull-left li.active a');
if(activeTabLink.attr('href') === '#' + config.dialogMapInfoLogsId){
$('#' + config.mapInfoLogsId).initLogsInfoTable(mapDataOrigin);
}
mapElement.initMapInfoData(mapData);
systemsElement.initSystemInfoTable(mapData);
connectionsElement.initConnectionInfoTable(mapData);
usersElement.initUsersInfoTable(mapData);
}
});
// load map data
mapElement.initMapInfoData(mapData);
// load system table
systemsElement.initSystemInfoTable(mapData);
// load connection table
connectionsElement.initConnectionInfoTable(mapData);
// load users table
usersElement.initUsersInfoTable(mapData);
// set global dialog observer
setDialogObserver(mapInfoDialog, mapData);
});
// events for tab change
mapInfoDialog.find('.navbar a').on('shown.bs.tab', function(e){
if($(e.target).attr('href') === '#' + config.dialogMapInfoLogsId){
// "log" tab
let mapDataOrigin = Util.getCurrentMapData(mapData.config.id);
$('#' + config.mapInfoLogsId).initLogsInfoTable(mapDataOrigin);
}
});
});
}else{
// no active map found (e.g. not loaded yet, or no map exists)
Util.showNotify({
title: 'Map data not found',
text: 'No map initialized at this point',
type: 'warning'}
);
}
};
});