- improved search results for "Corporation" dropdown
This commit is contained in:
@@ -461,7 +461,7 @@ define([
|
||||
* @param term search term
|
||||
*/
|
||||
function sortResultData (data, term){
|
||||
let levenshtein = function (a,b){
|
||||
let levenshtein = (a,b) => {
|
||||
let matrix = new Array(a.length+1);
|
||||
for(let i = 0; i < matrix.length; i++){
|
||||
matrix[i] = new Array(b.length+1).fill(0);
|
||||
@@ -480,7 +480,7 @@ define([
|
||||
matrix[ai][bi] = Math.min(
|
||||
matrix[ai-1][bi]+1,
|
||||
matrix[ai][bi-1]+1,
|
||||
matrix[ai-1][bi-1]+(a[ai-1] == b[bi-1] ? 0 : 1)
|
||||
matrix[ai-1][bi-1]+(a[ai-1] === b[bi-1] ? 0 : 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -488,7 +488,7 @@ define([
|
||||
return matrix[a.length][b.length];
|
||||
};
|
||||
|
||||
data.sort(function(a,b){
|
||||
data.sort((a,b) => {
|
||||
let levA = levenshtein(term, a.name.toLowerCase());
|
||||
let levB = levenshtein(term, b.name.toLowerCase());
|
||||
return levA === levB ? 0 : (levA > levB ? 1 : -1);
|
||||
@@ -531,6 +531,7 @@ define([
|
||||
for(let category in result){
|
||||
// skip custom functions in case result = [] (array functions)
|
||||
if(result.hasOwnProperty(category)){
|
||||
// sort results (optional)
|
||||
sortResultData(result[category], page.term);
|
||||
data.results.push({
|
||||
text: category,
|
||||
|
||||
@@ -1220,7 +1220,7 @@ define([
|
||||
searchable: true,
|
||||
title: 'id',
|
||||
type: 'string',
|
||||
width: 15,
|
||||
width: 12,
|
||||
class: [config.tableCellFocusClass, config.sigTableEditSigNameInput].join(' '),
|
||||
data: 'name',
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -461,7 +461,7 @@ define([
|
||||
* @param term search term
|
||||
*/
|
||||
function sortResultData (data, term){
|
||||
let levenshtein = function (a,b){
|
||||
let levenshtein = (a,b) => {
|
||||
let matrix = new Array(a.length+1);
|
||||
for(let i = 0; i < matrix.length; i++){
|
||||
matrix[i] = new Array(b.length+1).fill(0);
|
||||
@@ -480,7 +480,7 @@ define([
|
||||
matrix[ai][bi] = Math.min(
|
||||
matrix[ai-1][bi]+1,
|
||||
matrix[ai][bi-1]+1,
|
||||
matrix[ai-1][bi-1]+(a[ai-1] == b[bi-1] ? 0 : 1)
|
||||
matrix[ai-1][bi-1]+(a[ai-1] === b[bi-1] ? 0 : 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -488,7 +488,7 @@ define([
|
||||
return matrix[a.length][b.length];
|
||||
};
|
||||
|
||||
data.sort(function(a,b){
|
||||
data.sort((a,b) => {
|
||||
let levA = levenshtein(term, a.name.toLowerCase());
|
||||
let levB = levenshtein(term, b.name.toLowerCase());
|
||||
return levA === levB ? 0 : (levA > levB ? 1 : -1);
|
||||
@@ -531,6 +531,7 @@ define([
|
||||
for(let category in result){
|
||||
// skip custom functions in case result = [] (array functions)
|
||||
if(result.hasOwnProperty(category)){
|
||||
// sort results (optional)
|
||||
sortResultData(result[category], page.term);
|
||||
data.results.push({
|
||||
text: category,
|
||||
|
||||
@@ -1220,7 +1220,7 @@ define([
|
||||
searchable: true,
|
||||
title: 'id',
|
||||
type: 'string',
|
||||
width: 15,
|
||||
width: 12,
|
||||
class: [config.tableCellFocusClass, config.sigTableEditSigNameInput].join(' '),
|
||||
data: 'name',
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,248 +0,0 @@
|
||||
/**
|
||||
* System graph module
|
||||
*/
|
||||
|
||||
define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util',
|
||||
'morris'
|
||||
], ($, Init, Util, Morris) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
// module info
|
||||
modulePosition: 3,
|
||||
moduleName: 'systemGraph',
|
||||
moduleHeadClass: 'pf-module-head', // class for module header
|
||||
moduleHandlerClass: 'pf-module-handler-drag', // class for "drag" handler
|
||||
|
||||
// system graph module
|
||||
moduleTypeClass: 'pf-system-graph-module', // class for this module
|
||||
systemGraphClass: 'pf-system-graph', // class for each graph
|
||||
|
||||
// system graph labels
|
||||
systemGraphs: {
|
||||
jumps: {
|
||||
headline: 'Jumps',
|
||||
units: 'jumps',
|
||||
ykeys: ['y'],
|
||||
labels: ['jumps'],
|
||||
lineColors: ['#375959'],
|
||||
pointFillColors: ['#477372']
|
||||
},
|
||||
shipKills: {
|
||||
headline: 'Ship/POD Kills',
|
||||
units: 'kills',
|
||||
ykeys: ['y', 'z'],
|
||||
labels: ['Ship kills', 'POD kills'],
|
||||
lineColors: ['#375959', '#477372'],
|
||||
pointFillColors: ['#477372', '#568a89']
|
||||
},
|
||||
factionKills: {
|
||||
headline: 'NPC Kills',
|
||||
units: 'kills',
|
||||
ykeys: ['y'],
|
||||
labels: ['kills'],
|
||||
lineColors: ['#375959'],
|
||||
pointFillColors: ['#477372']
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* get info for a given graph key
|
||||
* @param graphKey
|
||||
* @param option
|
||||
* @returns {string}
|
||||
*/
|
||||
let getInfoForGraph = function(graphKey, option){
|
||||
let info = '';
|
||||
if(config.systemGraphs.hasOwnProperty(graphKey)){
|
||||
info = config.systemGraphs[graphKey][option];
|
||||
}
|
||||
|
||||
return info;
|
||||
};
|
||||
|
||||
/**
|
||||
* init Morris Graph
|
||||
* @param graphElement
|
||||
* @param graphKey
|
||||
* @param graphData
|
||||
* @param eventLine
|
||||
*/
|
||||
let initGraph = function(graphElement, graphKey, graphData, eventLine){
|
||||
if(graphData.length > 0){
|
||||
let labelYFormat = function(y){
|
||||
return Math.round(y);
|
||||
};
|
||||
|
||||
let graphConfig = {
|
||||
element: graphElement,
|
||||
data: graphData,
|
||||
xkey: 'x',
|
||||
ykeys: getInfoForGraph(graphKey, 'ykeys'),
|
||||
labels: getInfoForGraph(graphKey, 'labels'),
|
||||
parseTime: false,
|
||||
ymin: 0,
|
||||
yLabelFormat: labelYFormat,
|
||||
padding: 10,
|
||||
hideHover: true,
|
||||
pointSize: 3,
|
||||
lineColors: getInfoForGraph(graphKey, 'lineColors'),
|
||||
pointFillColors: getInfoForGraph(graphKey, 'pointFillColors'),
|
||||
pointStrokeColors: ['#141413'],
|
||||
lineWidth: 2,
|
||||
grid: true,
|
||||
gridStrokeWidth: 0.3,
|
||||
gridTextSize: 9,
|
||||
gridTextFamily: 'Oxygen Bold',
|
||||
gridTextColor: '#63676a',
|
||||
behaveLikeLine: false,
|
||||
goals: [],
|
||||
goalLineColors: ['#5cb85c'],
|
||||
smooth: true,
|
||||
fillOpacity: 0.2,
|
||||
resize: true,
|
||||
redraw: true,
|
||||
eventStrokeWidth: 2,
|
||||
eventLineColors: ['#5CB85C']
|
||||
};
|
||||
|
||||
if(eventLine >= 0){
|
||||
graphConfig.events = [eventLine];
|
||||
}
|
||||
|
||||
Morris.Area(graphConfig);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* request graphs data
|
||||
* @param requestData
|
||||
* @param context
|
||||
* @param callback
|
||||
*/
|
||||
let requestGraphData = (requestData, context, callback) => {
|
||||
// show loading animation
|
||||
context.moduleElement.find('.' + config.systemGraphClass).showLoadingAnimation();
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Init.path.getSystemGraphData,
|
||||
data: requestData,
|
||||
dataType: 'json',
|
||||
context: context
|
||||
}).done(function(systemGraphsData){
|
||||
callback(this, systemGraphsData);
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
let reason = status + ' ' + error;
|
||||
Util.showNotify({title: jqXHR.status + ': System graph data', text: reason, type: 'warning'});
|
||||
$(document).setProgramStatus('problem');
|
||||
this.moduleElement.hide();
|
||||
}).always(function(){
|
||||
// hide loading animation
|
||||
context.moduleElement.find('.' + config.systemGraphClass).hideLoadingAnimation();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* update graph elements with data
|
||||
* @param context
|
||||
* @param systemGraphsData
|
||||
*/
|
||||
let addGraphData = (context, systemGraphsData) => {
|
||||
|
||||
// calculate time offset until system created -----------------------------------------------------------------
|
||||
let serverData = Util.getServerTime();
|
||||
let timestampNow = Math.floor(serverData.getTime() / 1000);
|
||||
let timeSinceUpdate = timestampNow - context.systemData.updated.updated;
|
||||
|
||||
let timeInHours = Math.floor(timeSinceUpdate / 3600);
|
||||
let timeInMinutes = Math.floor((timeSinceUpdate % 3600) / 60);
|
||||
let timeInMinutesPercent = ( timeInMinutes / 60 ).toFixed(2);
|
||||
let eventLine = timeInHours + timeInMinutesPercent;
|
||||
|
||||
// graph is from right to left -> convert event line
|
||||
eventLine = 23 - eventLine;
|
||||
|
||||
// update graph data ------------------------------------------------------------------------------------------
|
||||
for (let [systemId, graphsData] of Object.entries(systemGraphsData)){
|
||||
for (let [graphKey, graphData] of Object.entries(graphsData)){
|
||||
let graphElement = context.moduleElement.find('[data-graph="' + graphKey + '"]');
|
||||
initGraph(graphElement, graphKey, graphData, eventLine);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @see requestGraphData
|
||||
* @param moduleElement
|
||||
* @param mapId
|
||||
* @param systemData
|
||||
*/
|
||||
let updateGraphPanel = (moduleElement, mapId, systemData) => {
|
||||
let requestData = {
|
||||
systemIds: [systemData.systemId]
|
||||
};
|
||||
|
||||
let contextData = {
|
||||
moduleElement: moduleElement,
|
||||
systemData: systemData
|
||||
};
|
||||
|
||||
requestGraphData(requestData, contextData, addGraphData);
|
||||
};
|
||||
|
||||
/**
|
||||
* get module element
|
||||
* @param parentElement
|
||||
* @param mapId
|
||||
* @param systemData
|
||||
* @returns {*}
|
||||
*/
|
||||
let getModule = (parentElement, mapId, systemData) => {
|
||||
// graph data is available for k-space systems
|
||||
let moduleElement = null;
|
||||
if(systemData.type.id === 2){
|
||||
moduleElement = $('<div>');
|
||||
let rowElement = $('<div>', {
|
||||
class: 'row'
|
||||
});
|
||||
|
||||
for (let [graphKey, graphConfig] of Object.entries(config.systemGraphs)){
|
||||
rowElement.append(
|
||||
$('<div>', {
|
||||
class: ['col-xs-12', 'col-sm-6', 'col-md-4'].join(' ')
|
||||
}).append(
|
||||
$('<div>', {
|
||||
class: config.moduleHeadClass
|
||||
}).append(
|
||||
$('<h5>', {
|
||||
class: config.moduleHandlerClass
|
||||
}),
|
||||
$('<h5>', {
|
||||
text: getInfoForGraph(graphKey, 'headline')
|
||||
})
|
||||
),
|
||||
$('<div>', {
|
||||
class: config.systemGraphClass
|
||||
}).attr('data-graph', graphKey)
|
||||
)
|
||||
);
|
||||
}
|
||||
moduleElement.append(rowElement);
|
||||
|
||||
updateGraphPanel(moduleElement, mapId, systemData);
|
||||
}
|
||||
|
||||
return moduleElement;
|
||||
};
|
||||
|
||||
return {
|
||||
config: config,
|
||||
getModule: getModule
|
||||
};
|
||||
|
||||
});
|
||||
@@ -1,421 +0,0 @@
|
||||
/**
|
||||
* System info module
|
||||
*/
|
||||
|
||||
define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util',
|
||||
'app/render',
|
||||
'app/map/util'
|
||||
], ($, Init, Util, Render, MapUtil) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
// module info
|
||||
modulePosition: 2,
|
||||
moduleName: 'systemInfo',
|
||||
|
||||
// system info module
|
||||
moduleTypeClass: 'pf-system-info-module', // class for this module
|
||||
|
||||
// breadcrumb
|
||||
constellationLinkClass: 'pf-system-info-constellation', // class for "constellation" name
|
||||
regionLinkClass: 'pf-system-info-region', // class for "region" name
|
||||
typeLinkClass: 'pf-system-info-type', // class for "type" name
|
||||
|
||||
// info table
|
||||
systemInfoTableClass: 'pf-module-table', // class for system info table
|
||||
systemInfoNameClass: 'pf-system-info-name', // class for "name" information element
|
||||
systemInfoEffectClass: 'pf-system-info-effect', // class for "effect" information element
|
||||
systemInfoPlanetsClass: 'pf-system-info-planets', // class for "planets" information element
|
||||
systemInfoStatusLabelClass: 'pf-system-info-status-label', // class for "status" information element
|
||||
systemInfoStatusAttributeName: 'data-status', // attribute name for status label
|
||||
systemInfoWormholeClass: 'pf-system-info-wormhole-', // class prefix for static wormhole element
|
||||
|
||||
// description field
|
||||
descriptionArea: 'pf-system-info-description-area', // class for "description" area
|
||||
addDescriptionButtonClass: 'pf-system-info-description-button', // class for "add description" button
|
||||
moduleElementToolbarClass: 'pf-table-tools', // class for "module toolbar" element
|
||||
tableToolsActionClass: 'pf-table-tools-action', // class for "edit" action
|
||||
|
||||
descriptionTextareaElementClass: 'pf-system-info-description', // class for "description" textarea element (xEditable)
|
||||
descriptionTextareaCharCounter: 'pf-form-field-char-count', // class for "character counter" element for form field
|
||||
|
||||
// fonts
|
||||
fontTriglivianClass: 'pf-triglivian' // class for "Triglivian" names (e.g. Abyssal systems)
|
||||
};
|
||||
|
||||
// disable Module update temporary (in case e.g. textarea is currently active)
|
||||
let disableModuleUpdate = false;
|
||||
|
||||
// animation speed values
|
||||
let animationSpeedToolbarAction = 200;
|
||||
|
||||
// max character length for system description
|
||||
let maxDescriptionLength = 512;
|
||||
|
||||
/**
|
||||
* shows the tool action element by animation
|
||||
* @param toolsActionElement
|
||||
*/
|
||||
let showToolsActionElement = (toolsActionElement) => {
|
||||
toolsActionElement.velocity('stop').velocity({
|
||||
opacity: 1,
|
||||
height: '100%'
|
||||
},{
|
||||
duration: animationSpeedToolbarAction,
|
||||
display: 'block',
|
||||
visibility: 'visible'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* hides the tool action element by animation
|
||||
* @param toolsActionElement
|
||||
*/
|
||||
let hideToolsActionElement = (toolsActionElement) => {
|
||||
toolsActionElement.velocity('stop').velocity('reverse', {
|
||||
display: 'none',
|
||||
visibility: 'hidden'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* update trigger function for this module
|
||||
* compare data and update module
|
||||
* @param moduleElement
|
||||
* @param systemData
|
||||
*/
|
||||
let updateModule = (moduleElement, systemData) => {
|
||||
let systemId = moduleElement.data('id');
|
||||
|
||||
if(systemId === systemData.id){
|
||||
// update system status -----------------------------------------------------------------------------------
|
||||
let systemStatusLabelElement = moduleElement.find('.' + config.systemInfoStatusLabelClass);
|
||||
let systemStatusId = parseInt( systemStatusLabelElement.attr( config.systemInfoStatusAttributeName ) );
|
||||
|
||||
if(systemStatusId !== systemData.status.id){
|
||||
// status changed
|
||||
let currentStatusClass = Util.getStatusInfoForSystem(systemStatusId, 'class');
|
||||
let newStatusClass = Util.getStatusInfoForSystem(systemData.status.id, 'class');
|
||||
let newStatusLabel = Util.getStatusInfoForSystem(systemData.status.id, 'label');
|
||||
systemStatusLabelElement.removeClass(currentStatusClass).addClass(newStatusClass).text(newStatusLabel);
|
||||
|
||||
// set new status attribute
|
||||
systemStatusLabelElement.attr( config.systemInfoStatusAttributeName, systemData.status.id);
|
||||
}
|
||||
|
||||
// update description textarea ----------------------------------------------------------------------------
|
||||
let descriptionTextareaElement = moduleElement.find('.' + config.descriptionTextareaElementClass);
|
||||
let description = descriptionTextareaElement.editable('getValue', true);
|
||||
|
||||
if(
|
||||
!disableModuleUpdate && // don´t update if field is active
|
||||
description !== systemData.description
|
||||
){
|
||||
// description changed
|
||||
let descriptionButton = moduleElement.find('.' + config.addDescriptionButtonClass);
|
||||
|
||||
// set new value
|
||||
descriptionTextareaElement.editable('setValue', systemData.description);
|
||||
|
||||
let actionElement = descriptionButton.siblings('.' + config.tableToolsActionClass);
|
||||
|
||||
if(systemData.description.length === 0){
|
||||
// show/activate description field
|
||||
// show button if value is empty
|
||||
descriptionButton.show();
|
||||
hideToolsActionElement(actionElement);
|
||||
}else{
|
||||
// hide/disable description field
|
||||
// hide tool button
|
||||
descriptionButton.hide();
|
||||
showToolsActionElement(actionElement);
|
||||
}
|
||||
}
|
||||
|
||||
// created/updated tooltip --------------------------------------------------------------------------------
|
||||
let nameRowElement = moduleElement.find('.' + config.systemInfoNameClass);
|
||||
|
||||
let tooltipData = {
|
||||
created: systemData.created,
|
||||
updated: systemData.updated
|
||||
};
|
||||
|
||||
nameRowElement.addCharacterInfoTooltip( tooltipData );
|
||||
}
|
||||
|
||||
moduleElement.find('.' + config.descriptionArea).hideLoadingAnimation();
|
||||
};
|
||||
|
||||
/**
|
||||
* get module element
|
||||
* @param parentElement
|
||||
* @param mapId
|
||||
* @param systemData
|
||||
*/
|
||||
let getModule = (parentElement, mapId, systemData) => {
|
||||
|
||||
// create new module container
|
||||
let moduleElement = $('<div>');
|
||||
|
||||
// store systemId -> module can be updated with the correct data
|
||||
moduleElement.data('id', systemData.id);
|
||||
|
||||
// system "static" wh data
|
||||
let staticsData = [];
|
||||
if(
|
||||
systemData.statics &&
|
||||
systemData.statics.length > 0
|
||||
){
|
||||
for(let wormholeName of systemData.statics){
|
||||
let wormholeData = Object.assign({}, Init.wormholes[wormholeName]);
|
||||
wormholeData.class = Util.getSecurityClassForSystem(wormholeData.security);
|
||||
staticsData.push(wormholeData);
|
||||
}
|
||||
}
|
||||
|
||||
let effectName = MapUtil.getEffectInfoForSystem(systemData.effect, 'name');
|
||||
let effectClass = MapUtil.getEffectInfoForSystem(systemData.effect, 'class');
|
||||
|
||||
// systemInfo template config
|
||||
let moduleConfig = {
|
||||
name: 'modules/system_info',
|
||||
position: moduleElement,
|
||||
link: 'append',
|
||||
functions: {
|
||||
after: function(conf){
|
||||
let tempModuleElement = conf.position;
|
||||
|
||||
// lock "description" field until first update
|
||||
tempModuleElement.find('.' + config.descriptionArea).showLoadingAnimation();
|
||||
|
||||
// "add description" button
|
||||
let descriptionButton = tempModuleElement.find('.' + config.addDescriptionButtonClass);
|
||||
|
||||
// description textarea element
|
||||
let descriptionTextareaElement = tempModuleElement.find('.' + config.descriptionTextareaElementClass);
|
||||
|
||||
// init description textarea
|
||||
descriptionTextareaElement.editable({
|
||||
url: Init.path.saveSystem,
|
||||
dataType: 'json',
|
||||
pk: systemData.id,
|
||||
type: 'textarea',
|
||||
mode: 'inline',
|
||||
emptytext: '',
|
||||
onblur: 'cancel',
|
||||
showbuttons: true,
|
||||
value: '', // value is set by trigger function updateModule()
|
||||
rows: 5,
|
||||
name: 'description',
|
||||
inputclass: config.descriptionTextareaElementClass,
|
||||
tpl: '<textarea maxlength="' + maxDescriptionLength + '"></textarea>',
|
||||
params: function(params){
|
||||
params.mapData = {
|
||||
id: mapId
|
||||
};
|
||||
|
||||
params.systemData = {};
|
||||
params.systemData.id = params.pk;
|
||||
params.systemData[params.name] = params.value;
|
||||
|
||||
// clear unnecessary data
|
||||
delete params.pk;
|
||||
delete params.name;
|
||||
delete params.value;
|
||||
|
||||
return params;
|
||||
},
|
||||
validate: function(value){
|
||||
if(value.length > 0 && $.trim(value).length === 0) {
|
||||
return {newValue: ''};
|
||||
}
|
||||
},
|
||||
success: function(response, newValue){
|
||||
Util.showNotify({title: 'System updated', text: 'Name: ' + response.name, type: 'success'});
|
||||
},
|
||||
error: function(jqXHR, newValue){
|
||||
let reason = '';
|
||||
let status = '';
|
||||
if(jqXHR.name){
|
||||
// save error new sig (mass save)
|
||||
reason = jqXHR.name;
|
||||
status = 'Error';
|
||||
}else{
|
||||
reason = jqXHR.responseJSON.text;
|
||||
status = jqXHR.status;
|
||||
}
|
||||
|
||||
Util.showNotify({title: status + ': save system information', text: reason, type: 'warning'});
|
||||
$(document).setProgramStatus('problem');
|
||||
return reason;
|
||||
}
|
||||
});
|
||||
|
||||
// on xEditable open ------------------------------------------------------------------------------
|
||||
descriptionTextareaElement.on('shown', function(e, editable){
|
||||
let textarea = editable.input.$input;
|
||||
|
||||
// disable module update until description field is open
|
||||
disableModuleUpdate = true;
|
||||
|
||||
// create character counter
|
||||
let charCounter = $('<kbd>', {
|
||||
class: [config.descriptionTextareaCharCounter, 'txt-color', 'text-right'].join(' ')
|
||||
});
|
||||
textarea.parent().next().append(charCounter);
|
||||
|
||||
// update character counter
|
||||
Util.updateCounter(textarea, charCounter, maxDescriptionLength);
|
||||
|
||||
textarea.on('keyup', function(){
|
||||
Util.updateCounter($(this), charCounter, maxDescriptionLength);
|
||||
});
|
||||
});
|
||||
|
||||
// on xEditable close -----------------------------------------------------------------------------
|
||||
descriptionTextareaElement.on('hidden', function(e){
|
||||
let value = $(this).editable('getValue', true);
|
||||
if(value.length === 0){
|
||||
// show button if value is empty
|
||||
hideToolsActionElement(descriptionButton.siblings('.' + config.tableToolsActionClass));
|
||||
descriptionButton.show();
|
||||
}
|
||||
|
||||
// enable module update
|
||||
disableModuleUpdate = false;
|
||||
});
|
||||
|
||||
// enable xEditable field on Button click ---------------------------------------------------------
|
||||
descriptionButton.on('click', function(e){
|
||||
e.stopPropagation();
|
||||
let descriptionButton = $(this);
|
||||
|
||||
// hide tool buttons
|
||||
descriptionButton.hide();
|
||||
|
||||
// show field *before* showing the element
|
||||
descriptionTextareaElement.editable('show');
|
||||
|
||||
showToolsActionElement(descriptionButton.siblings('.' + config.tableToolsActionClass));
|
||||
});
|
||||
|
||||
// init tooltips ----------------------------------------------------------------------------------
|
||||
let tooltipElements = tempModuleElement.find('[data-toggle="tooltip"]');
|
||||
tooltipElements.tooltip();
|
||||
|
||||
// init system effect popover ---------------------------------------------------------------------
|
||||
$(moduleElement).find('.' + config.systemInfoEffectClass).addSystemEffectTooltip(systemData.security, systemData.effect);
|
||||
|
||||
// init planets popover ---------------------------------------------------------------------------
|
||||
$(moduleElement).find('.' + config.systemInfoPlanetsClass).addSystemPlanetsTooltip(systemData.planets);
|
||||
|
||||
// init static wormhole information ---------------------------------------------------------------
|
||||
for(let staticData of staticsData){
|
||||
let staticRowElement = tempModuleElement.find('.' + config.systemInfoWormholeClass + staticData.name);
|
||||
staticRowElement.addWormholeInfoTooltip(staticData);
|
||||
}
|
||||
|
||||
// constellation popover --------------------------------------------------------------------------
|
||||
tempModuleElement.find('a.popup-ajax').popover({
|
||||
html: true,
|
||||
trigger: 'hover',
|
||||
placement: 'top',
|
||||
delay: 200,
|
||||
container: 'body',
|
||||
content: function(){
|
||||
return details_in_popup(this);
|
||||
}
|
||||
});
|
||||
|
||||
function details_in_popup(popoverElement){
|
||||
popoverElement = $(popoverElement);
|
||||
let popover = popoverElement.data('bs.popover');
|
||||
|
||||
$.ajax({
|
||||
url: popoverElement.data('url'),
|
||||
success: function(data){
|
||||
let systemEffectTable = Util.getSystemsInfoTable( data.systemsData );
|
||||
popover.options.content = systemEffectTable;
|
||||
// reopen popover (new content size)
|
||||
popover.show();
|
||||
}
|
||||
});
|
||||
return 'Loading...';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let moduleData = {
|
||||
system: systemData,
|
||||
static: staticsData,
|
||||
tableClass: config.systemInfoTableClass,
|
||||
nameInfoClass: config.systemInfoNameClass,
|
||||
effectInfoClass: config.systemInfoEffectClass,
|
||||
planetsInfoClass: config.systemInfoPlanetsClass,
|
||||
wormholePrefixClass: config.systemInfoWormholeClass,
|
||||
statusInfoClass: config.systemInfoStatusLabelClass,
|
||||
|
||||
systemTypeName: MapUtil.getSystemTypeInfo(systemData.type.id, 'name'),
|
||||
systemIsWormhole: MapUtil.getSystemTypeInfo(systemData.type.id, 'name') === 'w-space',
|
||||
systemStatusId: systemData.status.id,
|
||||
systemStatusClass: Util.getStatusInfoForSystem(systemData.status.id, 'class'),
|
||||
systemStatusLabel: Util.getStatusInfoForSystem(systemData.status.id, 'label'),
|
||||
securityClass: Util.getSecurityClassForSystem( systemData.security ),
|
||||
trueSec: systemData.trueSec.toFixed(1),
|
||||
trueSecClass: Util.getTrueSecClassForSystem( systemData.trueSec ),
|
||||
effectName: effectName,
|
||||
effectClass: effectClass,
|
||||
moduleToolbarClass: config.moduleElementToolbarClass,
|
||||
descriptionButtonClass: config.addDescriptionButtonClass,
|
||||
tableToolsActionClass: config.tableToolsActionClass,
|
||||
descriptionTextareaClass: config.descriptionTextareaElementClass,
|
||||
systemNameClass: () => {
|
||||
return (val, render) => {
|
||||
return render(val) === 'A' ? config.fontTriglivianClass : '';
|
||||
};
|
||||
},
|
||||
formatUrl: () => {
|
||||
return (val, render) => render(val).replace(/ /g, '_');
|
||||
},
|
||||
planetCount: systemData.planets ? systemData.planets.length : 0,
|
||||
|
||||
shatteredClass: Util.getSecurityClassForSystem('SH'),
|
||||
|
||||
ajaxConstellationInfoUrl: Init.path.getConstellationData,
|
||||
|
||||
systemConstellationLinkClass: config.constellationLinkClass,
|
||||
systemRegionLinkClass: config.regionLinkClass,
|
||||
systemTypeLinkClass: config.typeLinkClass
|
||||
|
||||
};
|
||||
|
||||
Render.showModule(moduleConfig, moduleData);
|
||||
|
||||
return moduleElement;
|
||||
};
|
||||
|
||||
/**
|
||||
* efore module destroy callback
|
||||
* @param moduleElement
|
||||
*/
|
||||
let beforeDestroy = (moduleElement) => {
|
||||
// remove xEditable description textarea
|
||||
let descriptionTextareaElement = moduleElement.find('.' + config.descriptionTextareaElementClass);
|
||||
descriptionTextareaElement.editable('destroy');
|
||||
};
|
||||
|
||||
return {
|
||||
config: config,
|
||||
getModule: getModule,
|
||||
updateModule: updateModule,
|
||||
beforeDestroy: beforeDestroy
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -1,827 +0,0 @@
|
||||
/**
|
||||
* system route module
|
||||
*/
|
||||
|
||||
define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util',
|
||||
'bootbox'
|
||||
], ($, Init, Util, bootbox) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
// module info
|
||||
modulePosition: 1,
|
||||
moduleName: 'systemIntel',
|
||||
moduleHeadClass: 'pf-module-head', // class for module header
|
||||
moduleHandlerClass: 'pf-module-handler-drag', // class for "drag" handler
|
||||
moduleTypeClass: 'pf-system-intel-module', // class for this module
|
||||
|
||||
// headline toolbar
|
||||
moduleHeadlineIconClass: 'pf-module-icon-button', // class for toolbar icons in the head
|
||||
moduleHeadlineIconAddClass: 'pf-module-icon-button-add', // class for "add structure" icon
|
||||
moduleHeadlineIconReaderClass: 'pf-module-icon-button-reader', // class for "dScan reader" icon
|
||||
moduleHeadlineIconRefreshClass: 'pf-module-icon-button-refresh', // class for "refresh" icon
|
||||
|
||||
// system intel module
|
||||
systemStructuresTableClass: 'pf-system-structure-table', // class for route tables
|
||||
|
||||
// structure dialog
|
||||
structureDialogId: 'pf-structure-dialog', // id for "structure" dialog
|
||||
statusSelectId: 'pf-structure-dialog-status-select', // id for "status" select
|
||||
typeSelectId: 'pf-structure-dialog-type-select', // id for "type" select
|
||||
corporationSelectId: 'pf-structure-dialog-corporation-select', // id for "corporation" select
|
||||
descriptionTextareaId: 'pf-structure-dialog-description-textarea', // id for "description" textarea
|
||||
descriptionTextareaCharCounter: 'pf-form-field-char-count', // class for "character counter" element for form field
|
||||
|
||||
// dataTable
|
||||
tableRowIdPrefix: 'pf-structure-row_', // id prefix for table rows
|
||||
tableCellImageClass: 'pf-table-image-smaller-cell', // class for table "image" cells
|
||||
tableCellCounterClass: 'pf-table-counter-cell', // class for table "counter" cells
|
||||
tableCellEllipsisClass: 'pf-table-cell-ellipses-auto', // class for table "ellipsis" cells
|
||||
dataTableActionCellClass: 'pf-table-action-cell' // class for "action" cells
|
||||
};
|
||||
|
||||
let maxDescriptionLength = 512;
|
||||
|
||||
/**
|
||||
* get status icon for structure
|
||||
* @param statusData
|
||||
* @returns {string}
|
||||
*/
|
||||
let getStatusData = (statusData) => {
|
||||
return '<i class="fas fa-fw fa-circle ' + statusData.class + '" title="' + statusData.label + '"></i>';
|
||||
};
|
||||
|
||||
/**
|
||||
* get <tr> DOM id by id
|
||||
* @param tableApi
|
||||
* @param id
|
||||
* @returns {*}
|
||||
*/
|
||||
let getRowId = (tableApi, id) => {
|
||||
return tableApi.rows().ids().toArray().find(rowId => rowId === config.tableRowIdPrefix + id);
|
||||
};
|
||||
|
||||
/**
|
||||
* callback -> add structure rows from responseData
|
||||
* @param context
|
||||
* @param responseData
|
||||
*/
|
||||
let callbackAddStructureRows = (context, responseData) => {
|
||||
let systemData = Util.getObjVal(responseData, 'system');
|
||||
callbackUpdateStructureRows(context, systemData);
|
||||
};
|
||||
|
||||
/**
|
||||
* callback -> add structure rows from systemData
|
||||
* @param context
|
||||
* @param systemData
|
||||
*/
|
||||
let callbackUpdateStructureRows = (context, systemData) => {
|
||||
let touchedRows = [];
|
||||
let hadData = context.tableApi.rows().any();
|
||||
let notificationCounter = {
|
||||
added: 0,
|
||||
changed: 0,
|
||||
deleted: 0
|
||||
};
|
||||
|
||||
if(systemData){
|
||||
let corporations = Util.getObjVal(systemData, 'structures');
|
||||
if(corporations) {
|
||||
for (let [corporationId, corporationData] of Object.entries(corporations)){
|
||||
if(corporationData.structures && corporationData.structures.length){
|
||||
for(let structureData of corporationData.structures){
|
||||
let rowId = getRowId(context.tableApi, structureData.id);
|
||||
|
||||
// add corporation data
|
||||
structureData.corporation = {
|
||||
id: corporationData.id,
|
||||
name: corporationData.name
|
||||
};
|
||||
|
||||
if(rowId){
|
||||
// update row
|
||||
let api = context.tableApi.row('#' + rowId);
|
||||
let rowData = api.data();
|
||||
|
||||
// check for update
|
||||
if(rowData.updated.updated !== structureData.updated.updated){
|
||||
// row data changed -> update
|
||||
api.data(structureData);
|
||||
api.nodes().to$().data('animationStatus', 'changed').destroyTimestampCounter();
|
||||
notificationCounter.changed++;
|
||||
}
|
||||
|
||||
touchedRows.push(api.id());
|
||||
}else{
|
||||
// insert new row
|
||||
let api = context.tableApi.row.add(structureData);
|
||||
api.nodes().to$().data('animationStatus', 'added');
|
||||
notificationCounter.added++;
|
||||
|
||||
touchedRows.push(api.id());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(context.removeMissing){
|
||||
let api = context.tableApi.rows((idx, data, node) => !touchedRows.includes(node.id));
|
||||
notificationCounter.deleted += api.ids().count();
|
||||
api.remove();
|
||||
}
|
||||
|
||||
context.tableApi.draw();
|
||||
|
||||
// show notification ------------------------------------------------------------------------------------------
|
||||
let notification = '';
|
||||
notification += notificationCounter.added > 0 ? notificationCounter.added + ' added<br>' : '';
|
||||
notification += notificationCounter.changed > 0 ? notificationCounter.changed + ' changed<br>' : '';
|
||||
notification += notificationCounter.deleted > 0 ? notificationCounter.deleted + ' deleted<br>' : '';
|
||||
|
||||
if(hadData && notification.length){
|
||||
Util.showNotify({title: 'Structures updated', text: notification, type: 'success'});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* callback -> delete structure rows
|
||||
* @param context
|
||||
* @param responseData
|
||||
*/
|
||||
let callbackDeleteStructures = (context, responseData) => {
|
||||
let structureIds = Util.getObjVal(responseData, 'deletedStructureIds');
|
||||
let deletedCounter = 0;
|
||||
if(structureIds && structureIds.length){
|
||||
for(let structureId of structureIds){
|
||||
let rowId = getRowId(context.tableApi, structureId);
|
||||
if(rowId){
|
||||
context.tableApi.row('#' + rowId).remove();
|
||||
deletedCounter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(deletedCounter){
|
||||
context.tableApi.draw();
|
||||
Util.showNotify({title: 'Structure deleted', text: deletedCounter + ' deleted', type: 'success'});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* send ajax request
|
||||
* @param url
|
||||
* @param requestData
|
||||
* @param context
|
||||
* @param callback
|
||||
*/
|
||||
let sendRequest = (url, requestData, context, callback) => {
|
||||
context.moduleElement.showLoadingAnimation();
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: requestData,
|
||||
context: context
|
||||
}).done(function(data){
|
||||
callback(this, data);
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
let reason = status + ' ' + error;
|
||||
Util.showNotify({title: jqXHR.status + ': System intel data', text: reason, type: 'warning'});
|
||||
$(document).setProgramStatus('problem');
|
||||
}).always(function(){
|
||||
// hide loading animation
|
||||
this.moduleElement.hideLoadingAnimation();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* requests system data
|
||||
* @param requestData
|
||||
* @param context
|
||||
* @param callback
|
||||
*/
|
||||
let getStructureData = (requestData, context, callback) => {
|
||||
sendRequest(Init.path.getSystemData, requestData, context, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* save structure data
|
||||
* @param requestData
|
||||
* @param context
|
||||
* @param callback
|
||||
*/
|
||||
let saveStructureData = (requestData, context, callback) => {
|
||||
sendRequest(Init.path.saveStructureData, requestData, context, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* delete structure
|
||||
* @param requestData
|
||||
* @param context
|
||||
* @param callback
|
||||
*/
|
||||
let deleteStructure = (requestData, context, callback) => {
|
||||
sendRequest(Init.path.deleteStructureData, requestData, context, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* show structure dialog
|
||||
* @param moduleElement
|
||||
* @param tableApi
|
||||
* @param systemId
|
||||
* @param structureData
|
||||
*/
|
||||
let showStructureDialog = (moduleElement, tableApi, systemId, structureData) => {
|
||||
let structureStatusData = Util.getObjVal(Init, 'structureStatus');
|
||||
let structureTypeData = Util.getObjVal(Init, 'structureStatus');
|
||||
|
||||
let statusData = Object.keys(structureStatusData).map((k) => {
|
||||
let data = structureStatusData[k];
|
||||
data.selected = data.id === Util.getObjVal(structureData, 'status.id');
|
||||
return data;
|
||||
});
|
||||
|
||||
let data = {
|
||||
id: config.structureDialogId,
|
||||
structureData: structureData,
|
||||
structureStatus: statusData,
|
||||
statusSelectId: config.statusSelectId,
|
||||
typeSelectId: config.typeSelectId,
|
||||
corporationSelectId: config.corporationSelectId,
|
||||
descriptionTextareaId: config.descriptionTextareaId,
|
||||
descriptionTextareaCharCounter: config.descriptionTextareaCharCounter,
|
||||
maxDescriptionLength: maxDescriptionLength
|
||||
};
|
||||
|
||||
requirejs(['text!templates/dialog/structure.html', 'mustache'], (template, Mustache) => {
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
let structureDialog = bootbox.dialog({
|
||||
title: 'Structure',
|
||||
message: content,
|
||||
show: false,
|
||||
buttons: {
|
||||
close: {
|
||||
label: 'cancel',
|
||||
className: 'btn-default'
|
||||
},
|
||||
success: {
|
||||
label: '<i class="fas fa-fw fa-check"></i> save',
|
||||
className: 'btn-success',
|
||||
callback: function (){
|
||||
let form = this.find('form');
|
||||
|
||||
// validate form
|
||||
form.validator('validate');
|
||||
|
||||
// check whether the form is valid
|
||||
let formValid = form.isValidForm();
|
||||
|
||||
if(formValid){
|
||||
// get form data
|
||||
let formData = form.getFormValues();
|
||||
formData.id = Util.getObjVal(structureData, 'id') | 0;
|
||||
formData.structureId = Util.getObjVal(formData, 'structureId') | 0;
|
||||
formData.corporationId = Util.getObjVal(formData, 'corporationId') | 0;
|
||||
formData.systemId = systemId | 0;
|
||||
|
||||
saveStructureData({
|
||||
structures: [formData]
|
||||
}, {
|
||||
moduleElement: moduleElement,
|
||||
tableApi: tableApi
|
||||
}, callbackUpdateStructureRows);
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
structureDialog.on('show.bs.modal', function(e) {
|
||||
let modalContent = $('#' + config.structureDialogId);
|
||||
|
||||
// init type select live search
|
||||
let selectElementType = modalContent.find('#' + config.typeSelectId);
|
||||
selectElementType.initUniverseTypeSelect({
|
||||
categoryIds: [65],
|
||||
maxSelectionLength: 1,
|
||||
selected: [Util.getObjVal(structureData, 'structure.id')]
|
||||
});
|
||||
|
||||
// init corporation select live search
|
||||
let selectElementCorporation = modalContent.find('#' + config.corporationSelectId);
|
||||
selectElementCorporation.initUniverseSearch({
|
||||
categoryNames: ['corporation'],
|
||||
maxSelectionLength: 1
|
||||
});
|
||||
|
||||
// init status select2
|
||||
modalContent.find('#' + config.statusSelectId).initStatusSelect({
|
||||
data: statusData
|
||||
});
|
||||
|
||||
// init character counter
|
||||
let textarea = modalContent.find('#' + config.descriptionTextareaId);
|
||||
let charCounter = modalContent.find('.' + config.descriptionTextareaCharCounter);
|
||||
Util.updateCounter(textarea, charCounter, maxDescriptionLength);
|
||||
|
||||
textarea.on('keyup', function(){
|
||||
Util.updateCounter($(this), charCounter, maxDescriptionLength);
|
||||
});
|
||||
|
||||
// set form validator (after select2 init finish)
|
||||
modalContent.find('form').initFormValidation();
|
||||
});
|
||||
|
||||
// show dialog
|
||||
structureDialog.modal('show');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* show D-Scan reader dialog
|
||||
* @param moduleElement
|
||||
* @param tableApi
|
||||
* @param systemData
|
||||
*/
|
||||
let showDscanReaderDialog = (moduleElement, tableApi, systemData) => {
|
||||
requirejs(['text!templates/dialog/dscan_reader.html', 'mustache'], (template, Mustache) => {
|
||||
let structureDialog = bootbox.dialog({
|
||||
title: 'D-Scan reader',
|
||||
message: Mustache.render(template, {}),
|
||||
show: true,
|
||||
buttons: {
|
||||
close: {
|
||||
label: 'cancel',
|
||||
className: 'btn-default'
|
||||
},
|
||||
success: {
|
||||
label: '<i class="fas fa-fw fa-paste fa-fw"></i> update intel',
|
||||
className: 'btn-success',
|
||||
callback: function (){
|
||||
let form = this.find('form');
|
||||
let formData = form.getFormValues();
|
||||
|
||||
updateStructureTableByClipboard(systemData, formData.clipboard, {
|
||||
moduleElement: moduleElement,
|
||||
tableApi: tableApi
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// dialog shown event
|
||||
structureDialog.on('shown.bs.modal', function(e) {
|
||||
// set focus on textarea
|
||||
structureDialog.find('textarea').focus();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* get module element
|
||||
* @param parentElement
|
||||
* @param mapId
|
||||
* @param systemData
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
let getModule = (parentElement, mapId, systemData) => {
|
||||
let corporationId = Util.getCurrentUserInfo('corporationId');
|
||||
|
||||
// create new module container
|
||||
let moduleElement = $('<div>').append(
|
||||
$('<div>', {
|
||||
class: config.moduleHeadClass
|
||||
}).append(
|
||||
$('<h5>', {
|
||||
class: config.moduleHandlerClass
|
||||
}),
|
||||
$('<h5>', {
|
||||
class: 'pull-right'
|
||||
}).append(
|
||||
$('<i>', {
|
||||
class: ['fas', 'fa-fw', 'fa-plus', config.moduleHeadlineIconClass, config.moduleHeadlineIconAddClass].join(' '),
|
||||
title: 'add'
|
||||
}).attr('data-html', 'true').attr('data-toggle', 'tooltip'),
|
||||
$('<i>', {
|
||||
class: ['fas', 'fa-fw', 'fa-paste', config.moduleHeadlineIconClass, config.moduleHeadlineIconReaderClass].join(' '),
|
||||
title: 'D-Scan reader'
|
||||
}).attr('data-html', 'true').attr('data-toggle', 'tooltip'),
|
||||
$('<i>', {
|
||||
class: ['fas', 'fa-fw', 'fa-sync', config.moduleHeadlineIconClass, config.moduleHeadlineIconRefreshClass].join(' '),
|
||||
title: 'refresh all'
|
||||
}).attr('data-html', 'true').attr('data-toggle', 'tooltip')
|
||||
),
|
||||
$('<h5>', {
|
||||
text: 'Intel'
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
let table = $('<table>', {
|
||||
class: ['compact', 'stripe', 'order-column', 'row-border', 'pf-table-fixed', config.systemStructuresTableClass].join(' ')
|
||||
});
|
||||
moduleElement.append(table);
|
||||
|
||||
let structureTable = table.DataTable({
|
||||
paging: false,
|
||||
lengthChange: false,
|
||||
ordering: true,
|
||||
order: [[ 10, 'desc' ], [ 0, 'asc' ]],
|
||||
info: false,
|
||||
searching: false,
|
||||
hover: false,
|
||||
autoWidth: false,
|
||||
rowId: rowData => config.tableRowIdPrefix + rowData.id,
|
||||
language: {
|
||||
emptyTable: 'No structures recorded',
|
||||
info: '_START_ to _END_ of _MAX_',
|
||||
infoEmpty: ''
|
||||
},
|
||||
rowGroup: {
|
||||
enable: true,
|
||||
dataSrc: 'systemId'
|
||||
},
|
||||
columnDefs: [
|
||||
{
|
||||
targets: 0,
|
||||
title: '',
|
||||
width: 2,
|
||||
class: 'text-center',
|
||||
data: 'status',
|
||||
render: {
|
||||
display: data => getStatusData(data),
|
||||
sort: data => data.id
|
||||
},
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
$(cell).find('i').tooltip();
|
||||
}
|
||||
},{
|
||||
targets: 1,
|
||||
title: '',
|
||||
width: 26,
|
||||
orderable: false,
|
||||
className: [config.tableCellImageClass, 'text-center'].join(' '),
|
||||
data: 'structure.id',
|
||||
defaultContent: '<i class="fas fa-question txt-color txt-color-orangeDark"></i>',
|
||||
render: {
|
||||
_: function(data, type, row, meta){
|
||||
let value = data;
|
||||
if(type === 'display' && value){
|
||||
value = '<img src="' + Init.url.ccpImageServer + '/Type/' + value + '_32.png" />';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
},{
|
||||
targets: 2,
|
||||
title: 'type',
|
||||
width: 30,
|
||||
className: [config.tableCellEllipsisClass].join(' '),
|
||||
data: 'structure.name',
|
||||
defaultContent: '<i class="fas fa-question txt-color txt-color-orangeDark"></i>',
|
||||
},{
|
||||
targets: 3,
|
||||
title: 'name',
|
||||
width: 60,
|
||||
className: [config.tableCellEllipsisClass].join(' '),
|
||||
data: 'name'
|
||||
},{
|
||||
targets: 4,
|
||||
title: '',
|
||||
width: 26,
|
||||
orderable: false,
|
||||
className: [config.tableCellImageClass, 'text-center'].join(' '),
|
||||
data: 'owner.id',
|
||||
defaultContent: '<i class="fas fa-question txt-color txt-color-orangeDark"></i>',
|
||||
render: {
|
||||
_: function(data, type, row, meta){
|
||||
let value = data;
|
||||
if(type === 'display' && value){
|
||||
value = '<a href="https://zkillboard.com/corporation/' + data + '/" target="_blank" rel="noopener">';
|
||||
value += '<img src="' + Init.url.ccpImageServer + '/Corporation/' + data + '_32.png" />';
|
||||
value += '</a>';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
},{
|
||||
targets: 5,
|
||||
title: 'owner',
|
||||
width: 50,
|
||||
className: [config.tableCellEllipsisClass].join(' '),
|
||||
data: 'owner.name',
|
||||
defaultContent: '<i class="fas fa-question txt-color txt-color-orangeDark"></i>',
|
||||
},{
|
||||
targets: 6,
|
||||
title: 'note',
|
||||
className: [config.tableCellEllipsisClass].join(' '),
|
||||
data: 'description'
|
||||
},{
|
||||
targets: 7,
|
||||
title: 'updated',
|
||||
width: 60,
|
||||
className: ['text-right', config.tableCellCounterClass].join(' '),
|
||||
data: 'updated.updated'
|
||||
},{
|
||||
targets: 8,
|
||||
title: '',
|
||||
orderable: false,
|
||||
width: 10,
|
||||
class: ['text-center', config.dataTableActionCellClass, config.moduleHeadlineIconClass].join(' '),
|
||||
data: null,
|
||||
render: {
|
||||
display: data => {
|
||||
let icon = '<i class="fas fa-pencil-alt"></i>';
|
||||
if(data.corporation.id !== corporationId){
|
||||
icon = '';
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
},
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
let tableApi = this.api();
|
||||
|
||||
if($(cell).is(':empty')){
|
||||
$(cell).removeClass(config.dataTableActionCellClass + ' ' + config.moduleHeadlineIconClass);
|
||||
}else{
|
||||
$(cell).on('click', function(e) {
|
||||
// get current row data (important!)
|
||||
// -> "rowData" param is not current state, values are "on createCell()" state
|
||||
rowData = tableApi.row( $(cell).parents('tr')).data();
|
||||
showStructureDialog(moduleElement, tableApi, systemData.systemId, rowData);
|
||||
});
|
||||
}
|
||||
}
|
||||
},{
|
||||
targets: 9,
|
||||
title: '',
|
||||
orderable: false,
|
||||
width: 10,
|
||||
class: ['text-center', config.dataTableActionCellClass].join(' '),
|
||||
data: null,
|
||||
render: {
|
||||
display: data => {
|
||||
let icon = '<i class="fas fa-times txt-color txt-color-redDarker"></i>';
|
||||
if(data.corporation.id !== corporationId){
|
||||
icon = '<i class="fas fa-ban txt-color txt-color-grayLight" title="restricted" data-placement="left"></i>';
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
},
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
let tableApi = this.api();
|
||||
|
||||
if($(cell).find('.fa-ban').length){
|
||||
$(cell).removeClass(config.dataTableActionCellClass + ' ' + config.moduleHeadlineIconClass);
|
||||
$(cell).find('i').tooltip();
|
||||
}else{
|
||||
let confirmationSettings = {
|
||||
container: 'body',
|
||||
placement: 'left',
|
||||
btnCancelClass: 'btn btn-sm btn-default',
|
||||
btnCancelLabel: 'cancel',
|
||||
btnCancelIcon: 'fas fa-fw fa-ban',
|
||||
title: 'delete structure',
|
||||
btnOkClass: 'btn btn-sm btn-danger',
|
||||
btnOkLabel: 'delete',
|
||||
btnOkIcon: 'fas fa-fw fa-times',
|
||||
onConfirm : function(e, target){
|
||||
// get current row data (important!)
|
||||
// -> "rowData" param is not current state, values are "on createCell()" state
|
||||
rowData = tableApi.row( $(cell).parents('tr')).data();
|
||||
|
||||
// let deleteRowElement = $(cell).parents('tr');
|
||||
// tableApi.rows(deleteRowElement).remove().draw();
|
||||
deleteStructure({
|
||||
id: rowData.id
|
||||
},{
|
||||
moduleElement: moduleElement,
|
||||
tableApi: tableApi
|
||||
}, callbackDeleteStructures);
|
||||
}
|
||||
};
|
||||
|
||||
// init confirmation dialog
|
||||
$(cell).confirmation(confirmationSettings);
|
||||
}
|
||||
}
|
||||
},{
|
||||
targets: 10,
|
||||
name: 'corporation',
|
||||
data: 'corporation',
|
||||
visible: false,
|
||||
render: {
|
||||
sort: function(data){
|
||||
return data.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
drawCallback: function (settings){
|
||||
let tableApi = this.api();
|
||||
let columnCount = tableApi.columns(':visible').count();
|
||||
let rows = tableApi.rows( {page:'current'} ).nodes();
|
||||
let last= null;
|
||||
|
||||
tableApi.column('corporation:name', {page:'current'} ).data().each( function ( group, i ) {
|
||||
if ( !last || last.id !== group.id ) {
|
||||
$(rows).eq(i).before(
|
||||
'<tr class="group">' +
|
||||
'<td></td>' +
|
||||
'<td class="' + config.tableCellImageClass + '">' +
|
||||
'<img src="' + Init.url.ccpImageServer + '/Corporation/' + group.id + '_32.png" />' +
|
||||
'</td>' +
|
||||
'<td colspan="' + (columnCount - 2 ) + '">' + group.name + '</td>' +
|
||||
'</tr>'
|
||||
);
|
||||
last = group;
|
||||
}
|
||||
});
|
||||
|
||||
rows.to$().find('.' + config.tableCellCounterClass + ':not([data-counter])').initTimestampCounter('d');
|
||||
|
||||
let animationRows = rows.to$().filter(function() {
|
||||
return (
|
||||
$(this).data('animationStatus') ||
|
||||
$(this).data('animationTimer')
|
||||
);
|
||||
});
|
||||
|
||||
for(let i = 0; i < animationRows.length; i++){
|
||||
let animationRow = $(animationRows[i]);
|
||||
animationRow.pulseTableRow(animationRow.data('animationStatus'));
|
||||
animationRow.removeData('animationStatus');
|
||||
}
|
||||
},
|
||||
initComplete: function(settings){
|
||||
// table data is load in updateModule() method
|
||||
// -> no need to trigger additional ajax call here for data
|
||||
// -> in case table update failed -> each if this initComplete() function finished before table updata
|
||||
// e.g. return now promise in getModule() function
|
||||
}
|
||||
});
|
||||
|
||||
// init tooltips for this module
|
||||
let tooltipElements = moduleElement.find('[data-toggle="tooltip"]');
|
||||
tooltipElements.tooltip({
|
||||
container: 'body'
|
||||
});
|
||||
|
||||
moduleElement.showLoadingAnimation();
|
||||
|
||||
return moduleElement;
|
||||
};
|
||||
|
||||
/**
|
||||
* get universe typeIds for given categoryIds
|
||||
* @param categoryIds
|
||||
* @returns {Array}
|
||||
*/
|
||||
let getUniverseTypeIdsByCategoryIds = (categoryIds) => {
|
||||
let typeIds = [];
|
||||
let mapIds = type => type.id;
|
||||
for(let categoryId of categoryIds){
|
||||
let categoryData = Util.getObjVal(Init, 'universeCategories.' + categoryId);
|
||||
if(categoryData && categoryData.groups){
|
||||
for(let groupData of categoryData.groups){
|
||||
if(groupData && groupData.types){
|
||||
typeIds = typeIds.concat(groupData.types.map(mapIds));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return typeIds;
|
||||
};
|
||||
|
||||
/**
|
||||
* parse a copy&paste string from ingame dScan windows
|
||||
* @param systemData
|
||||
* @param clipboard
|
||||
* @returns {Array}
|
||||
*/
|
||||
let parseDscanString = (systemData, clipboard) => {
|
||||
let dScanData = [];
|
||||
let structureTypeIds = getUniverseTypeIdsByCategoryIds([65]);
|
||||
|
||||
if(clipboard.length){
|
||||
let dScanRows = clipboard.split(/\r\n|\r|\n/g);
|
||||
|
||||
for(let rowData of dScanRows){
|
||||
rowData = rowData.split(/\t/g);
|
||||
|
||||
if(rowData.length === 4){
|
||||
rowData[0] = parseInt(rowData[0]);
|
||||
// valid dScan result
|
||||
if(structureTypeIds.indexOf( rowData[0] ) !== -1){
|
||||
dScanData.push({
|
||||
structureId: rowData[0],
|
||||
name: rowData[1],
|
||||
systemId: systemData.systemId
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dScanData;
|
||||
};
|
||||
|
||||
/**
|
||||
* parse clipboard data for structures and update table
|
||||
* @param systemData
|
||||
* @param clipboard
|
||||
* @param context
|
||||
*/
|
||||
let updateStructureTableByClipboard = (systemData, clipboard, context) => {
|
||||
let structureData = parseDscanString(systemData, clipboard);
|
||||
if(structureData.length){
|
||||
saveStructureData({
|
||||
structures: structureData
|
||||
}, context, callbackUpdateStructureRows);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* update trigger function for this module
|
||||
* compare data and update module
|
||||
* @param moduleElement
|
||||
* @param systemData
|
||||
*/
|
||||
let updateModule = (moduleElement, systemData) => {
|
||||
|
||||
// update structure table data
|
||||
let structureTableElement = moduleElement.find('.' + config.systemStructuresTableClass);
|
||||
let tableApi = structureTableElement.DataTable();
|
||||
|
||||
let context = {
|
||||
tableApi: tableApi,
|
||||
removeMissing: true
|
||||
};
|
||||
|
||||
callbackUpdateStructureRows(context, systemData);
|
||||
|
||||
moduleElement.hideLoadingAnimation();
|
||||
};
|
||||
|
||||
/**
|
||||
* init intel module
|
||||
* @param moduleElement
|
||||
* @param mapId
|
||||
* @param systemData
|
||||
*/
|
||||
let initModule = (moduleElement, mapId, systemData) => {
|
||||
|
||||
let structureTableElement = moduleElement.find('.' + config.systemStructuresTableClass);
|
||||
let tableApi = structureTableElement.DataTable();
|
||||
|
||||
// init structure dialog --------------------------------------------------------------------------------------
|
||||
moduleElement.find('.' + config.moduleHeadlineIconAddClass).on('click', function(e){
|
||||
showStructureDialog(moduleElement, tableApi, systemData.systemId);
|
||||
});
|
||||
|
||||
// init structure dialog --------------------------------------------------------------------------------------
|
||||
moduleElement.find('.' + config.moduleHeadlineIconReaderClass).on('click', function(e){
|
||||
showDscanReaderDialog(moduleElement, tableApi, systemData);
|
||||
});
|
||||
|
||||
// init refresh button ----------------------------------------------------------------------------------------
|
||||
moduleElement.find('.' + config.moduleHeadlineIconRefreshClass).on('click', function(e){
|
||||
getStructureData({
|
||||
mapId: mapId,
|
||||
systemId: systemData.id
|
||||
},{
|
||||
moduleElement: moduleElement,
|
||||
tableApi: tableApi,
|
||||
removeMissing: true
|
||||
}, callbackAddStructureRows);
|
||||
});
|
||||
|
||||
// init listener for global "past" dScan into this page -------------------------------------------------------
|
||||
moduleElement.on('pf:updateIntelModuleByClipboard', function(e, clipboard){
|
||||
updateStructureTableByClipboard(systemData, clipboard, {
|
||||
moduleElement: moduleElement,
|
||||
tableApi: tableApi
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
config: config,
|
||||
getModule: getModule,
|
||||
initModule: initModule,
|
||||
updateModule: updateModule
|
||||
};
|
||||
|
||||
});
|
||||
@@ -1,404 +0,0 @@
|
||||
define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util',
|
||||
'morris'
|
||||
], ($, Init, Util, Morris) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
// module info
|
||||
modulePosition: 2,
|
||||
moduleName: 'systemKillboard',
|
||||
moduleHeadClass: 'pf-module-head', // class for module header
|
||||
moduleHandlerClass: 'pf-module-handler-drag', // class for "drag" handler
|
||||
|
||||
// headline toolbar
|
||||
moduleHeadlineIconClass: 'pf-module-icon-button', // class for toolbar icons in the head
|
||||
|
||||
// system killboard module
|
||||
moduleTypeClass: 'pf-system-killboard-module', // class for this module
|
||||
systemKillboardGraphKillsClass: 'pf-system-killboard-graph-kills', // class for system kill graph
|
||||
|
||||
// system killboard list
|
||||
systemKillboardListClass: 'pf-system-killboard-list', // class for a list with kill entries
|
||||
systemKillboardListEntryClass: 'pf-system-killboard-list-entry', // class for a list entry
|
||||
systemKillboardListImgShip: 'pf-system-killboard-img-ship', // class for all ship images
|
||||
systemKillboardListImgChar: 'pf-system-killboard-img-char', // class for all character logos
|
||||
systemKillboardListImgAlly: 'pf-system-killboard-img-ally', // class for all alliance logos
|
||||
systemKillboardListImgCorp: 'pf-system-killboard-img-corp' // class for all corp logos
|
||||
};
|
||||
|
||||
let cache = {
|
||||
systemKillsGraphData: {} // data for system kills info graph
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param text
|
||||
* @param options
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
let getLabel = (text, options) => {
|
||||
let label = $('<span>', {
|
||||
class: ['label', options.type, options.align].join(' ')
|
||||
}).text( text );
|
||||
|
||||
return label;
|
||||
};
|
||||
|
||||
/**
|
||||
* show killMails
|
||||
* @param moduleElement
|
||||
* @param killboardData
|
||||
*/
|
||||
let showKillmails = (moduleElement, killboardData) => {
|
||||
|
||||
// show number of killMails
|
||||
let killMailCounterMax = 20;
|
||||
let killMailCounter = 0;
|
||||
|
||||
// change order (show right to left)
|
||||
killboardData.tableData.reverse();
|
||||
|
||||
let data = {
|
||||
tableData: killboardData.tableData,
|
||||
systemKillboardListClass: config.systemKillboardListClass,
|
||||
systemKillboardListEntryClass: config.systemKillboardListEntryClass,
|
||||
systemKillboardListImgShip: config.systemKillboardListImgShip,
|
||||
systemKillboardListImgChar: config.systemKillboardListImgChar,
|
||||
systemKillboardListImgAlly: config.systemKillboardListImgAlly,
|
||||
systemKillboardListImgCorp: config.systemKillboardListImgCorp,
|
||||
zKillboardUrl: 'https://zkillboard.com',
|
||||
ccpImageServerUrl: Init.url.ccpImageServer,
|
||||
|
||||
dateFormat: () => {
|
||||
return (val, render) => {
|
||||
let killDate = Util.convertDateToUTC(new Date(render(val)));
|
||||
return Util.convertDateToString(killDate);
|
||||
};
|
||||
},
|
||||
iskFormat: () => {
|
||||
return (val, render) => {
|
||||
return Util.formatPrice(render(val));
|
||||
};
|
||||
},
|
||||
checkRender : () => {
|
||||
return (val, render) => {
|
||||
if(killMailCounter < killMailCounterMax){
|
||||
return render(val);
|
||||
}
|
||||
};
|
||||
},
|
||||
increaseCount : () => {
|
||||
return (val, render) => {
|
||||
killMailCounter++;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
requirejs(['text!templates/modules/killboard.html', 'mustache'], function(template, Mustache) {
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
moduleElement.append(content);
|
||||
|
||||
// animate kill li-elements
|
||||
$('.' + config.systemKillboardListEntryClass).velocity('transition.expandIn', {
|
||||
stagger: 50,
|
||||
complete: function(){
|
||||
// init tooltips
|
||||
moduleElement.find('[title]').tooltip({
|
||||
container: 'body'
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* updates the system info graph
|
||||
* @param systemData
|
||||
*/
|
||||
$.fn.updateSystemInfoGraphs = function(systemData){
|
||||
let moduleElement = $(this);
|
||||
|
||||
let killboardGraphElement = $('<div>', {
|
||||
class: config.systemKillboardGraphKillsClass
|
||||
});
|
||||
|
||||
moduleElement.append(killboardGraphElement);
|
||||
|
||||
let showHours = 24;
|
||||
let maxKillmailCount = 200; // limited by API
|
||||
|
||||
let labelOptions = {
|
||||
align: 'center-block'
|
||||
};
|
||||
let label = '';
|
||||
|
||||
// private function draws a "system kills" graph
|
||||
let drawGraph = function(data){
|
||||
let tableData = data.tableData;
|
||||
|
||||
// change order (show right to left)
|
||||
tableData.reverse();
|
||||
|
||||
if(data.count === 0){
|
||||
labelOptions.type = 'label-success';
|
||||
label = getLabel( 'No kills found within the last 24h', labelOptions );
|
||||
killboardGraphElement.append( label );
|
||||
|
||||
minifyKillboardGraphElement(killboardGraphElement);
|
||||
return;
|
||||
}
|
||||
|
||||
let labelYFormat = function(y){
|
||||
return Math.round(y);
|
||||
};
|
||||
|
||||
// draw chart
|
||||
Morris.Bar({
|
||||
element: killboardGraphElement,
|
||||
resize: true,
|
||||
redraw: true,
|
||||
grid: true,
|
||||
gridStrokeWidth: 0.3,
|
||||
gridTextSize: 9,
|
||||
gridTextColor: '#63676a',
|
||||
gridTextFamily: 'Oxygen Bold',
|
||||
hideHover: true,
|
||||
data: tableData,
|
||||
xkey: 'label',
|
||||
ykeys: ['kills'],
|
||||
labels: ['Kills'],
|
||||
yLabelFormat: labelYFormat,
|
||||
xLabelMargin: 10,
|
||||
padding: 10,
|
||||
parseTime: false,
|
||||
barOpacity: 0.8,
|
||||
barRadius: [2, 2, 0, 0],
|
||||
barSizeRatio: 0.5,
|
||||
barGap: 3,
|
||||
barColors: function (row, series, type) {
|
||||
if (type === 'bar') {
|
||||
// highlight last row -> recent kills found
|
||||
if(this.xmax === row.x){
|
||||
return '#c2760c';
|
||||
}
|
||||
}
|
||||
|
||||
return '#375959';
|
||||
}
|
||||
});
|
||||
|
||||
// show hint for recent kills
|
||||
if(tableData[tableData.length - 1].kills > 0){
|
||||
labelOptions.type = 'label-warning';
|
||||
label = getLabel( tableData[tableData.length - 1].kills + ' kills within the last hour', labelOptions );
|
||||
killboardGraphElement.prepend( label );
|
||||
}
|
||||
};
|
||||
|
||||
// get recent KB stats (last 24h))
|
||||
let localDate = new Date();
|
||||
|
||||
// cache result for 5min
|
||||
let cacheKey = systemData.systemId + '_' + localDate.getHours() + '_' + ( Math.ceil( localDate.getMinutes() / 5 ) * 5);
|
||||
|
||||
if(cache.systemKillsGraphData.hasOwnProperty(cacheKey) ){
|
||||
// cached results
|
||||
|
||||
drawGraph( cache.systemKillsGraphData[cacheKey] );
|
||||
|
||||
// show killmail information
|
||||
showKillmails(moduleElement, cache.systemKillsGraphData[cacheKey]);
|
||||
}else{
|
||||
|
||||
// chart data
|
||||
let chartData = [];
|
||||
|
||||
for(let i = 0; i < showHours; i++){
|
||||
let tempData = {
|
||||
label: i + 'h',
|
||||
kills: 0
|
||||
};
|
||||
|
||||
chartData.push(tempData);
|
||||
}
|
||||
|
||||
// get kills within the last 24h
|
||||
let timeFrameInSeconds = 60 * 60 * 24;
|
||||
|
||||
// get current server time
|
||||
let serverDate= Util.getServerTime();
|
||||
|
||||
// if system is w-space system -> add link modifier
|
||||
let wSpaceLinkModifier = '';
|
||||
if(systemData.type.id === 1){
|
||||
wSpaceLinkModifier = 'w-space/';
|
||||
}
|
||||
|
||||
let url = Init.url.zKillboard + '/';
|
||||
url += 'no-items/' + wSpaceLinkModifier + 'no-attackers/solarSystemID/' + systemData.systemId + '/pastSeconds/' + timeFrameInSeconds + '/';
|
||||
|
||||
killboardGraphElement.showLoadingAnimation();
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'GET',
|
||||
dataType: 'json'
|
||||
}).done(function(kbData) {
|
||||
|
||||
// the API wont return more than 200KMs ! - remember last bar block with complete KM information
|
||||
let lastCompleteDiffHourData = 0;
|
||||
|
||||
// loop kills and count kills by hour
|
||||
for (let i = 0; i < kbData.length; i++) {
|
||||
let killmailData = kbData[i];
|
||||
let killDate = Util.convertDateToUTC(new Date(killmailData.killmail_time));
|
||||
|
||||
// get time diff
|
||||
let timeDiffMin = Math.round(( serverDate - killDate ) / 1000 / 60);
|
||||
let timeDiffHour = Math.floor(timeDiffMin / 60);
|
||||
|
||||
// update chart data
|
||||
if (chartData[timeDiffHour]) {
|
||||
chartData[timeDiffHour].kills++;
|
||||
|
||||
// add kill mail data
|
||||
if (chartData[timeDiffHour].killmails === undefined) {
|
||||
chartData[timeDiffHour].killmails = [];
|
||||
}
|
||||
chartData[timeDiffHour].killmails.push(killmailData);
|
||||
|
||||
if (timeDiffHour > lastCompleteDiffHourData) {
|
||||
lastCompleteDiffHourData = timeDiffHour;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// remove empty chart Data
|
||||
if (kbData.length >= maxKillmailCount) {
|
||||
chartData = chartData.splice(0, lastCompleteDiffHourData + 1);
|
||||
}
|
||||
|
||||
// fill cache
|
||||
cache.systemKillsGraphData[cacheKey] = {};
|
||||
cache.systemKillsGraphData[cacheKey].tableData = chartData;
|
||||
cache.systemKillsGraphData[cacheKey].count = kbData.length;
|
||||
|
||||
// draw table
|
||||
drawGraph(cache.systemKillsGraphData[cacheKey]);
|
||||
|
||||
// show killmail information
|
||||
showKillmails(moduleElement, cache.systemKillsGraphData[cacheKey]);
|
||||
|
||||
killboardGraphElement.hideLoadingAnimation();
|
||||
}).fail(function(e){
|
||||
|
||||
labelOptions.type = 'label-danger';
|
||||
label = getLabel( 'zKillboard is not responding', labelOptions );
|
||||
killboardGraphElement.prepend( label );
|
||||
|
||||
killboardGraphElement.hideLoadingAnimation();
|
||||
|
||||
minifyKillboardGraphElement(killboardGraphElement);
|
||||
|
||||
Util.showNotify({title: e.status + ': Get system kills', text: 'Loading failed', type: 'error'});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// init tooltips
|
||||
let tooltipElements = moduleElement.find('[data-toggle="tooltip"]');
|
||||
tooltipElements.tooltip({
|
||||
container: 'body'
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* minify the killboard graph element e.g. if no kills where found, or on error
|
||||
* @param killboardGraphElement
|
||||
*/
|
||||
let minifyKillboardGraphElement = (killboardGraphElement) => {
|
||||
killboardGraphElement.velocity({
|
||||
height: '20px',
|
||||
marginBottom: '0px'
|
||||
},{
|
||||
duration: Init.animationSpeed.mapModule
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* get module toolbar element
|
||||
* @param systemData
|
||||
* @returns {*|jQuery|HTMLElement|void}
|
||||
*/
|
||||
let getHeadlineToolbar = (systemData) => {
|
||||
let headlineToolbar = $('<h5>', {
|
||||
class: 'pull-right'
|
||||
}).append(
|
||||
$('<i>', {
|
||||
class: ['fas', 'fa-fw', 'fa-external-link-alt ', config.moduleHeadlineIconClass].join(' '),
|
||||
title: 'zkillboard.com'
|
||||
}).on('click', function(e){
|
||||
window.open(
|
||||
'//zkillboard.com/system/' + systemData.systemId,
|
||||
'_blank'
|
||||
);
|
||||
}).attr('data-toggle', 'tooltip')
|
||||
);
|
||||
|
||||
headlineToolbar.find('[data-toggle="tooltip"]').tooltip({
|
||||
container: 'body'
|
||||
});
|
||||
|
||||
return headlineToolbar;
|
||||
};
|
||||
|
||||
/**
|
||||
* before module "show" callback
|
||||
* @param moduleElement
|
||||
* @param systemData
|
||||
*/
|
||||
let beforeShow = (moduleElement, systemData) => {
|
||||
// update graph
|
||||
moduleElement.updateSystemInfoGraphs(systemData);
|
||||
};
|
||||
|
||||
/**
|
||||
* get module element
|
||||
* @param parentElement
|
||||
* @param mapId
|
||||
* @param systemData
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
let getModule = (parentElement, mapId, systemData) => {
|
||||
// create new module container
|
||||
let moduleElement = $('<div>').append(
|
||||
$('<div>', {
|
||||
class: config.moduleHeadClass
|
||||
}).append(
|
||||
$('<h5>', {
|
||||
class: config.moduleHandlerClass
|
||||
}),
|
||||
$('<h5>', {
|
||||
text: 'Killboard'
|
||||
}),
|
||||
getHeadlineToolbar(systemData)
|
||||
)
|
||||
);
|
||||
|
||||
return moduleElement;
|
||||
};
|
||||
|
||||
return {
|
||||
config: config,
|
||||
getModule: getModule,
|
||||
beforeShow: beforeShow
|
||||
};
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user