- full refactoring of the "signature module" #679
- improved "character info" tooltips in e.g. signature Table - improved performance with the live time counters in e.g. signature table - fixed a bug where mass delete signatures on a system sometimes failed - fixed a bug where "signature type" sometimes not get saved correctly - fixed a bug where "responsive table columns" were not shown on larger screens
This commit is contained in:
@@ -173,20 +173,25 @@ class Signature extends Controller\AccessController {
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete(\Base $f3){
|
||||
$signatureIds = $f3->get('POST.signatureIds');
|
||||
$signatureIds = array_unique(array_map('intval', (array)$f3->get('POST.signatureIds')));
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
$return = (object) [];
|
||||
$return->deletedSignatureIds = [];
|
||||
|
||||
/**
|
||||
* @var Model\SystemSignatureModel $signature
|
||||
*/
|
||||
$signature = Model\BasicModel::getNew('SystemSignatureModel');
|
||||
foreach($signatureIds as $signatureId){
|
||||
$signature->getById($signatureId);
|
||||
$signature->delete( $activeCharacter );
|
||||
if($signature->delete($activeCharacter)){
|
||||
$return->deletedSignatureIds[] = $signatureId;
|
||||
}
|
||||
$signature->reset();
|
||||
}
|
||||
|
||||
echo json_encode([]);
|
||||
echo json_encode($return);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -218,14 +218,17 @@ class SystemSignatureModel extends AbstractMapTrackingModel {
|
||||
/**
|
||||
* delete signature
|
||||
* @param CharacterModel $characterModel
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(CharacterModel $characterModel){
|
||||
public function delete(CharacterModel $characterModel) : bool {
|
||||
$deleted = false;
|
||||
if( !$this->dry() ){
|
||||
// check if character has access
|
||||
if($this->hasAccess($characterModel)){
|
||||
$this->erase();
|
||||
$deleted = $this->erase();
|
||||
}
|
||||
}
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,7 @@ define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util'
|
||||
], function($, Init, Util) {
|
||||
], ($, Init, Util) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
@@ -16,7 +16,7 @@ define([
|
||||
* @param tempDate
|
||||
* @param round
|
||||
*/
|
||||
let updateDateDiff = function(element, tempDate, round){
|
||||
let updateDateDiff = (element, tempDate, round) => {
|
||||
let diff = Util.getTimeDiffParts(tempDate, new Date());
|
||||
let days = diff.days;
|
||||
let hrs = diff.hours;
|
||||
@@ -65,17 +65,21 @@ define([
|
||||
/**
|
||||
* destroy all active counter recursive
|
||||
*/
|
||||
$.fn.destroyTimestampCounter = function(){
|
||||
$.fn.destroyTimestampCounter = function(recursive){
|
||||
return this.each(function(){
|
||||
let parentElement = $(this);
|
||||
parentElement.find('[data-counter="init"]').each(function(){
|
||||
let element = $(this);
|
||||
let counterSelector = '[data-counter="init"]';
|
||||
let counterElements = element.filter(counterSelector);
|
||||
if(recursive){
|
||||
counterElements = counterElements.add(element.find(counterSelector));
|
||||
}
|
||||
|
||||
counterElements.each(function(){
|
||||
let element = $(this);
|
||||
let interval = element.data('interval');
|
||||
if(interval){
|
||||
clearInterval(interval);
|
||||
element.removeAttr('data-counter')
|
||||
.removeData('interval')
|
||||
.removeClass('stopCounter');
|
||||
element.removeAttr('data-counter').removeData('interval').removeClass('stopCounter');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -102,18 +106,27 @@ define([
|
||||
// show element (if invisible) after first update
|
||||
element.css({'visibility': 'initial'});
|
||||
|
||||
let refreshIntervalId = window.setInterval(function(){
|
||||
// calc ms until next second
|
||||
// -> makes sure all counter update in sync no matter when init
|
||||
let msUntilSecond = 1500 - new Date().getMilliseconds();
|
||||
setTimeout(function(){
|
||||
let refreshIntervalId = window.setInterval(function(){
|
||||
|
||||
// update element with current time
|
||||
if( !element.hasClass('stopCounter')){
|
||||
updateDateDiff(element, date, round);
|
||||
}else{
|
||||
clearInterval( element.data('interval') );
|
||||
}
|
||||
}, 500);
|
||||
// update element with current time
|
||||
if( !element.hasClass('stopCounter')){
|
||||
updateDateDiff(element, date, round);
|
||||
}else{
|
||||
clearInterval( element.data('interval') );
|
||||
}
|
||||
}, 500);
|
||||
|
||||
element.data('interval', refreshIntervalId);
|
||||
element.data('interval', refreshIntervalId);
|
||||
}, msUntilSecond);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
updateDateDiff: updateDateDiff
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,11 +1,41 @@
|
||||
define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'datatables.net',
|
||||
'datatables.net-buttons',
|
||||
'datatables.net-buttons-html',
|
||||
'datatables.net-responsive',
|
||||
'datatables.net-select'
|
||||
], (a, b) => {
|
||||
], ($, Init) => {
|
||||
'use strict';
|
||||
|
||||
// all Datatables stuff is available...
|
||||
let initDefaultDatatablesConfig = () => {
|
||||
|
||||
|
||||
|
||||
$.extend(true, $.fn.dataTable.defaults, {
|
||||
pageLength: -1,
|
||||
pagingType: 'simple_numbers',
|
||||
lengthMenu: [[5, 10, 25, 50, -1], [5, 10, 25, 50, 'All']],
|
||||
order: [], // no default order because columnDefs is empty
|
||||
autoWidth: false,
|
||||
responsive: {
|
||||
breakpoints: Init.breakpoints,
|
||||
details: false
|
||||
},
|
||||
columnDefs: [],
|
||||
data: []
|
||||
});
|
||||
|
||||
// global open event
|
||||
$(document).on('destroy.dt', '.dataTable ', function(e, settings){
|
||||
let table = $(this);
|
||||
|
||||
// remove all active counters in table
|
||||
table.destroyTimestampCounter(true);
|
||||
});
|
||||
};
|
||||
|
||||
initDefaultDatatablesConfig();
|
||||
});
|
||||
@@ -60,10 +60,12 @@ define(['jquery'], ($) => {
|
||||
gitHubReleases: '/api/github/releases' // ajax URL - get release info from GitHub
|
||||
},
|
||||
breakpoints: [
|
||||
{ name: 'desktop', width: Infinity },
|
||||
{ name: 'tablet', width: 1200 },
|
||||
{ name: 'fablet', width: 780 },
|
||||
{ name: 'phone', width: 480 }
|
||||
{ name: 'screen-xl', width: Infinity },
|
||||
{ name: 'screen-l', width: 1600 },
|
||||
{ name: 'screen-m', width: 1200 },
|
||||
{ name: 'screen-d', width: 1000 },
|
||||
{ name: 'screen-s', width: 780 },
|
||||
{ name: 'screen-xs', width: 480 }
|
||||
],
|
||||
animationSpeed: {
|
||||
splashOverlay: 300, // "splash" loading overlay
|
||||
|
||||
@@ -65,7 +65,7 @@ define([
|
||||
* @param connectionsData
|
||||
*/
|
||||
let addConnectionsOverlay = (connections, connectionsData) => {
|
||||
let SystemSignatures = require('app/ui/system_signature');
|
||||
let SystemSignatures = require('app/ui/module/system_signature_new');
|
||||
|
||||
/**
|
||||
* add label to endpoint
|
||||
|
||||
@@ -367,7 +367,7 @@ define([
|
||||
connection &&
|
||||
connectionData.signatures // signature data is required...
|
||||
){
|
||||
let SystemSignatures = require('app/ui/system_signature');
|
||||
let SystemSignatures = require('app/ui/module/system_signature_new');
|
||||
|
||||
let connectionId = connection.getParameter('connectionId');
|
||||
let sourceEndpoint = connection.endpoints[0];
|
||||
@@ -1426,6 +1426,7 @@ define([
|
||||
/**
|
||||
* add a wormhole tooltip with wh specific data to elements
|
||||
* @param tooltipData
|
||||
* @param options
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.addWormholeInfoTooltip = function(tooltipData, options){
|
||||
|
||||
@@ -5,13 +5,14 @@ define([
|
||||
'app/map/map',
|
||||
'app/map/util',
|
||||
'sortable',
|
||||
'app/ui/system_info',
|
||||
'app/ui/system_graph',
|
||||
'app/ui/system_signature',
|
||||
'app/ui/system_route',
|
||||
'app/ui/system_intel',
|
||||
'app/ui/system_killboard',
|
||||
'app/ui/connection_info',
|
||||
'app/ui/module/system_info',
|
||||
'app/ui/module/system_graph',
|
||||
//'app/ui/module/system_signature',
|
||||
'app/ui/module/system_signature_new',
|
||||
'app/ui/module/system_route',
|
||||
'app/ui/module/system_intel',
|
||||
'app/ui/module/system_killboard',
|
||||
'app/ui/module/connection_info',
|
||||
'app/counter'
|
||||
], (
|
||||
$,
|
||||
@@ -180,11 +181,12 @@ define([
|
||||
* @param moduleElement
|
||||
* @param Module
|
||||
* @param callback
|
||||
* @param addSpacer
|
||||
*/
|
||||
let removeModule = (moduleElement, Module, callback, addSpacer) => {
|
||||
if(moduleElement.length > 0){
|
||||
if(typeof Module.beforeReDraw === 'function'){
|
||||
Module.beforeReDraw();
|
||||
if(typeof Module.beforeHide === 'function'){
|
||||
Module.beforeHide(moduleElement);
|
||||
}
|
||||
|
||||
moduleElement.velocity('reverse',{
|
||||
@@ -336,8 +338,6 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
return new Promise(drawModuleExecutor);
|
||||
};
|
||||
|
||||
@@ -539,23 +539,25 @@ define([
|
||||
let clickY = e.pageY - posY;
|
||||
|
||||
// check for top-left click
|
||||
if(clickX <= 8 && clickY <= 8 && clickX >= 0 && clickY >= 0){
|
||||
if(clickX <= 9 && clickY <= 9 && clickX >= 0 && clickY >= 0){
|
||||
|
||||
// remember height
|
||||
if(! moduleElement.data('origHeight')){
|
||||
if( !moduleElement.data('origHeight') ){
|
||||
moduleElement.data('origHeight', moduleElement.outerHeight());
|
||||
}
|
||||
|
||||
if(moduleElement.hasClass( config.moduleClosedClass )){
|
||||
if(moduleElement.hasClass(config.moduleClosedClass)){
|
||||
let moduleHeight = moduleElement.data('origHeight');
|
||||
moduleElement.velocity('finish').velocity({
|
||||
height: [ moduleHeight + 'px', [ 400, 15 ] ]
|
||||
},{
|
||||
duration: 400,
|
||||
easing: 'easeOutSine',
|
||||
complete: function(){
|
||||
moduleElement.removeClass( config.moduleClosedClass );
|
||||
complete: function(moduleElement){
|
||||
moduleElement = $(moduleElement);
|
||||
moduleElement.removeClass(config.moduleClosedClass);
|
||||
moduleElement.removeData('origHeight');
|
||||
moduleElement.css({height: ''});
|
||||
}
|
||||
});
|
||||
}else{
|
||||
@@ -564,8 +566,9 @@ define([
|
||||
},{
|
||||
duration: 400,
|
||||
easing: 'easeOutSine',
|
||||
complete: function(){
|
||||
moduleElement.addClass( config.moduleClosedClass );
|
||||
complete: function(moduleElement){
|
||||
moduleElement = $(moduleElement);
|
||||
moduleElement.addClass(config.moduleClosedClass);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ define([
|
||||
dynamicElementWrapperId: 'pf-dialog-wrapper', // class for container element that holds hidden "context menus"
|
||||
|
||||
// system signature module
|
||||
systemSignatureModuleClass: 'pf-signature-table-module', // module wrapper (signatures)
|
||||
systemSignatureModuleClass: 'pf-system-signature-module', // module wrapper (signatures)
|
||||
systemIntelModuleClass: 'pf-system-intel-module', // module wrapper (intel)
|
||||
};
|
||||
|
||||
@@ -744,7 +744,7 @@ define([
|
||||
// global "modal" callback (for all modals)
|
||||
$('body').on('hide.bs.modal', '> .modal', function(e) {
|
||||
let modalElement = $(this);
|
||||
modalElement.destroyTimestampCounter();
|
||||
modalElement.destroyTimestampCounter(true);
|
||||
|
||||
// destroy all Select2
|
||||
modalElement.find('.' + Util.config.select2Class)
|
||||
|
||||
@@ -321,10 +321,6 @@ define([
|
||||
tooltipElements.tooltip();
|
||||
});
|
||||
|
||||
systemTable.on('destroy.dt', function(){
|
||||
$(this).destroyTimestampCounter();
|
||||
});
|
||||
|
||||
// prepare data for dataTables
|
||||
let systemsData = [];
|
||||
for(let i = 0; i < mapData.data.systems.length; i++){
|
||||
@@ -470,11 +466,6 @@ define([
|
||||
lengthMenu: [[5, 10, 20, 50, -1], [5, 10, 20, 50, 'All']],
|
||||
ordering: true,
|
||||
order: [[ 9, 'desc' ], [ 3, 'asc' ]],
|
||||
autoWidth: false,
|
||||
responsive: {
|
||||
breakpoints: Init.breakpoints,
|
||||
details: false
|
||||
},
|
||||
hover: false,
|
||||
data: systemsData,
|
||||
columnDefs: [],
|
||||
@@ -488,7 +479,7 @@ define([
|
||||
{
|
||||
title: 'type',
|
||||
width: '25px',
|
||||
className: ['min-desktop'].join(' '),
|
||||
className: ['min-screen-l'].join(' '),
|
||||
data: 'type',
|
||||
render: {
|
||||
_: 'type',
|
||||
@@ -506,7 +497,7 @@ define([
|
||||
},{
|
||||
title: 'sec',
|
||||
width: '18px',
|
||||
className: ['text-center', 'min-desktop'].join(' '),
|
||||
className: ['text-center', 'min-screen-l'].join(' '),
|
||||
searchable: false,
|
||||
data: 'trueSec',
|
||||
render: {
|
||||
@@ -516,7 +507,7 @@ define([
|
||||
},{
|
||||
title: '<i class="fas fa-skull" title="shattered" data-toggle="tooltip"></i>',
|
||||
width: '10px',
|
||||
className: ['text-center', 'min-desktop'].join(' '),
|
||||
className: ['text-center', 'min-screen-l'].join(' '),
|
||||
searchable: false,
|
||||
data: 'shattered',
|
||||
render: {
|
||||
@@ -593,7 +584,7 @@ define([
|
||||
title: 'updated',
|
||||
width: '80px',
|
||||
searchable: false,
|
||||
className: ['text-right', config.tableCellCounterClass, 'min-desktop'].join(' '),
|
||||
className: ['text-right', config.tableCellCounterClass, 'min-screen-l'].join(' '),
|
||||
data: 'updated',
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
$(cell).initTimestampCounter();
|
||||
@@ -863,11 +854,6 @@ define([
|
||||
lengthMenu: [[5, 10, 20, 50, -1], [5, 10, 20, 50, 'All']],
|
||||
ordering: true,
|
||||
order: [[ 3, 'asc' ]],
|
||||
autoWidth: false,
|
||||
responsive: {
|
||||
breakpoints: Init.breakpoints,
|
||||
details: false
|
||||
},
|
||||
hover: false,
|
||||
data: usersData,
|
||||
language: {
|
||||
@@ -962,7 +948,7 @@ define([
|
||||
width: 26,
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
className: [config.tableCellImageClass, config.tableCellImageSmallClass, 'min-desktop'].join(' '),
|
||||
className: [config.tableCellImageClass, config.tableCellImageSmallClass, 'min-screen-l'].join(' '),
|
||||
data: 'corporation',
|
||||
render: {
|
||||
_: function(data, type, row, meta){
|
||||
@@ -978,7 +964,7 @@ define([
|
||||
title: 'corporation',
|
||||
orderable: true,
|
||||
searchable: true,
|
||||
className: [config.tableCellActionClass, 'min-desktop'].join(' '),
|
||||
className: [config.tableCellActionClass, 'min-screen-l'].join(' '),
|
||||
data: 'corporation',
|
||||
render: {
|
||||
_: function (data, type, row, meta) {
|
||||
@@ -1041,7 +1027,7 @@ define([
|
||||
width: 30,
|
||||
orderable: true,
|
||||
searchable: true,
|
||||
className: ['text-right', 'min-desktop'].join(' '),
|
||||
className: ['text-right', 'min-screen-l'].join(' '),
|
||||
data: 'role',
|
||||
render: {
|
||||
_: function (data, type, row, meta) {
|
||||
|
||||
@@ -654,7 +654,7 @@ define([
|
||||
*/
|
||||
$.fn.initSignatureTypeSelect = function(options, hasOptGroups){
|
||||
let defaultConfig = {
|
||||
minimumResultsForSearch: 6,
|
||||
minimumResultsForSearch: 10,
|
||||
width: '220px',
|
||||
dropdownParent: this.parents('.popover-content')
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* connection info module
|
||||
* Connection info module
|
||||
*/
|
||||
|
||||
define([
|
||||
@@ -764,7 +764,7 @@ define([
|
||||
});
|
||||
|
||||
for(let i = 0; i < animationRows.length; i++){
|
||||
$(animationRows[i]).pulseTableRow($(animationRows[i]).data('animationStatus'));
|
||||
$(animationRows[i]).pulseBackgroundColor($(animationRows[i]).data('animationStatus'));
|
||||
$(animationRows[i]).removeData('animationStatus');
|
||||
}
|
||||
|
||||
@@ -808,10 +808,6 @@ define([
|
||||
$(cell).html(content);
|
||||
});
|
||||
});
|
||||
|
||||
logTable.on('destroy.dt', function(){
|
||||
$(this).destroyTimestampCounter();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -981,7 +977,6 @@ define([
|
||||
* @returns {*|jQuery|HTMLElement}
|
||||
*/
|
||||
let getModule = (parentElement, mapId, connections) => {
|
||||
// create new module container
|
||||
let moduleElement = $('<div>').append(
|
||||
$('<div>', {
|
||||
class: config.moduleHeadClass
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* System info module
|
||||
* System info module
|
||||
*/
|
||||
|
||||
define([
|
||||
@@ -156,8 +156,6 @@ define([
|
||||
* @param systemData
|
||||
*/
|
||||
let getModule = (parentElement, mapId, systemData) => {
|
||||
|
||||
// create new module container
|
||||
let moduleElement = $('<div>');
|
||||
|
||||
// store systemId -> module can be updated with the correct data
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* system route module
|
||||
* System intel module
|
||||
*/
|
||||
|
||||
define([
|
||||
@@ -16,6 +16,8 @@ define([
|
||||
moduleName: 'systemIntel',
|
||||
moduleHeadClass: 'pf-module-head', // class for module header
|
||||
moduleHandlerClass: 'pf-module-handler-drag', // class for "drag" handler
|
||||
|
||||
// system info module
|
||||
moduleTypeClass: 'pf-system-intel-module', // class for this module
|
||||
|
||||
// headline toolbar
|
||||
@@ -398,7 +400,6 @@ define([
|
||||
let getModule = (parentElement, mapId, systemData) => {
|
||||
let corporationId = Util.getCurrentUserInfo('corporationId');
|
||||
|
||||
// create new module container
|
||||
let moduleElement = $('<div>').append(
|
||||
$('<div>', {
|
||||
class: config.moduleHeadClass
|
||||
@@ -460,7 +461,7 @@ define([
|
||||
class: 'text-center',
|
||||
data: 'status',
|
||||
render: {
|
||||
display: data => getStatusData(data),
|
||||
display: data => getStatusData(data),
|
||||
sort: data => data.id
|
||||
},
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
@@ -542,7 +543,7 @@ define([
|
||||
data: null,
|
||||
render: {
|
||||
display: data => {
|
||||
let icon = '<i class="fas fa-pencil-alt"></i>';
|
||||
let icon = '<i class="fas fa-pen"></i>';
|
||||
if(data.corporation.id !== corporationId){
|
||||
icon = '';
|
||||
}
|
||||
@@ -660,7 +661,7 @@ define([
|
||||
|
||||
for(let i = 0; i < animationRows.length; i++){
|
||||
let animationRow = $(animationRows[i]);
|
||||
animationRow.pulseTableRow(animationRow.data('animationStatus'));
|
||||
animationRow.pulseBackgroundColor(animationRow.data('animationStatus'));
|
||||
animationRow.removeData('animationStatus');
|
||||
}
|
||||
},
|
||||
@@ -817,11 +818,24 @@ define([
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* before module destroy callback
|
||||
* @param moduleElement
|
||||
*/
|
||||
let beforeDestroy = moduleElement => {
|
||||
// Destroying the data tables throws
|
||||
// -> safety remove all dataTables
|
||||
let structureTableElement = moduleElement.find('.' + config.systemStructuresTableClass);
|
||||
let tableApi = structureTableElement.DataTable();
|
||||
tableApi.destroy();
|
||||
};
|
||||
|
||||
return {
|
||||
config: config,
|
||||
getModule: getModule,
|
||||
initModule: initModule,
|
||||
updateModule: updateModule
|
||||
updateModule: updateModule,
|
||||
beforeDestroy: beforeDestroy
|
||||
};
|
||||
|
||||
});
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* System killboard module
|
||||
*/
|
||||
|
||||
define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
@@ -378,7 +382,6 @@ define([
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
let getModule = (parentElement, mapId, systemData) => {
|
||||
// create new module container
|
||||
let moduleElement = $('<div>').append(
|
||||
$('<div>', {
|
||||
class: config.moduleHeadClass
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* system route module
|
||||
* System route module
|
||||
*/
|
||||
|
||||
define([
|
||||
@@ -18,8 +18,6 @@ define([
|
||||
moduleHeadClass: 'pf-module-head', // class for module header
|
||||
moduleHandlerClass: 'pf-module-handler-drag', // class for "drag" handler
|
||||
|
||||
routeCacheTTL: 5, // route cache timer (client) in seconds
|
||||
|
||||
// system route module
|
||||
moduleTypeClass: 'pf-system-route-module', // class for this module
|
||||
|
||||
@@ -42,7 +40,9 @@ define([
|
||||
dataTableRouteCellClass: 'pf-table-route-cell', // class for "route" cells
|
||||
dataTableJumpCellClass: 'pf-table-jump-cell', // class for "route jump" cells
|
||||
|
||||
rallyClass: 'pf-rally' // class for "rally point" style
|
||||
rallyClass: 'pf-rally', // class for "rally point" style
|
||||
|
||||
routeCacheTTL: 5 // route cache timer (client) in seconds
|
||||
};
|
||||
|
||||
// cache for system routes
|
||||
@@ -875,8 +875,6 @@ define([
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
let getModule = (parentElement, mapId, systemData) => {
|
||||
|
||||
// create new module container
|
||||
let moduleElement = $('<div>').append(
|
||||
$('<div>', {
|
||||
class: config.moduleHeadClass
|
||||
@@ -921,7 +919,7 @@ define([
|
||||
moduleElement.append(table);
|
||||
|
||||
// init empty table
|
||||
let routesTable = table.DataTable( {
|
||||
let routesTable = table.dataTable( {
|
||||
paging: false,
|
||||
ordering: true,
|
||||
order: [[ 2, 'asc' ], [ 0, 'asc' ]],
|
||||
@@ -1137,7 +1135,7 @@ define([
|
||||
|
||||
for(let i = 0; i < animationRows.length; i++){
|
||||
let animationRow = $(animationRows[i]);
|
||||
animationRow.pulseTableRow(animationRow.data('animationStatus'));
|
||||
animationRow.pulseBackgroundColor(animationRow.data('animationStatus'));
|
||||
animationRow.removeData('animationStatus');
|
||||
}
|
||||
},
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* System signature module
|
||||
* System signature module
|
||||
*/
|
||||
|
||||
define([
|
||||
@@ -24,7 +24,7 @@ define([
|
||||
moduleClass: 'pf-module', // class for each module
|
||||
|
||||
// system signature module
|
||||
moduleTypeClass: 'pf-signature-table-module', // module wrapper
|
||||
moduleTypeClass: 'pf-system-signature-module', // module wrapper
|
||||
|
||||
// headline toolbar
|
||||
moduleHeadlineIconClass: 'pf-module-icon-button', // class for toolbar icons in the head
|
||||
@@ -395,7 +395,7 @@ define([
|
||||
|
||||
if(changedRowElement){
|
||||
// highlight
|
||||
changedRowElement.pulseTableRow('changed');
|
||||
changedRowElement.pulseBackgroundColor('changed');
|
||||
notificationCounter.changed++;
|
||||
}
|
||||
}
|
||||
@@ -439,7 +439,7 @@ define([
|
||||
|
||||
if(newRowElement){
|
||||
// highlight
|
||||
newRowElement.pulseTableRow('added');
|
||||
newRowElement.pulseBackgroundColor('added');
|
||||
notificationCounter.added++;
|
||||
}
|
||||
}
|
||||
@@ -921,7 +921,7 @@ define([
|
||||
|
||||
/**
|
||||
* check the "delete signature" button. show/hide the button if a signature is selected
|
||||
* @param moduleElement
|
||||
* @param tableApi
|
||||
*/
|
||||
let checkDeleteSignaturesButton = tableApi => {
|
||||
let selectedRows = getSelectedRows(tableApi);
|
||||
@@ -1907,8 +1907,8 @@ define([
|
||||
highlight: false,
|
||||
title: 'filter groups',
|
||||
value: selectedValues,
|
||||
source: sourceOptions,
|
||||
prepend: prependOptions,
|
||||
source: sourceOptions,
|
||||
inputclass: config.editableUnknownInputClass,
|
||||
display: function(value, sourceData){
|
||||
// update filter button label
|
||||
@@ -2231,7 +2231,7 @@ define([
|
||||
|
||||
if(newRowElement){
|
||||
// highlight
|
||||
newRowElement.pulseTableRow('added');
|
||||
newRowElement.pulseBackgroundColor('added');
|
||||
|
||||
// prepare "add signature" table for new entry -> reset -------------------
|
||||
let signatureData = formatSignatureData(systemData, [emptySignatureData], emptySignatureOptions);
|
||||
@@ -2429,7 +2429,6 @@ define([
|
||||
* @returns {*|jQuery|HTMLElement}
|
||||
*/
|
||||
let getModule = function(parentElement, mapId, systemData){
|
||||
// create new module container
|
||||
let moduleElement = $('<div>').append(
|
||||
$('<div>', {
|
||||
class: config.moduleHeadClass
|
||||
@@ -2481,9 +2480,9 @@ define([
|
||||
};
|
||||
|
||||
/**
|
||||
* before module reDraw callback
|
||||
* before module hide callback
|
||||
*/
|
||||
let beforeReDraw = () => {
|
||||
let beforeHide = () => {
|
||||
// disable update
|
||||
lockSignatureTable();
|
||||
};
|
||||
@@ -2504,8 +2503,8 @@ define([
|
||||
config: config,
|
||||
getModule: getModule,
|
||||
initModule: initModule,
|
||||
beforeReDraw: beforeReDraw,
|
||||
updateModule: updateModule,
|
||||
beforeHide: beforeHide,
|
||||
beforeDestroy: beforeDestroy,
|
||||
getAllSignatureNamesBySystem: getAllSignatureNamesBySystem
|
||||
};
|
||||
2461
js/app/ui/module/system_signature_new.js
Normal file
2461
js/app/ui/module/system_signature_new.js
Normal file
File diff suppressed because it is too large
Load Diff
274
js/app/util.js
274
js/app/util.js
@@ -33,7 +33,6 @@ define([
|
||||
|
||||
// head
|
||||
headMapTrackingId: 'pf-head-map-tracking', // id for "map tracking" toggle (checkbox)
|
||||
headCharacterSwitchId: 'pf-head-character-switch', // id for "character switch" popover
|
||||
headCurrentLocationId: 'pf-head-current-location', // id for "show current location" element
|
||||
|
||||
// menu
|
||||
@@ -66,10 +65,12 @@ define([
|
||||
// animation
|
||||
animationPulseSuccessClass: 'pf-animation-pulse-success', // animation class
|
||||
animationPulseWarningClass: 'pf-animation-pulse-warning', // animation class
|
||||
animationPulseDangerClass: 'pf-animation-pulse-danger', // animation class
|
||||
|
||||
// popover
|
||||
popoverSmallClass: 'pf-popover-small', // class for "small" popover
|
||||
popoverTriggerClass: 'pf-popover-trigger', // class for "popover" trigger elements
|
||||
popoverSmallClass: 'pf-popover-small', // class for small "popover"
|
||||
popoverCharacterClass: 'pf-popover-character', // class for character "popover"
|
||||
|
||||
// help
|
||||
helpDefaultClass: 'pf-help-default', // class for "help" tooltip elements
|
||||
@@ -231,7 +232,7 @@ define([
|
||||
}else{
|
||||
callback(responseData.img);
|
||||
}
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
}).fail(function( jqXHR, status, error){
|
||||
let reason = status + ' ' + error;
|
||||
showNotify({title: jqXHR.status + ': getCaptchaImage', text: reason, type: 'error'});
|
||||
});
|
||||
@@ -424,7 +425,7 @@ define([
|
||||
let width = element.offsetWidth;
|
||||
let height = element.offsetHeight;
|
||||
|
||||
while(element.offsetParent) {
|
||||
while(element.offsetParent){
|
||||
element = element.offsetParent;
|
||||
top += element.offsetTop;
|
||||
left += element.offsetLeft;
|
||||
@@ -494,7 +495,7 @@ define([
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.destroyTooltip = function(recursive){
|
||||
return this.each(function() {
|
||||
return this.each(function(){
|
||||
let element = $(this);
|
||||
let tooltipSelector = '[title]';
|
||||
let tooltipElements = element.filter(tooltipSelector);
|
||||
@@ -502,18 +503,20 @@ define([
|
||||
tooltipElements = tooltipElements.add(element.find(tooltipSelector));
|
||||
}
|
||||
|
||||
tooltipElements.each(function() {
|
||||
tooltipElements.each(function(){
|
||||
$(this).tooltip('destroy');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* adds a popup tooltip with character information (created/updated)
|
||||
* add a popup tooltip with character information (created/updated)
|
||||
* @param tooltipData
|
||||
* @param options
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.addCharacterInfoTooltip = function(tooltipData){
|
||||
let element = $(this);
|
||||
$.fn.addCharacterInfoTooltip = function(tooltipData, options){
|
||||
let data = {};
|
||||
|
||||
if(
|
||||
tooltipData.created.character &&
|
||||
@@ -522,59 +525,60 @@ define([
|
||||
let createdData = tooltipData.created;
|
||||
let updatedData = tooltipData.updated;
|
||||
|
||||
// check if data has changed
|
||||
if(
|
||||
element.data('created') !== createdData.created ||
|
||||
element.data('updated') !== updatedData.updated
|
||||
){
|
||||
// data changed
|
||||
// set new data for next check
|
||||
element.data('created', createdData.created);
|
||||
element.data('updated', updatedData.updated);
|
||||
let statusCreatedClass = getStatusInfoForCharacter(createdData.character, 'class');
|
||||
let statusUpdatedClass = getStatusInfoForCharacter(updatedData.character, 'class');
|
||||
|
||||
let statusCreatedClass = getStatusInfoForCharacter(createdData.character, 'class');
|
||||
let statusUpdatedClass = getStatusInfoForCharacter(updatedData.character, 'class');
|
||||
// convert timestamps
|
||||
let dateCreated = new Date(createdData.created * 1000);
|
||||
let dateUpdated = new Date(updatedData.updated * 1000);
|
||||
let dateCreatedUTC = convertDateToUTC(dateCreated);
|
||||
let dateUpdatedUTC = convertDateToUTC(dateUpdated);
|
||||
|
||||
// convert timestamps
|
||||
let dateCreated = new Date(createdData.created * 1000);
|
||||
let dateUpdated = new Date(updatedData.updated * 1000);
|
||||
let dateCreatedUTC = convertDateToUTC(dateCreated);
|
||||
let dateUpdatedUTC = convertDateToUTC(dateUpdated);
|
||||
|
||||
let data = {
|
||||
created: createdData,
|
||||
updated: updatedData,
|
||||
createdTime: convertDateToString(dateCreatedUTC),
|
||||
updatedTime: convertDateToString(dateUpdatedUTC),
|
||||
createdStatusClass: statusCreatedClass,
|
||||
updatedStatusClass: statusUpdatedClass
|
||||
};
|
||||
|
||||
requirejs(['text!templates/tooltip/character_info.html', 'mustache'], function(template, Mustache) {
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
element.popover({
|
||||
placement: 'top',
|
||||
html: true,
|
||||
trigger: 'hover',
|
||||
content: '',
|
||||
container: 'body',
|
||||
title: 'Created / Updated',
|
||||
delay: {
|
||||
show: 250,
|
||||
hide: 0
|
||||
}
|
||||
});
|
||||
|
||||
// set new popover content
|
||||
let popover = element.data('bs.popover');
|
||||
popover.options.content = content;
|
||||
});
|
||||
|
||||
}
|
||||
data = {
|
||||
popoverClass: config.popoverCharacterClass,
|
||||
ccpImageServerUrl: Init.url.ccpImageServer,
|
||||
created: createdData,
|
||||
updated: updatedData,
|
||||
createdTime: convertDateToString(dateCreatedUTC),
|
||||
updatedTime: convertDateToString(dateUpdatedUTC),
|
||||
createdStatusClass: statusCreatedClass,
|
||||
updatedStatusClass: statusUpdatedClass
|
||||
};
|
||||
}
|
||||
|
||||
return element;
|
||||
let defaultOptions = {
|
||||
placement: 'top',
|
||||
html: true,
|
||||
trigger: 'hover',
|
||||
container: 'body',
|
||||
title: 'Created / Updated',
|
||||
delay: {
|
||||
show: 150,
|
||||
hide: 0
|
||||
}
|
||||
};
|
||||
|
||||
options = $.extend({}, defaultOptions, options);
|
||||
|
||||
return this.each(function(){
|
||||
let element = $(this);
|
||||
|
||||
requirejs(['text!templates/tooltip/character_info.html', 'mustache'], (template, Mustache) => {
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
element.popover(options);
|
||||
|
||||
// set new popover content
|
||||
let popover = element.data('bs.popover');
|
||||
popover.options.content = content;
|
||||
|
||||
if(options.show){
|
||||
element.popover('show');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -585,10 +589,10 @@ define([
|
||||
let elements = $(this);
|
||||
let eventNamespace = 'hideCharacterPopup';
|
||||
|
||||
requirejs(['text!templates/tooltip/character_switch.html', 'mustache'], function (template, Mustache) {
|
||||
requirejs(['text!templates/tooltip/character_switch.html', 'mustache'], function (template, Mustache){
|
||||
|
||||
let data = {
|
||||
id: config.headCharacterSwitchId,
|
||||
popoverClass: config.popoverCharacterClass,
|
||||
browserTabId: getBrowserTabId(),
|
||||
routes: Init.routes,
|
||||
userData: userData,
|
||||
@@ -608,7 +612,7 @@ define([
|
||||
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
return elements.each(function() {
|
||||
return elements.each(function(){
|
||||
let element = $(this);
|
||||
|
||||
// check if popover already exists -> remove it
|
||||
@@ -616,7 +620,7 @@ define([
|
||||
element.off('click').popover('destroy');
|
||||
}
|
||||
|
||||
element.on('click', function(e) {
|
||||
element.on('click', function(e){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
@@ -631,7 +635,7 @@ define([
|
||||
|
||||
if(popoverData === undefined){
|
||||
|
||||
button.on('shown.bs.popover', function (e) {
|
||||
button.on('shown.bs.popover', function (e){
|
||||
let tmpPopupElement = $(this).data('bs.popover').tip();
|
||||
tmpPopupElement.find('.btn').on('click', function(e){
|
||||
// close popover
|
||||
@@ -662,7 +666,7 @@ define([
|
||||
// character switch detected
|
||||
$('body').data('characterSwitch', true);
|
||||
// ... and remove "characterSwitch" data again! after "unload"
|
||||
setTimeout(function() {
|
||||
setTimeout(function(){
|
||||
$('body').removeData('characterSwitch');
|
||||
}, 500);
|
||||
});
|
||||
@@ -690,7 +694,7 @@ define([
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.destroyPopover = function(recursive){
|
||||
return this.each(function() {
|
||||
return this.each(function(){
|
||||
let element = $(this);
|
||||
let popoverSelector = '.' + config.popoverTriggerClass;
|
||||
let popoverElements = element.filter(popoverSelector);
|
||||
@@ -698,7 +702,7 @@ define([
|
||||
popoverElements = popoverElements.add(element.find(popoverSelector));
|
||||
}
|
||||
|
||||
popoverElements.each(function() {
|
||||
popoverElements.each(function(){
|
||||
let popoverElement = $(this);
|
||||
if(popoverElement.data('bs.popover')){
|
||||
popoverElement.popover('destroy');
|
||||
@@ -713,9 +717,9 @@ define([
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.initPopoverClose = function(eventNamespace){
|
||||
return this.each(function() {
|
||||
$('body').off('click.' + eventNamespace).on('click.' + eventNamespace + ' contextmenu', function (e) {
|
||||
$('.' + config.popoverTriggerClass).each(function () {
|
||||
return this.each(function(){
|
||||
$('body').off('click.' + eventNamespace).on('click.' + eventNamespace + ' contextmenu', function (e){
|
||||
$('.' + config.popoverTriggerClass).each(function (){
|
||||
let popoverElement = $(this);
|
||||
//the 'is' for buttons that trigger popups
|
||||
//the 'has' for icons within a button that triggers a popup
|
||||
@@ -743,7 +747,7 @@ define([
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.setPopoverSmall = function(){
|
||||
return this.each(function() {
|
||||
return this.each(function(){
|
||||
let element = $(this);
|
||||
let popover = element.data('bs.popover');
|
||||
if(popover){
|
||||
@@ -760,7 +764,7 @@ define([
|
||||
$.fn.showMessage = function(config){
|
||||
let containerElement = $(this);
|
||||
|
||||
requirejs(['text!templates/form/message.html', 'mustache'], function(template, Mustache) {
|
||||
requirejs(['text!templates/form/message.html', 'mustache'], function(template, Mustache){
|
||||
|
||||
let messageTypeClass = 'alert-danger';
|
||||
let messageTextClass = 'txt-color-danger';
|
||||
@@ -809,7 +813,7 @@ define([
|
||||
* add/remove css class for keyframe animation
|
||||
* @returns {any|JQuery|*}
|
||||
*/
|
||||
$.fn.pulseTableRow = function(status, clear){
|
||||
$.fn.pulseBackgroundColor = function(status, clear){
|
||||
|
||||
let animationClass = '';
|
||||
switch(status){
|
||||
@@ -819,9 +823,12 @@ define([
|
||||
case 'changed':
|
||||
animationClass = config.animationPulseWarningClass;
|
||||
break;
|
||||
case 'deleted':
|
||||
animationClass = config.animationPulseDangerClass;
|
||||
break;
|
||||
}
|
||||
|
||||
let clearTimer = function(element) {
|
||||
let clearTimer = element => {
|
||||
element.removeClass( animationClass );
|
||||
let currentTimer = element.data('animationTimer');
|
||||
|
||||
@@ -841,7 +848,7 @@ define([
|
||||
}
|
||||
|
||||
if(clear !== true){
|
||||
element.addClass( animationClass );
|
||||
element.addClass(animationClass);
|
||||
let timer = setTimeout(clearTimer, 1500, element);
|
||||
element.data('animationTimer', timer);
|
||||
animationTimerCache[timer] = true;
|
||||
@@ -902,14 +909,14 @@ define([
|
||||
|
||||
const prepareSafeListener = (listener, passive) => {
|
||||
if (!passive) return listener;
|
||||
return function (e) {
|
||||
return function (e){
|
||||
e.preventDefault = () => {};
|
||||
return listener.call(this, e);
|
||||
};
|
||||
};
|
||||
|
||||
const overwriteAddEvent = (superMethod) => {
|
||||
EventTarget.prototype.addEventListener = function (type, listener, options) { // jshint ignore:line
|
||||
EventTarget.prototype.addEventListener = function (type, listener, options){ // jshint ignore:line
|
||||
const usesListenerOptions = typeof options === 'object';
|
||||
const useCapture = usesListenerOptions ? options.capture : options;
|
||||
|
||||
@@ -927,20 +934,20 @@ define([
|
||||
|
||||
try {
|
||||
const opts = Object.defineProperty({}, 'passive', {
|
||||
get() {
|
||||
get(){
|
||||
supported = true;
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('test', null, opts);
|
||||
window.removeEventListener('test', null, opts);
|
||||
} catch (e) {}
|
||||
} catch (e){}
|
||||
|
||||
return supported;
|
||||
};
|
||||
|
||||
let supportsPassive = eventListenerOptionsSupported ();
|
||||
if (supportsPassive) {
|
||||
if (supportsPassive){
|
||||
const addEvent = EventTarget.prototype.addEventListener; // jshint ignore:line
|
||||
overwriteAddEvent(addEvent);
|
||||
}
|
||||
@@ -953,8 +960,8 @@ define([
|
||||
// Array diff
|
||||
// [1,2,3,4,5,6].diff( [3,4,5] );
|
||||
// => [1, 2, 6]
|
||||
Array.prototype.diff = function(a) {
|
||||
return this.filter(function(i) {return a.indexOf(i) < 0;});
|
||||
Array.prototype.diff = function(a){
|
||||
return this.filter(function(i){return a.indexOf(i) < 0;});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -962,7 +969,7 @@ define([
|
||||
* @param p
|
||||
* @returns {Array.<T>}
|
||||
*/
|
||||
Array.prototype.sortBy = function(p) {
|
||||
Array.prototype.sortBy = function(p){
|
||||
return this.slice(0).sort((a,b) => {
|
||||
return (a[p] > b[p]) ? 1 : (a[p] < b[p]) ? -1 : 0;
|
||||
});
|
||||
@@ -972,10 +979,10 @@ define([
|
||||
* get hash from string
|
||||
* @returns {number}
|
||||
*/
|
||||
String.prototype.hashCode = function() {
|
||||
String.prototype.hashCode = function(){
|
||||
let hash = 0, i, chr;
|
||||
if (this.length === 0) return hash;
|
||||
for (i = 0; i < this.length; i++) {
|
||||
for (i = 0; i < this.length; i++){
|
||||
chr = this.charCodeAt(i);
|
||||
hash = ((hash << 5) - hash) + chr;
|
||||
hash |= 0; // Convert to 32bit integer
|
||||
@@ -1094,6 +1101,12 @@ define([
|
||||
if(resultsWrapper){
|
||||
resultsWrapper.mCustomScrollbar('destroy');
|
||||
}
|
||||
|
||||
// select2 sets :focus to the select2 <input> field. This is bad!
|
||||
// we want to keep the focus where it is (e.g. signature table cell)
|
||||
// the only way to prevent this is to remove the element
|
||||
// https://stackoverflow.com/questions/17995057/prevent-select2-from-autmatically-focussing-its-search-input-when-dropdown-is-op
|
||||
$(this).parents('.editableform').find(this).next().find('.select2-selection').remove();
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1262,7 +1275,7 @@ define([
|
||||
// line breaks are 2 characters!
|
||||
let newLines = value.match(/(\r\n|\n|\r)/g);
|
||||
let addition = 0;
|
||||
if (newLines != null) {
|
||||
if(newLines != null){
|
||||
addition = newLines.length;
|
||||
}
|
||||
inputLength += addition;
|
||||
@@ -1300,7 +1313,7 @@ define([
|
||||
* stop browser tab title "blinking"
|
||||
*/
|
||||
let stopTabBlink = function(){
|
||||
requirejs(['notification'], function(Notification) {
|
||||
requirejs(['notification'], function(Notification){
|
||||
Notification.stopTabBlink();
|
||||
});
|
||||
};
|
||||
@@ -1388,7 +1401,7 @@ define([
|
||||
*/
|
||||
let ajaxSetup = () => {
|
||||
$.ajaxSetup({
|
||||
beforeSend: function(jqXHR, settings) {
|
||||
beforeSend: function(jqXHR, settings){
|
||||
// store request URL for later use (e.g. in error messages)
|
||||
jqXHR.url = location.protocol + '//' + location.host + settings.url;
|
||||
|
||||
@@ -1579,11 +1592,13 @@ define([
|
||||
};
|
||||
|
||||
/**
|
||||
* get Area ID by security string
|
||||
* get areaId by security string
|
||||
* areaId is required as a key for signature names
|
||||
* if areaId is 0, no signature data is available for this system
|
||||
* @param security
|
||||
* @returns {number}
|
||||
*/
|
||||
let getAreaIdBySecurity = (security) => {
|
||||
let getAreaIdBySecurity = security => {
|
||||
let areaId = 0;
|
||||
switch(security){
|
||||
case 'H':
|
||||
@@ -1646,7 +1661,6 @@ define([
|
||||
* @returns {string}
|
||||
*/
|
||||
let getStatusInfoForCharacter = (characterData, option) => {
|
||||
|
||||
let statusInfo = '';
|
||||
|
||||
// character status can not be checked if there are no reference data
|
||||
@@ -1898,20 +1912,17 @@ define([
|
||||
/**
|
||||
* get signature group information
|
||||
* @param option
|
||||
* @returns {{}}
|
||||
* @returns {Array}
|
||||
*/
|
||||
let getSignatureGroupInfo = function(option){
|
||||
|
||||
let groupInfo = {};
|
||||
|
||||
for (let prop in Init.signatureGroups) {
|
||||
if(Init.signatureGroups.hasOwnProperty(prop)){
|
||||
prop = parseInt(prop);
|
||||
groupInfo[prop] = Init.signatureGroups[prop][option];
|
||||
}
|
||||
let getSignatureGroupOptions = option => {
|
||||
let options = [];
|
||||
for(let [key, data] of Object.entries(Init.signatureGroups)){
|
||||
options.push({
|
||||
value: parseInt(key),
|
||||
text: data[option]
|
||||
});
|
||||
}
|
||||
|
||||
return groupInfo;
|
||||
return options;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1943,28 +1954,22 @@ define([
|
||||
* @param name
|
||||
* @returns {number}
|
||||
*/
|
||||
let getSignatureTypeIdByName = function(systemData, sigGroupId, name){
|
||||
|
||||
let getSignatureTypeIdByName = (systemData, sigGroupId, name) => {
|
||||
let signatureTypeId = 0;
|
||||
|
||||
let areaId = getAreaIdBySecurity(systemData.security);
|
||||
|
||||
if(areaId > 0){
|
||||
let signatureNames = getAllSignatureNames(systemData.type.id, areaId, sigGroupId );
|
||||
let signatureNames = getAllSignatureNames(systemData.type.id, areaId, sigGroupId);
|
||||
name = name.toLowerCase();
|
||||
|
||||
for(let prop in signatureNames) {
|
||||
|
||||
for(let prop in signatureNames){
|
||||
if(
|
||||
signatureNames.hasOwnProperty(prop) &&
|
||||
signatureNames[prop].toLowerCase() === name
|
||||
){
|
||||
signatureTypeId = parseInt( prop );
|
||||
signatureTypeId = parseInt(prop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return signatureTypeId;
|
||||
};
|
||||
|
||||
@@ -1995,9 +2000,8 @@ define([
|
||||
* to keep the data always up2data
|
||||
* @param mapUserData
|
||||
*/
|
||||
let setCurrentMapUserData = (mapUserData) => {
|
||||
let setCurrentMapUserData = mapUserData => {
|
||||
Init.currentMapUserData = mapUserData;
|
||||
|
||||
return getCurrentMapUserData();
|
||||
};
|
||||
|
||||
@@ -2006,7 +2010,7 @@ define([
|
||||
* @param mapId
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let getCurrentMapUserData = (mapId) => {
|
||||
let getCurrentMapUserData = mapId => {
|
||||
let currentMapUserData = false;
|
||||
|
||||
if(Init.currentMapUserData){
|
||||
@@ -2041,7 +2045,7 @@ define([
|
||||
* @param mapId
|
||||
* @returns {boolean|int}
|
||||
*/
|
||||
let getCurrentMapUserDataIndex = (mapId) => {
|
||||
let getCurrentMapUserDataIndex = mapId => {
|
||||
return getDataIndexByMapId(Init.currentMapUserData, mapId);
|
||||
};
|
||||
|
||||
@@ -2049,7 +2053,7 @@ define([
|
||||
* update cached mapUserData for a single map
|
||||
* @param mapUserData
|
||||
*/
|
||||
let updateCurrentMapUserData = (mapUserData) => {
|
||||
let updateCurrentMapUserData = mapUserData => {
|
||||
let mapUserDataIndex = getCurrentMapUserDataIndex( mapUserData.config.id );
|
||||
|
||||
if( !Array.isArray(Init.currentMapUserData) ){
|
||||
@@ -2072,7 +2076,7 @@ define([
|
||||
* to keep the data always up2data
|
||||
* @param mapData
|
||||
*/
|
||||
let setCurrentMapData = (mapData) => {
|
||||
let setCurrentMapData = mapData => {
|
||||
Init.currentMapData = mapData;
|
||||
|
||||
return getCurrentMapData();
|
||||
@@ -2083,7 +2087,7 @@ define([
|
||||
* @param mapId
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let getCurrentMapData = (mapId) => {
|
||||
let getCurrentMapData = mapId => {
|
||||
let currentMapData = false;
|
||||
|
||||
if( mapId === parseInt(mapId, 10) ){
|
||||
@@ -2107,7 +2111,7 @@ define([
|
||||
* @param mapId
|
||||
* @returns {boolean|int}
|
||||
*/
|
||||
let getCurrentMapDataIndex = (mapId) => {
|
||||
let getCurrentMapDataIndex = mapId => {
|
||||
return getDataIndexByMapId(Init.currentMapData, mapId);
|
||||
};
|
||||
|
||||
@@ -2115,7 +2119,7 @@ define([
|
||||
* update cached mapData for a single map
|
||||
* @param mapData
|
||||
*/
|
||||
let updateCurrentMapData = (mapData) => {
|
||||
let updateCurrentMapData = mapData => {
|
||||
let mapDataIndex = getCurrentMapDataIndex( mapData.config.id );
|
||||
|
||||
if(mapDataIndex !== false){
|
||||
@@ -2146,7 +2150,7 @@ define([
|
||||
* delete map data by mapId from currentMapData
|
||||
* @param mapId
|
||||
*/
|
||||
let deleteCurrentMapData = (mapId) => {
|
||||
let deleteCurrentMapData = mapId => {
|
||||
Init.currentMapData = Init.currentMapData.filter((mapData) => {
|
||||
return (mapData.config.id !== mapId);
|
||||
});
|
||||
@@ -2176,7 +2180,7 @@ define([
|
||||
* @param option
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let getCurrentUserInfo = (option) => {
|
||||
let getCurrentUserInfo = option => {
|
||||
let currentUserData = getCurrentUserData();
|
||||
let userInfo = false;
|
||||
|
||||
@@ -2297,7 +2301,7 @@ define([
|
||||
characterData = characterData.filter(function(tmpCharacterData, index, allData){
|
||||
let keepData = true;
|
||||
|
||||
for(let tmpJump in data) {
|
||||
for(let tmpJump in data){
|
||||
// just scan systems with > jumps than current system
|
||||
if(tmpJump > jumps){
|
||||
let filteredFinalData = data[tmpJump].filter(filterFinalCharData, tmpCharacterData);
|
||||
@@ -2325,7 +2329,7 @@ define([
|
||||
}
|
||||
|
||||
jumps++;
|
||||
for(let prop in nearBySystems.tree) {
|
||||
for(let prop in nearBySystems.tree){
|
||||
if( nearBySystems.tree.hasOwnProperty(prop) ){
|
||||
let tmpSystemData = nearBySystems.tree[prop];
|
||||
data = getNearByCharacterData(tmpSystemData, userData, jumps, data);
|
||||
@@ -2374,7 +2378,7 @@ define([
|
||||
responseData.systemData &&
|
||||
responseData.systemData.length > 0
|
||||
){
|
||||
for (let j = 0; j < responseData.systemData.length; j++) {
|
||||
for (let j = 0; j < responseData.systemData.length; j++){
|
||||
showNotify({title: this.description, text: 'System: ' + responseData.systemData[j].name, type: 'success'});
|
||||
}
|
||||
}
|
||||
@@ -2388,7 +2392,7 @@ define([
|
||||
}
|
||||
}
|
||||
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
}).fail(function( jqXHR, status, error){
|
||||
let reason = status + ' ' + error;
|
||||
showNotify({title: jqXHR.status + ': ' + this.description, text: reason, type: 'warning'});
|
||||
});
|
||||
@@ -2452,7 +2456,7 @@ define([
|
||||
}else{
|
||||
showNotify({title: 'Open window in client', text: 'Check your EVE client', type: 'success'});
|
||||
}
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
}).fail(function( jqXHR, status, error){
|
||||
let reason = status + ' ' + error;
|
||||
showNotify({title: jqXHR.status + ': openWindow', text: reason, type: 'error'});
|
||||
});
|
||||
@@ -2585,9 +2589,9 @@ define([
|
||||
|
||||
element.off(eventName).on(eventName, function(e){
|
||||
clicks++;
|
||||
if (clicks === 1) {
|
||||
if (clicks === 1){
|
||||
setTimeout(element => {
|
||||
if(clicks === 1) {
|
||||
if(clicks === 1){
|
||||
singleClickCallback.call(element, e);
|
||||
} else {
|
||||
doubleClickCallback.call(element, e);
|
||||
@@ -2666,7 +2670,7 @@ define([
|
||||
if(data.reroute){
|
||||
redirect(data.reroute, ['logout']);
|
||||
}
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
}).fail(function( jqXHR, status, error){
|
||||
let reason = status + ' ' + error;
|
||||
showNotify({title: jqXHR.status + ': logout', text: reason, type: 'error'});
|
||||
});
|
||||
@@ -2709,13 +2713,13 @@ define([
|
||||
let name = cname + '=';
|
||||
let ca = document.cookie.split(';');
|
||||
|
||||
for(let i = 0; i <ca.length; i++) {
|
||||
for(let i = 0; i <ca.length; i++){
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) === ' ') {
|
||||
while (c.charAt(0) === ' '){
|
||||
c = c.substring(1);
|
||||
}
|
||||
|
||||
if (c.indexOf(name) === 0) {
|
||||
if (c.indexOf(name) === 0){
|
||||
return c.substring(name.length,c.length);
|
||||
}
|
||||
}
|
||||
@@ -2757,7 +2761,7 @@ define([
|
||||
getSecurityClassForSystem: getSecurityClassForSystem,
|
||||
getTrueSecClassForSystem: getTrueSecClassForSystem,
|
||||
getStatusInfoForSystem: getStatusInfoForSystem,
|
||||
getSignatureGroupInfo: getSignatureGroupInfo,
|
||||
getSignatureGroupOptions: getSignatureGroupOptions,
|
||||
getAllSignatureNames: getAllSignatureNames,
|
||||
getSignatureTypeIdByName: getSignatureTypeIdByName,
|
||||
getAreaIdBySecurity: getAreaIdBySecurity,
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -2,7 +2,7 @@ define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util'
|
||||
], function($, Init, Util) {
|
||||
], ($, Init, Util) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
@@ -16,7 +16,7 @@ define([
|
||||
* @param tempDate
|
||||
* @param round
|
||||
*/
|
||||
let updateDateDiff = function(element, tempDate, round){
|
||||
let updateDateDiff = (element, tempDate, round) => {
|
||||
let diff = Util.getTimeDiffParts(tempDate, new Date());
|
||||
let days = diff.days;
|
||||
let hrs = diff.hours;
|
||||
@@ -65,17 +65,21 @@ define([
|
||||
/**
|
||||
* destroy all active counter recursive
|
||||
*/
|
||||
$.fn.destroyTimestampCounter = function(){
|
||||
$.fn.destroyTimestampCounter = function(recursive){
|
||||
return this.each(function(){
|
||||
let parentElement = $(this);
|
||||
parentElement.find('[data-counter="init"]').each(function(){
|
||||
let element = $(this);
|
||||
let counterSelector = '[data-counter="init"]';
|
||||
let counterElements = element.filter(counterSelector);
|
||||
if(recursive){
|
||||
counterElements = counterElements.add(element.find(counterSelector));
|
||||
}
|
||||
|
||||
counterElements.each(function(){
|
||||
let element = $(this);
|
||||
let interval = element.data('interval');
|
||||
if(interval){
|
||||
clearInterval(interval);
|
||||
element.removeAttr('data-counter')
|
||||
.removeData('interval')
|
||||
.removeClass('stopCounter');
|
||||
element.removeAttr('data-counter').removeData('interval').removeClass('stopCounter');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -102,18 +106,27 @@ define([
|
||||
// show element (if invisible) after first update
|
||||
element.css({'visibility': 'initial'});
|
||||
|
||||
let refreshIntervalId = window.setInterval(function(){
|
||||
// calc ms until next second
|
||||
// -> makes sure all counter update in sync no matter when init
|
||||
let msUntilSecond = 1500 - new Date().getMilliseconds();
|
||||
setTimeout(function(){
|
||||
let refreshIntervalId = window.setInterval(function(){
|
||||
|
||||
// update element with current time
|
||||
if( !element.hasClass('stopCounter')){
|
||||
updateDateDiff(element, date, round);
|
||||
}else{
|
||||
clearInterval( element.data('interval') );
|
||||
}
|
||||
}, 500);
|
||||
// update element with current time
|
||||
if( !element.hasClass('stopCounter')){
|
||||
updateDateDiff(element, date, round);
|
||||
}else{
|
||||
clearInterval( element.data('interval') );
|
||||
}
|
||||
}, 500);
|
||||
|
||||
element.data('interval', refreshIntervalId);
|
||||
element.data('interval', refreshIntervalId);
|
||||
}, msUntilSecond);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
updateDateDiff: updateDateDiff
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,11 +1,41 @@
|
||||
define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'datatables.net',
|
||||
'datatables.net-buttons',
|
||||
'datatables.net-buttons-html',
|
||||
'datatables.net-responsive',
|
||||
'datatables.net-select'
|
||||
], (a, b) => {
|
||||
], ($, Init) => {
|
||||
'use strict';
|
||||
|
||||
// all Datatables stuff is available...
|
||||
let initDefaultDatatablesConfig = () => {
|
||||
|
||||
|
||||
|
||||
$.extend(true, $.fn.dataTable.defaults, {
|
||||
pageLength: -1,
|
||||
pagingType: 'simple_numbers',
|
||||
lengthMenu: [[5, 10, 25, 50, -1], [5, 10, 25, 50, 'All']],
|
||||
order: [], // no default order because columnDefs is empty
|
||||
autoWidth: false,
|
||||
responsive: {
|
||||
breakpoints: Init.breakpoints,
|
||||
details: false
|
||||
},
|
||||
columnDefs: [],
|
||||
data: []
|
||||
});
|
||||
|
||||
// global open event
|
||||
$(document).on('destroy.dt', '.dataTable ', function(e, settings){
|
||||
let table = $(this);
|
||||
|
||||
// remove all active counters in table
|
||||
table.destroyTimestampCounter(true);
|
||||
});
|
||||
};
|
||||
|
||||
initDefaultDatatablesConfig();
|
||||
});
|
||||
@@ -60,10 +60,12 @@ define(['jquery'], ($) => {
|
||||
gitHubReleases: '/api/github/releases' // ajax URL - get release info from GitHub
|
||||
},
|
||||
breakpoints: [
|
||||
{ name: 'desktop', width: Infinity },
|
||||
{ name: 'tablet', width: 1200 },
|
||||
{ name: 'fablet', width: 780 },
|
||||
{ name: 'phone', width: 480 }
|
||||
{ name: 'screen-xl', width: Infinity },
|
||||
{ name: 'screen-l', width: 1600 },
|
||||
{ name: 'screen-m', width: 1200 },
|
||||
{ name: 'screen-d', width: 1000 },
|
||||
{ name: 'screen-s', width: 780 },
|
||||
{ name: 'screen-xs', width: 480 }
|
||||
],
|
||||
animationSpeed: {
|
||||
splashOverlay: 300, // "splash" loading overlay
|
||||
|
||||
@@ -65,7 +65,7 @@ define([
|
||||
* @param connectionsData
|
||||
*/
|
||||
let addConnectionsOverlay = (connections, connectionsData) => {
|
||||
let SystemSignatures = require('app/ui/system_signature');
|
||||
let SystemSignatures = require('app/ui/module/system_signature_new');
|
||||
|
||||
/**
|
||||
* add label to endpoint
|
||||
|
||||
@@ -367,7 +367,7 @@ define([
|
||||
connection &&
|
||||
connectionData.signatures // signature data is required...
|
||||
){
|
||||
let SystemSignatures = require('app/ui/system_signature');
|
||||
let SystemSignatures = require('app/ui/module/system_signature_new');
|
||||
|
||||
let connectionId = connection.getParameter('connectionId');
|
||||
let sourceEndpoint = connection.endpoints[0];
|
||||
@@ -1426,6 +1426,7 @@ define([
|
||||
/**
|
||||
* add a wormhole tooltip with wh specific data to elements
|
||||
* @param tooltipData
|
||||
* @param options
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.addWormholeInfoTooltip = function(tooltipData, options){
|
||||
|
||||
@@ -5,13 +5,14 @@ define([
|
||||
'app/map/map',
|
||||
'app/map/util',
|
||||
'sortable',
|
||||
'app/ui/system_info',
|
||||
'app/ui/system_graph',
|
||||
'app/ui/system_signature',
|
||||
'app/ui/system_route',
|
||||
'app/ui/system_intel',
|
||||
'app/ui/system_killboard',
|
||||
'app/ui/connection_info',
|
||||
'app/ui/module/system_info',
|
||||
'app/ui/module/system_graph',
|
||||
//'app/ui/module/system_signature',
|
||||
'app/ui/module/system_signature_new',
|
||||
'app/ui/module/system_route',
|
||||
'app/ui/module/system_intel',
|
||||
'app/ui/module/system_killboard',
|
||||
'app/ui/module/connection_info',
|
||||
'app/counter'
|
||||
], (
|
||||
$,
|
||||
@@ -180,11 +181,12 @@ define([
|
||||
* @param moduleElement
|
||||
* @param Module
|
||||
* @param callback
|
||||
* @param addSpacer
|
||||
*/
|
||||
let removeModule = (moduleElement, Module, callback, addSpacer) => {
|
||||
if(moduleElement.length > 0){
|
||||
if(typeof Module.beforeReDraw === 'function'){
|
||||
Module.beforeReDraw();
|
||||
if(typeof Module.beforeHide === 'function'){
|
||||
Module.beforeHide(moduleElement);
|
||||
}
|
||||
|
||||
moduleElement.velocity('reverse',{
|
||||
@@ -336,8 +338,6 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
return new Promise(drawModuleExecutor);
|
||||
};
|
||||
|
||||
@@ -539,23 +539,25 @@ define([
|
||||
let clickY = e.pageY - posY;
|
||||
|
||||
// check for top-left click
|
||||
if(clickX <= 8 && clickY <= 8 && clickX >= 0 && clickY >= 0){
|
||||
if(clickX <= 9 && clickY <= 9 && clickX >= 0 && clickY >= 0){
|
||||
|
||||
// remember height
|
||||
if(! moduleElement.data('origHeight')){
|
||||
if( !moduleElement.data('origHeight') ){
|
||||
moduleElement.data('origHeight', moduleElement.outerHeight());
|
||||
}
|
||||
|
||||
if(moduleElement.hasClass( config.moduleClosedClass )){
|
||||
if(moduleElement.hasClass(config.moduleClosedClass)){
|
||||
let moduleHeight = moduleElement.data('origHeight');
|
||||
moduleElement.velocity('finish').velocity({
|
||||
height: [ moduleHeight + 'px', [ 400, 15 ] ]
|
||||
},{
|
||||
duration: 400,
|
||||
easing: 'easeOutSine',
|
||||
complete: function(){
|
||||
moduleElement.removeClass( config.moduleClosedClass );
|
||||
complete: function(moduleElement){
|
||||
moduleElement = $(moduleElement);
|
||||
moduleElement.removeClass(config.moduleClosedClass);
|
||||
moduleElement.removeData('origHeight');
|
||||
moduleElement.css({height: ''});
|
||||
}
|
||||
});
|
||||
}else{
|
||||
@@ -564,8 +566,9 @@ define([
|
||||
},{
|
||||
duration: 400,
|
||||
easing: 'easeOutSine',
|
||||
complete: function(){
|
||||
moduleElement.addClass( config.moduleClosedClass );
|
||||
complete: function(moduleElement){
|
||||
moduleElement = $(moduleElement);
|
||||
moduleElement.addClass(config.moduleClosedClass);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ define([
|
||||
dynamicElementWrapperId: 'pf-dialog-wrapper', // class for container element that holds hidden "context menus"
|
||||
|
||||
// system signature module
|
||||
systemSignatureModuleClass: 'pf-signature-table-module', // module wrapper (signatures)
|
||||
systemSignatureModuleClass: 'pf-system-signature-module', // module wrapper (signatures)
|
||||
systemIntelModuleClass: 'pf-system-intel-module', // module wrapper (intel)
|
||||
};
|
||||
|
||||
@@ -744,7 +744,7 @@ define([
|
||||
// global "modal" callback (for all modals)
|
||||
$('body').on('hide.bs.modal', '> .modal', function(e) {
|
||||
let modalElement = $(this);
|
||||
modalElement.destroyTimestampCounter();
|
||||
modalElement.destroyTimestampCounter(true);
|
||||
|
||||
// destroy all Select2
|
||||
modalElement.find('.' + Util.config.select2Class)
|
||||
|
||||
@@ -321,10 +321,6 @@ define([
|
||||
tooltipElements.tooltip();
|
||||
});
|
||||
|
||||
systemTable.on('destroy.dt', function(){
|
||||
$(this).destroyTimestampCounter();
|
||||
});
|
||||
|
||||
// prepare data for dataTables
|
||||
let systemsData = [];
|
||||
for(let i = 0; i < mapData.data.systems.length; i++){
|
||||
@@ -470,11 +466,6 @@ define([
|
||||
lengthMenu: [[5, 10, 20, 50, -1], [5, 10, 20, 50, 'All']],
|
||||
ordering: true,
|
||||
order: [[ 9, 'desc' ], [ 3, 'asc' ]],
|
||||
autoWidth: false,
|
||||
responsive: {
|
||||
breakpoints: Init.breakpoints,
|
||||
details: false
|
||||
},
|
||||
hover: false,
|
||||
data: systemsData,
|
||||
columnDefs: [],
|
||||
@@ -488,7 +479,7 @@ define([
|
||||
{
|
||||
title: 'type',
|
||||
width: '25px',
|
||||
className: ['min-desktop'].join(' '),
|
||||
className: ['min-screen-l'].join(' '),
|
||||
data: 'type',
|
||||
render: {
|
||||
_: 'type',
|
||||
@@ -506,7 +497,7 @@ define([
|
||||
},{
|
||||
title: 'sec',
|
||||
width: '18px',
|
||||
className: ['text-center', 'min-desktop'].join(' '),
|
||||
className: ['text-center', 'min-screen-l'].join(' '),
|
||||
searchable: false,
|
||||
data: 'trueSec',
|
||||
render: {
|
||||
@@ -516,7 +507,7 @@ define([
|
||||
},{
|
||||
title: '<i class="fas fa-skull" title="shattered" data-toggle="tooltip"></i>',
|
||||
width: '10px',
|
||||
className: ['text-center', 'min-desktop'].join(' '),
|
||||
className: ['text-center', 'min-screen-l'].join(' '),
|
||||
searchable: false,
|
||||
data: 'shattered',
|
||||
render: {
|
||||
@@ -593,7 +584,7 @@ define([
|
||||
title: 'updated',
|
||||
width: '80px',
|
||||
searchable: false,
|
||||
className: ['text-right', config.tableCellCounterClass, 'min-desktop'].join(' '),
|
||||
className: ['text-right', config.tableCellCounterClass, 'min-screen-l'].join(' '),
|
||||
data: 'updated',
|
||||
createdCell: function(cell, cellData, rowData, rowIndex, colIndex){
|
||||
$(cell).initTimestampCounter();
|
||||
@@ -863,11 +854,6 @@ define([
|
||||
lengthMenu: [[5, 10, 20, 50, -1], [5, 10, 20, 50, 'All']],
|
||||
ordering: true,
|
||||
order: [[ 3, 'asc' ]],
|
||||
autoWidth: false,
|
||||
responsive: {
|
||||
breakpoints: Init.breakpoints,
|
||||
details: false
|
||||
},
|
||||
hover: false,
|
||||
data: usersData,
|
||||
language: {
|
||||
@@ -962,7 +948,7 @@ define([
|
||||
width: 26,
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
className: [config.tableCellImageClass, config.tableCellImageSmallClass, 'min-desktop'].join(' '),
|
||||
className: [config.tableCellImageClass, config.tableCellImageSmallClass, 'min-screen-l'].join(' '),
|
||||
data: 'corporation',
|
||||
render: {
|
||||
_: function(data, type, row, meta){
|
||||
@@ -978,7 +964,7 @@ define([
|
||||
title: 'corporation',
|
||||
orderable: true,
|
||||
searchable: true,
|
||||
className: [config.tableCellActionClass, 'min-desktop'].join(' '),
|
||||
className: [config.tableCellActionClass, 'min-screen-l'].join(' '),
|
||||
data: 'corporation',
|
||||
render: {
|
||||
_: function (data, type, row, meta) {
|
||||
@@ -1041,7 +1027,7 @@ define([
|
||||
width: 30,
|
||||
orderable: true,
|
||||
searchable: true,
|
||||
className: ['text-right', 'min-desktop'].join(' '),
|
||||
className: ['text-right', 'min-screen-l'].join(' '),
|
||||
data: 'role',
|
||||
render: {
|
||||
_: function (data, type, row, meta) {
|
||||
|
||||
@@ -654,7 +654,7 @@ define([
|
||||
*/
|
||||
$.fn.initSignatureTypeSelect = function(options, hasOptGroups){
|
||||
let defaultConfig = {
|
||||
minimumResultsForSearch: 6,
|
||||
minimumResultsForSearch: 10,
|
||||
width: '220px',
|
||||
dropdownParent: this.parents('.popover-content')
|
||||
};
|
||||
|
||||
1013
public/js/v1.4.1/app/ui/module/connection_info.js
Normal file
1013
public/js/v1.4.1/app/ui/module/connection_info.js
Normal file
File diff suppressed because it is too large
Load Diff
248
public/js/v1.4.1/app/ui/module/system_graph.js
Normal file
248
public/js/v1.4.1/app/ui/module/system_graph.js
Normal file
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
* 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
|
||||
};
|
||||
|
||||
});
|
||||
419
public/js/v1.4.1/app/ui/module/system_info.js
Normal file
419
public/js/v1.4.1/app/ui/module/system_info.js
Normal file
@@ -0,0 +1,419 @@
|
||||
/**
|
||||
* 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) => {
|
||||
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
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
|
||||
841
public/js/v1.4.1/app/ui/module/system_intel.js
Normal file
841
public/js/v1.4.1/app/ui/module/system_intel.js
Normal file
@@ -0,0 +1,841 @@
|
||||
/**
|
||||
* System intel 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
|
||||
|
||||
// system info module
|
||||
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');
|
||||
|
||||
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-pen"></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.pulseBackgroundColor(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
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* before module destroy callback
|
||||
* @param moduleElement
|
||||
*/
|
||||
let beforeDestroy = moduleElement => {
|
||||
// Destroying the data tables throws
|
||||
// -> safety remove all dataTables
|
||||
let structureTableElement = moduleElement.find('.' + config.systemStructuresTableClass);
|
||||
let tableApi = structureTableElement.DataTable();
|
||||
tableApi.destroy();
|
||||
};
|
||||
|
||||
return {
|
||||
config: config,
|
||||
getModule: getModule,
|
||||
initModule: initModule,
|
||||
updateModule: updateModule,
|
||||
beforeDestroy: beforeDestroy
|
||||
};
|
||||
|
||||
});
|
||||
407
public/js/v1.4.1/app/ui/module/system_killboard.js
Normal file
407
public/js/v1.4.1/app/ui/module/system_killboard.js
Normal file
@@ -0,0 +1,407 @@
|
||||
/**
|
||||
* System killboard module
|
||||
*/
|
||||
|
||||
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) => {
|
||||
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
|
||||
};
|
||||
});
|
||||
1367
public/js/v1.4.1/app/ui/module/system_route.js
Normal file
1367
public/js/v1.4.1/app/ui/module/system_route.js
Normal file
File diff suppressed because it is too large
Load Diff
2512
public/js/v1.4.1/app/ui/module/system_signature.js
Normal file
2512
public/js/v1.4.1/app/ui/module/system_signature.js
Normal file
File diff suppressed because it is too large
Load Diff
2461
public/js/v1.4.1/app/ui/module/system_signature_new.js
Normal file
2461
public/js/v1.4.1/app/ui/module/system_signature_new.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -33,7 +33,6 @@ define([
|
||||
|
||||
// head
|
||||
headMapTrackingId: 'pf-head-map-tracking', // id for "map tracking" toggle (checkbox)
|
||||
headCharacterSwitchId: 'pf-head-character-switch', // id for "character switch" popover
|
||||
headCurrentLocationId: 'pf-head-current-location', // id for "show current location" element
|
||||
|
||||
// menu
|
||||
@@ -66,10 +65,12 @@ define([
|
||||
// animation
|
||||
animationPulseSuccessClass: 'pf-animation-pulse-success', // animation class
|
||||
animationPulseWarningClass: 'pf-animation-pulse-warning', // animation class
|
||||
animationPulseDangerClass: 'pf-animation-pulse-danger', // animation class
|
||||
|
||||
// popover
|
||||
popoverSmallClass: 'pf-popover-small', // class for "small" popover
|
||||
popoverTriggerClass: 'pf-popover-trigger', // class for "popover" trigger elements
|
||||
popoverSmallClass: 'pf-popover-small', // class for small "popover"
|
||||
popoverCharacterClass: 'pf-popover-character', // class for character "popover"
|
||||
|
||||
// help
|
||||
helpDefaultClass: 'pf-help-default', // class for "help" tooltip elements
|
||||
@@ -231,7 +232,7 @@ define([
|
||||
}else{
|
||||
callback(responseData.img);
|
||||
}
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
}).fail(function( jqXHR, status, error){
|
||||
let reason = status + ' ' + error;
|
||||
showNotify({title: jqXHR.status + ': getCaptchaImage', text: reason, type: 'error'});
|
||||
});
|
||||
@@ -424,7 +425,7 @@ define([
|
||||
let width = element.offsetWidth;
|
||||
let height = element.offsetHeight;
|
||||
|
||||
while(element.offsetParent) {
|
||||
while(element.offsetParent){
|
||||
element = element.offsetParent;
|
||||
top += element.offsetTop;
|
||||
left += element.offsetLeft;
|
||||
@@ -494,7 +495,7 @@ define([
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.destroyTooltip = function(recursive){
|
||||
return this.each(function() {
|
||||
return this.each(function(){
|
||||
let element = $(this);
|
||||
let tooltipSelector = '[title]';
|
||||
let tooltipElements = element.filter(tooltipSelector);
|
||||
@@ -502,18 +503,20 @@ define([
|
||||
tooltipElements = tooltipElements.add(element.find(tooltipSelector));
|
||||
}
|
||||
|
||||
tooltipElements.each(function() {
|
||||
tooltipElements.each(function(){
|
||||
$(this).tooltip('destroy');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* adds a popup tooltip with character information (created/updated)
|
||||
* add a popup tooltip with character information (created/updated)
|
||||
* @param tooltipData
|
||||
* @param options
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.addCharacterInfoTooltip = function(tooltipData){
|
||||
let element = $(this);
|
||||
$.fn.addCharacterInfoTooltip = function(tooltipData, options){
|
||||
let data = {};
|
||||
|
||||
if(
|
||||
tooltipData.created.character &&
|
||||
@@ -522,59 +525,60 @@ define([
|
||||
let createdData = tooltipData.created;
|
||||
let updatedData = tooltipData.updated;
|
||||
|
||||
// check if data has changed
|
||||
if(
|
||||
element.data('created') !== createdData.created ||
|
||||
element.data('updated') !== updatedData.updated
|
||||
){
|
||||
// data changed
|
||||
// set new data for next check
|
||||
element.data('created', createdData.created);
|
||||
element.data('updated', updatedData.updated);
|
||||
let statusCreatedClass = getStatusInfoForCharacter(createdData.character, 'class');
|
||||
let statusUpdatedClass = getStatusInfoForCharacter(updatedData.character, 'class');
|
||||
|
||||
let statusCreatedClass = getStatusInfoForCharacter(createdData.character, 'class');
|
||||
let statusUpdatedClass = getStatusInfoForCharacter(updatedData.character, 'class');
|
||||
// convert timestamps
|
||||
let dateCreated = new Date(createdData.created * 1000);
|
||||
let dateUpdated = new Date(updatedData.updated * 1000);
|
||||
let dateCreatedUTC = convertDateToUTC(dateCreated);
|
||||
let dateUpdatedUTC = convertDateToUTC(dateUpdated);
|
||||
|
||||
// convert timestamps
|
||||
let dateCreated = new Date(createdData.created * 1000);
|
||||
let dateUpdated = new Date(updatedData.updated * 1000);
|
||||
let dateCreatedUTC = convertDateToUTC(dateCreated);
|
||||
let dateUpdatedUTC = convertDateToUTC(dateUpdated);
|
||||
|
||||
let data = {
|
||||
created: createdData,
|
||||
updated: updatedData,
|
||||
createdTime: convertDateToString(dateCreatedUTC),
|
||||
updatedTime: convertDateToString(dateUpdatedUTC),
|
||||
createdStatusClass: statusCreatedClass,
|
||||
updatedStatusClass: statusUpdatedClass
|
||||
};
|
||||
|
||||
requirejs(['text!templates/tooltip/character_info.html', 'mustache'], function(template, Mustache) {
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
element.popover({
|
||||
placement: 'top',
|
||||
html: true,
|
||||
trigger: 'hover',
|
||||
content: '',
|
||||
container: 'body',
|
||||
title: 'Created / Updated',
|
||||
delay: {
|
||||
show: 250,
|
||||
hide: 0
|
||||
}
|
||||
});
|
||||
|
||||
// set new popover content
|
||||
let popover = element.data('bs.popover');
|
||||
popover.options.content = content;
|
||||
});
|
||||
|
||||
}
|
||||
data = {
|
||||
popoverClass: config.popoverCharacterClass,
|
||||
ccpImageServerUrl: Init.url.ccpImageServer,
|
||||
created: createdData,
|
||||
updated: updatedData,
|
||||
createdTime: convertDateToString(dateCreatedUTC),
|
||||
updatedTime: convertDateToString(dateUpdatedUTC),
|
||||
createdStatusClass: statusCreatedClass,
|
||||
updatedStatusClass: statusUpdatedClass
|
||||
};
|
||||
}
|
||||
|
||||
return element;
|
||||
let defaultOptions = {
|
||||
placement: 'top',
|
||||
html: true,
|
||||
trigger: 'hover',
|
||||
container: 'body',
|
||||
title: 'Created / Updated',
|
||||
delay: {
|
||||
show: 150,
|
||||
hide: 0
|
||||
}
|
||||
};
|
||||
|
||||
options = $.extend({}, defaultOptions, options);
|
||||
|
||||
return this.each(function(){
|
||||
let element = $(this);
|
||||
|
||||
requirejs(['text!templates/tooltip/character_info.html', 'mustache'], (template, Mustache) => {
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
element.popover(options);
|
||||
|
||||
// set new popover content
|
||||
let popover = element.data('bs.popover');
|
||||
popover.options.content = content;
|
||||
|
||||
if(options.show){
|
||||
element.popover('show');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -585,10 +589,10 @@ define([
|
||||
let elements = $(this);
|
||||
let eventNamespace = 'hideCharacterPopup';
|
||||
|
||||
requirejs(['text!templates/tooltip/character_switch.html', 'mustache'], function (template, Mustache) {
|
||||
requirejs(['text!templates/tooltip/character_switch.html', 'mustache'], function (template, Mustache){
|
||||
|
||||
let data = {
|
||||
id: config.headCharacterSwitchId,
|
||||
popoverClass: config.popoverCharacterClass,
|
||||
browserTabId: getBrowserTabId(),
|
||||
routes: Init.routes,
|
||||
userData: userData,
|
||||
@@ -608,7 +612,7 @@ define([
|
||||
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
return elements.each(function() {
|
||||
return elements.each(function(){
|
||||
let element = $(this);
|
||||
|
||||
// check if popover already exists -> remove it
|
||||
@@ -616,7 +620,7 @@ define([
|
||||
element.off('click').popover('destroy');
|
||||
}
|
||||
|
||||
element.on('click', function(e) {
|
||||
element.on('click', function(e){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
@@ -631,7 +635,7 @@ define([
|
||||
|
||||
if(popoverData === undefined){
|
||||
|
||||
button.on('shown.bs.popover', function (e) {
|
||||
button.on('shown.bs.popover', function (e){
|
||||
let tmpPopupElement = $(this).data('bs.popover').tip();
|
||||
tmpPopupElement.find('.btn').on('click', function(e){
|
||||
// close popover
|
||||
@@ -662,7 +666,7 @@ define([
|
||||
// character switch detected
|
||||
$('body').data('characterSwitch', true);
|
||||
// ... and remove "characterSwitch" data again! after "unload"
|
||||
setTimeout(function() {
|
||||
setTimeout(function(){
|
||||
$('body').removeData('characterSwitch');
|
||||
}, 500);
|
||||
});
|
||||
@@ -690,7 +694,7 @@ define([
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.destroyPopover = function(recursive){
|
||||
return this.each(function() {
|
||||
return this.each(function(){
|
||||
let element = $(this);
|
||||
let popoverSelector = '.' + config.popoverTriggerClass;
|
||||
let popoverElements = element.filter(popoverSelector);
|
||||
@@ -698,7 +702,7 @@ define([
|
||||
popoverElements = popoverElements.add(element.find(popoverSelector));
|
||||
}
|
||||
|
||||
popoverElements.each(function() {
|
||||
popoverElements.each(function(){
|
||||
let popoverElement = $(this);
|
||||
if(popoverElement.data('bs.popover')){
|
||||
popoverElement.popover('destroy');
|
||||
@@ -713,9 +717,9 @@ define([
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.initPopoverClose = function(eventNamespace){
|
||||
return this.each(function() {
|
||||
$('body').off('click.' + eventNamespace).on('click.' + eventNamespace + ' contextmenu', function (e) {
|
||||
$('.' + config.popoverTriggerClass).each(function () {
|
||||
return this.each(function(){
|
||||
$('body').off('click.' + eventNamespace).on('click.' + eventNamespace + ' contextmenu', function (e){
|
||||
$('.' + config.popoverTriggerClass).each(function (){
|
||||
let popoverElement = $(this);
|
||||
//the 'is' for buttons that trigger popups
|
||||
//the 'has' for icons within a button that triggers a popup
|
||||
@@ -743,7 +747,7 @@ define([
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.setPopoverSmall = function(){
|
||||
return this.each(function() {
|
||||
return this.each(function(){
|
||||
let element = $(this);
|
||||
let popover = element.data('bs.popover');
|
||||
if(popover){
|
||||
@@ -760,7 +764,7 @@ define([
|
||||
$.fn.showMessage = function(config){
|
||||
let containerElement = $(this);
|
||||
|
||||
requirejs(['text!templates/form/message.html', 'mustache'], function(template, Mustache) {
|
||||
requirejs(['text!templates/form/message.html', 'mustache'], function(template, Mustache){
|
||||
|
||||
let messageTypeClass = 'alert-danger';
|
||||
let messageTextClass = 'txt-color-danger';
|
||||
@@ -809,7 +813,7 @@ define([
|
||||
* add/remove css class for keyframe animation
|
||||
* @returns {any|JQuery|*}
|
||||
*/
|
||||
$.fn.pulseTableRow = function(status, clear){
|
||||
$.fn.pulseBackgroundColor = function(status, clear){
|
||||
|
||||
let animationClass = '';
|
||||
switch(status){
|
||||
@@ -819,9 +823,12 @@ define([
|
||||
case 'changed':
|
||||
animationClass = config.animationPulseWarningClass;
|
||||
break;
|
||||
case 'deleted':
|
||||
animationClass = config.animationPulseDangerClass;
|
||||
break;
|
||||
}
|
||||
|
||||
let clearTimer = function(element) {
|
||||
let clearTimer = element => {
|
||||
element.removeClass( animationClass );
|
||||
let currentTimer = element.data('animationTimer');
|
||||
|
||||
@@ -841,7 +848,7 @@ define([
|
||||
}
|
||||
|
||||
if(clear !== true){
|
||||
element.addClass( animationClass );
|
||||
element.addClass(animationClass);
|
||||
let timer = setTimeout(clearTimer, 1500, element);
|
||||
element.data('animationTimer', timer);
|
||||
animationTimerCache[timer] = true;
|
||||
@@ -902,14 +909,14 @@ define([
|
||||
|
||||
const prepareSafeListener = (listener, passive) => {
|
||||
if (!passive) return listener;
|
||||
return function (e) {
|
||||
return function (e){
|
||||
e.preventDefault = () => {};
|
||||
return listener.call(this, e);
|
||||
};
|
||||
};
|
||||
|
||||
const overwriteAddEvent = (superMethod) => {
|
||||
EventTarget.prototype.addEventListener = function (type, listener, options) { // jshint ignore:line
|
||||
EventTarget.prototype.addEventListener = function (type, listener, options){ // jshint ignore:line
|
||||
const usesListenerOptions = typeof options === 'object';
|
||||
const useCapture = usesListenerOptions ? options.capture : options;
|
||||
|
||||
@@ -927,20 +934,20 @@ define([
|
||||
|
||||
try {
|
||||
const opts = Object.defineProperty({}, 'passive', {
|
||||
get() {
|
||||
get(){
|
||||
supported = true;
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('test', null, opts);
|
||||
window.removeEventListener('test', null, opts);
|
||||
} catch (e) {}
|
||||
} catch (e){}
|
||||
|
||||
return supported;
|
||||
};
|
||||
|
||||
let supportsPassive = eventListenerOptionsSupported ();
|
||||
if (supportsPassive) {
|
||||
if (supportsPassive){
|
||||
const addEvent = EventTarget.prototype.addEventListener; // jshint ignore:line
|
||||
overwriteAddEvent(addEvent);
|
||||
}
|
||||
@@ -953,8 +960,8 @@ define([
|
||||
// Array diff
|
||||
// [1,2,3,4,5,6].diff( [3,4,5] );
|
||||
// => [1, 2, 6]
|
||||
Array.prototype.diff = function(a) {
|
||||
return this.filter(function(i) {return a.indexOf(i) < 0;});
|
||||
Array.prototype.diff = function(a){
|
||||
return this.filter(function(i){return a.indexOf(i) < 0;});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -962,7 +969,7 @@ define([
|
||||
* @param p
|
||||
* @returns {Array.<T>}
|
||||
*/
|
||||
Array.prototype.sortBy = function(p) {
|
||||
Array.prototype.sortBy = function(p){
|
||||
return this.slice(0).sort((a,b) => {
|
||||
return (a[p] > b[p]) ? 1 : (a[p] < b[p]) ? -1 : 0;
|
||||
});
|
||||
@@ -972,10 +979,10 @@ define([
|
||||
* get hash from string
|
||||
* @returns {number}
|
||||
*/
|
||||
String.prototype.hashCode = function() {
|
||||
String.prototype.hashCode = function(){
|
||||
let hash = 0, i, chr;
|
||||
if (this.length === 0) return hash;
|
||||
for (i = 0; i < this.length; i++) {
|
||||
for (i = 0; i < this.length; i++){
|
||||
chr = this.charCodeAt(i);
|
||||
hash = ((hash << 5) - hash) + chr;
|
||||
hash |= 0; // Convert to 32bit integer
|
||||
@@ -1094,6 +1101,12 @@ define([
|
||||
if(resultsWrapper){
|
||||
resultsWrapper.mCustomScrollbar('destroy');
|
||||
}
|
||||
|
||||
// select2 sets :focus to the select2 <input> field. This is bad!
|
||||
// we want to keep the focus where it is (e.g. signature table cell)
|
||||
// the only way to prevent this is to remove the element
|
||||
// https://stackoverflow.com/questions/17995057/prevent-select2-from-autmatically-focussing-its-search-input-when-dropdown-is-op
|
||||
$(this).parents('.editableform').find(this).next().find('.select2-selection').remove();
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1262,7 +1275,7 @@ define([
|
||||
// line breaks are 2 characters!
|
||||
let newLines = value.match(/(\r\n|\n|\r)/g);
|
||||
let addition = 0;
|
||||
if (newLines != null) {
|
||||
if(newLines != null){
|
||||
addition = newLines.length;
|
||||
}
|
||||
inputLength += addition;
|
||||
@@ -1300,7 +1313,7 @@ define([
|
||||
* stop browser tab title "blinking"
|
||||
*/
|
||||
let stopTabBlink = function(){
|
||||
requirejs(['notification'], function(Notification) {
|
||||
requirejs(['notification'], function(Notification){
|
||||
Notification.stopTabBlink();
|
||||
});
|
||||
};
|
||||
@@ -1388,7 +1401,7 @@ define([
|
||||
*/
|
||||
let ajaxSetup = () => {
|
||||
$.ajaxSetup({
|
||||
beforeSend: function(jqXHR, settings) {
|
||||
beforeSend: function(jqXHR, settings){
|
||||
// store request URL for later use (e.g. in error messages)
|
||||
jqXHR.url = location.protocol + '//' + location.host + settings.url;
|
||||
|
||||
@@ -1579,11 +1592,13 @@ define([
|
||||
};
|
||||
|
||||
/**
|
||||
* get Area ID by security string
|
||||
* get areaId by security string
|
||||
* areaId is required as a key for signature names
|
||||
* if areaId is 0, no signature data is available for this system
|
||||
* @param security
|
||||
* @returns {number}
|
||||
*/
|
||||
let getAreaIdBySecurity = (security) => {
|
||||
let getAreaIdBySecurity = security => {
|
||||
let areaId = 0;
|
||||
switch(security){
|
||||
case 'H':
|
||||
@@ -1646,7 +1661,6 @@ define([
|
||||
* @returns {string}
|
||||
*/
|
||||
let getStatusInfoForCharacter = (characterData, option) => {
|
||||
|
||||
let statusInfo = '';
|
||||
|
||||
// character status can not be checked if there are no reference data
|
||||
@@ -1898,20 +1912,17 @@ define([
|
||||
/**
|
||||
* get signature group information
|
||||
* @param option
|
||||
* @returns {{}}
|
||||
* @returns {Array}
|
||||
*/
|
||||
let getSignatureGroupInfo = function(option){
|
||||
|
||||
let groupInfo = {};
|
||||
|
||||
for (let prop in Init.signatureGroups) {
|
||||
if(Init.signatureGroups.hasOwnProperty(prop)){
|
||||
prop = parseInt(prop);
|
||||
groupInfo[prop] = Init.signatureGroups[prop][option];
|
||||
}
|
||||
let getSignatureGroupOptions = option => {
|
||||
let options = [];
|
||||
for(let [key, data] of Object.entries(Init.signatureGroups)){
|
||||
options.push({
|
||||
value: parseInt(key),
|
||||
text: data[option]
|
||||
});
|
||||
}
|
||||
|
||||
return groupInfo;
|
||||
return options;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1943,28 +1954,22 @@ define([
|
||||
* @param name
|
||||
* @returns {number}
|
||||
*/
|
||||
let getSignatureTypeIdByName = function(systemData, sigGroupId, name){
|
||||
|
||||
let getSignatureTypeIdByName = (systemData, sigGroupId, name) => {
|
||||
let signatureTypeId = 0;
|
||||
|
||||
let areaId = getAreaIdBySecurity(systemData.security);
|
||||
|
||||
if(areaId > 0){
|
||||
let signatureNames = getAllSignatureNames(systemData.type.id, areaId, sigGroupId );
|
||||
let signatureNames = getAllSignatureNames(systemData.type.id, areaId, sigGroupId);
|
||||
name = name.toLowerCase();
|
||||
|
||||
for(let prop in signatureNames) {
|
||||
|
||||
for(let prop in signatureNames){
|
||||
if(
|
||||
signatureNames.hasOwnProperty(prop) &&
|
||||
signatureNames[prop].toLowerCase() === name
|
||||
){
|
||||
signatureTypeId = parseInt( prop );
|
||||
signatureTypeId = parseInt(prop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return signatureTypeId;
|
||||
};
|
||||
|
||||
@@ -1995,9 +2000,8 @@ define([
|
||||
* to keep the data always up2data
|
||||
* @param mapUserData
|
||||
*/
|
||||
let setCurrentMapUserData = (mapUserData) => {
|
||||
let setCurrentMapUserData = mapUserData => {
|
||||
Init.currentMapUserData = mapUserData;
|
||||
|
||||
return getCurrentMapUserData();
|
||||
};
|
||||
|
||||
@@ -2006,7 +2010,7 @@ define([
|
||||
* @param mapId
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let getCurrentMapUserData = (mapId) => {
|
||||
let getCurrentMapUserData = mapId => {
|
||||
let currentMapUserData = false;
|
||||
|
||||
if(Init.currentMapUserData){
|
||||
@@ -2041,7 +2045,7 @@ define([
|
||||
* @param mapId
|
||||
* @returns {boolean|int}
|
||||
*/
|
||||
let getCurrentMapUserDataIndex = (mapId) => {
|
||||
let getCurrentMapUserDataIndex = mapId => {
|
||||
return getDataIndexByMapId(Init.currentMapUserData, mapId);
|
||||
};
|
||||
|
||||
@@ -2049,7 +2053,7 @@ define([
|
||||
* update cached mapUserData for a single map
|
||||
* @param mapUserData
|
||||
*/
|
||||
let updateCurrentMapUserData = (mapUserData) => {
|
||||
let updateCurrentMapUserData = mapUserData => {
|
||||
let mapUserDataIndex = getCurrentMapUserDataIndex( mapUserData.config.id );
|
||||
|
||||
if( !Array.isArray(Init.currentMapUserData) ){
|
||||
@@ -2072,7 +2076,7 @@ define([
|
||||
* to keep the data always up2data
|
||||
* @param mapData
|
||||
*/
|
||||
let setCurrentMapData = (mapData) => {
|
||||
let setCurrentMapData = mapData => {
|
||||
Init.currentMapData = mapData;
|
||||
|
||||
return getCurrentMapData();
|
||||
@@ -2083,7 +2087,7 @@ define([
|
||||
* @param mapId
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let getCurrentMapData = (mapId) => {
|
||||
let getCurrentMapData = mapId => {
|
||||
let currentMapData = false;
|
||||
|
||||
if( mapId === parseInt(mapId, 10) ){
|
||||
@@ -2107,7 +2111,7 @@ define([
|
||||
* @param mapId
|
||||
* @returns {boolean|int}
|
||||
*/
|
||||
let getCurrentMapDataIndex = (mapId) => {
|
||||
let getCurrentMapDataIndex = mapId => {
|
||||
return getDataIndexByMapId(Init.currentMapData, mapId);
|
||||
};
|
||||
|
||||
@@ -2115,7 +2119,7 @@ define([
|
||||
* update cached mapData for a single map
|
||||
* @param mapData
|
||||
*/
|
||||
let updateCurrentMapData = (mapData) => {
|
||||
let updateCurrentMapData = mapData => {
|
||||
let mapDataIndex = getCurrentMapDataIndex( mapData.config.id );
|
||||
|
||||
if(mapDataIndex !== false){
|
||||
@@ -2146,7 +2150,7 @@ define([
|
||||
* delete map data by mapId from currentMapData
|
||||
* @param mapId
|
||||
*/
|
||||
let deleteCurrentMapData = (mapId) => {
|
||||
let deleteCurrentMapData = mapId => {
|
||||
Init.currentMapData = Init.currentMapData.filter((mapData) => {
|
||||
return (mapData.config.id !== mapId);
|
||||
});
|
||||
@@ -2176,7 +2180,7 @@ define([
|
||||
* @param option
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let getCurrentUserInfo = (option) => {
|
||||
let getCurrentUserInfo = option => {
|
||||
let currentUserData = getCurrentUserData();
|
||||
let userInfo = false;
|
||||
|
||||
@@ -2297,7 +2301,7 @@ define([
|
||||
characterData = characterData.filter(function(tmpCharacterData, index, allData){
|
||||
let keepData = true;
|
||||
|
||||
for(let tmpJump in data) {
|
||||
for(let tmpJump in data){
|
||||
// just scan systems with > jumps than current system
|
||||
if(tmpJump > jumps){
|
||||
let filteredFinalData = data[tmpJump].filter(filterFinalCharData, tmpCharacterData);
|
||||
@@ -2325,7 +2329,7 @@ define([
|
||||
}
|
||||
|
||||
jumps++;
|
||||
for(let prop in nearBySystems.tree) {
|
||||
for(let prop in nearBySystems.tree){
|
||||
if( nearBySystems.tree.hasOwnProperty(prop) ){
|
||||
let tmpSystemData = nearBySystems.tree[prop];
|
||||
data = getNearByCharacterData(tmpSystemData, userData, jumps, data);
|
||||
@@ -2374,7 +2378,7 @@ define([
|
||||
responseData.systemData &&
|
||||
responseData.systemData.length > 0
|
||||
){
|
||||
for (let j = 0; j < responseData.systemData.length; j++) {
|
||||
for (let j = 0; j < responseData.systemData.length; j++){
|
||||
showNotify({title: this.description, text: 'System: ' + responseData.systemData[j].name, type: 'success'});
|
||||
}
|
||||
}
|
||||
@@ -2388,7 +2392,7 @@ define([
|
||||
}
|
||||
}
|
||||
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
}).fail(function( jqXHR, status, error){
|
||||
let reason = status + ' ' + error;
|
||||
showNotify({title: jqXHR.status + ': ' + this.description, text: reason, type: 'warning'});
|
||||
});
|
||||
@@ -2452,7 +2456,7 @@ define([
|
||||
}else{
|
||||
showNotify({title: 'Open window in client', text: 'Check your EVE client', type: 'success'});
|
||||
}
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
}).fail(function( jqXHR, status, error){
|
||||
let reason = status + ' ' + error;
|
||||
showNotify({title: jqXHR.status + ': openWindow', text: reason, type: 'error'});
|
||||
});
|
||||
@@ -2585,9 +2589,9 @@ define([
|
||||
|
||||
element.off(eventName).on(eventName, function(e){
|
||||
clicks++;
|
||||
if (clicks === 1) {
|
||||
if (clicks === 1){
|
||||
setTimeout(element => {
|
||||
if(clicks === 1) {
|
||||
if(clicks === 1){
|
||||
singleClickCallback.call(element, e);
|
||||
} else {
|
||||
doubleClickCallback.call(element, e);
|
||||
@@ -2666,7 +2670,7 @@ define([
|
||||
if(data.reroute){
|
||||
redirect(data.reroute, ['logout']);
|
||||
}
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
}).fail(function( jqXHR, status, error){
|
||||
let reason = status + ' ' + error;
|
||||
showNotify({title: jqXHR.status + ': logout', text: reason, type: 'error'});
|
||||
});
|
||||
@@ -2709,13 +2713,13 @@ define([
|
||||
let name = cname + '=';
|
||||
let ca = document.cookie.split(';');
|
||||
|
||||
for(let i = 0; i <ca.length; i++) {
|
||||
for(let i = 0; i <ca.length; i++){
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) === ' ') {
|
||||
while (c.charAt(0) === ' '){
|
||||
c = c.substring(1);
|
||||
}
|
||||
|
||||
if (c.indexOf(name) === 0) {
|
||||
if (c.indexOf(name) === 0){
|
||||
return c.substring(name.length,c.length);
|
||||
}
|
||||
}
|
||||
@@ -2757,7 +2761,7 @@ define([
|
||||
getSecurityClassForSystem: getSecurityClassForSystem,
|
||||
getTrueSecClassForSystem: getTrueSecClassForSystem,
|
||||
getStatusInfoForSystem: getStatusInfoForSystem,
|
||||
getSignatureGroupInfo: getSignatureGroupInfo,
|
||||
getSignatureGroupOptions: getSignatureGroupOptions,
|
||||
getAllSignatureNames: getAllSignatureNames,
|
||||
getSignatureTypeIdByName: getSignatureTypeIdByName,
|
||||
getAreaIdBySecurity: getAreaIdBySecurity,
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<label class="col-sm-3 control-label">Username</label>
|
||||
<div class="col-sm-9">
|
||||
<p class="form-control-static">
|
||||
<i class="fas fa-fw fa-lg fa-pencil-alt pull-right pf-dialog-icon-button collapsed" data-toggle="collapse" data-target="#collapseUsername" aria-expanded="false" aria-controls="collapseUsername"></i>
|
||||
<i class="fas fa-fw fa-lg fa-pen pull-right pf-dialog-icon-button collapsed" data-toggle="collapse" data-target="#collapseUsername" aria-expanded="false" aria-controls="collapseUsername"></i>
|
||||
{{userData.name}}
|
||||
</p>
|
||||
</div>
|
||||
@@ -68,7 +68,7 @@
|
||||
<label class="col-sm-3 control-label">Email</label>
|
||||
<div class="col-sm-9">
|
||||
<p class="form-control-static">
|
||||
<i class="fas fa-fw fa-lg fa-pencil-alt pull-right pf-dialog-icon-button collapsed" data-toggle="collapse" data-target="#collapseEmail" aria-expanded="false" aria-controls="collapseEmail"></i>
|
||||
<i class="fas fa-fw fa-lg fa-pen pull-right pf-dialog-icon-button collapsed" data-toggle="collapse" data-target="#collapseEmail" aria-expanded="false" aria-controls="collapseEmail"></i>
|
||||
{{#userData.email}}
|
||||
{{userData.email}}
|
||||
{{/userData.email}}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<form role="form" class="form-horizontal">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<div class="form-group" style="margin-bottom: 0;">
|
||||
<label class="col-sm-2 control-label" for="form_result">Scan result</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea style="resize: vertical" rows="3" id="form_result" name="clipboard" class="form-control custom-scroll" autofocus></textarea>
|
||||
<span class="help-block">
|
||||
Copy and paste signatures from your probe scanning window.
|
||||
Hit <kbd>ctrl</kbd> + <kbd>c</kbd> (copy)
|
||||
then <kbd>ctrl</kbd> + <kbd>v</kbd> (paste). This tool can add and update signatures.
|
||||
Copy and paste signatures from your probe scanning window.<br>
|
||||
Hit <kbd>ctrl</kbd> + <kbd>c</kbd> (copy) then <kbd>ctrl</kbd> + <kbd>v</kbd> (paste).
|
||||
This tool can add and update signatures.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<div class="form-group" style="margin-bottom: 0;">
|
||||
<div class="col-sm-offset-2 col-sm-10 col-xs-9">
|
||||
<div class="checkbox checkbox-warning">
|
||||
<input id="form_delete" name="deleteOld" value="1" type="checkbox">
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
{{! info text ================================================================================================ }}
|
||||
<div class="col-xs-12 col-sm-7">
|
||||
<div class="pf-dynamic-area pf-system-info-description-area">
|
||||
<i class="fas fa-fw fa-lg fa-pencil-alt pull-right pf-module-icon-button {{descriptionButtonClass}}" data-toggle="tooltip" data-container="body" title="edit description"></i>
|
||||
<i class="fas fa-fw fa-lg fa-pen pull-right pf-module-icon-button {{descriptionButtonClass}}" data-toggle="tooltip" data-container="body" title="edit description"></i>
|
||||
|
||||
<div class="{{tableToolsActionClass}}">
|
||||
<a href="#" class="{{descriptionTextareaClass}}"></a>
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
<div class="pf-popover">
|
||||
|
||||
<img class="pull-right" src="//image.eveonline.com/Character/{{created.character.id}}_32.jpg">
|
||||
|
||||
<h6>
|
||||
<small>
|
||||
<i class="fas fa-fw fa-circle pf-user-status {{createdStatusClass}}"></i>
|
||||
</small> {{created.character.name}}
|
||||
</h6>
|
||||
|
||||
|
||||
<div class="well well-sm text-center">
|
||||
{{createdTime}}
|
||||
</div>
|
||||
|
||||
<div style="height: 1px"> </div>
|
||||
|
||||
<img class="pull-right" src="//image.eveonline.com/Character/{{updated.character.id}}_32.jpg">
|
||||
|
||||
<h6>
|
||||
<small>
|
||||
<i class="fas fa-fw fa-circle pf-user-status {{updatedStatusClass}}"></i>
|
||||
</small> {{updated.character.name}}
|
||||
</h6>
|
||||
|
||||
|
||||
<div class="well well-sm text-center">
|
||||
{{updatedTime}}
|
||||
</div>
|
||||
<div class="{{popoverClass}}">
|
||||
<table class="table table-condensed">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<img src="{{ccpImageServerUrl}}/Character/{{created.character.id}}_32.jpg" alt="{{created.character.name}}">
|
||||
</td>
|
||||
<td>
|
||||
<i class="fas fa-fw fa-circle pf-user-status {{createdStatusClass}}"></i>
|
||||
{{created.character.name}}
|
||||
</td>
|
||||
<td>
|
||||
<div class="well well-sm text-center"><i class="fas fa-fw fa-plus"></i> {{createdTime}}</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<img src="{{ccpImageServerUrl}}/Character/{{updated.character.id}}_32.jpg" alt="{{updated.character.name}}">
|
||||
</td>
|
||||
<td>
|
||||
<i class="fas fa-fw fa-circle pf-user-status {{updatedStatusClass}}"></i>
|
||||
{{updated.character.name}}
|
||||
</td>
|
||||
<td>
|
||||
<div class="well well-sm text-center"><i class="fas fa-fw fa-pen"></i> {{updatedTime}}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<table id="{{id}}" class="table table-condensed">
|
||||
<tbody>
|
||||
<div class="{{popoverClass}}">
|
||||
<table class="table table-condensed">
|
||||
<tbody>
|
||||
{{#otherCharacters}}
|
||||
<tr>
|
||||
<td><img src="{{image}}" alt="{{name}}"></td>
|
||||
<td>{{name}}</td>
|
||||
<td class="text-right text-nowrap">
|
||||
<a class="btn btn-sm btn-default" href="{{routes.ssoLogin}}?characterId={{id}}" target="_blank" title="new tab" rel="noopener">
|
||||
<i class="fas fa-fw fa-external-link-alt"></i>
|
||||
</a>
|
||||
<a class="btn btn-sm btn-primary" href="{{routes.ssoLogin}}?characterId={{id}}&tabId={{browserTabId}}" target="_self" title="switch character">
|
||||
<i class="fas fa-fw fa-exchange-alt"></i>
|
||||
</a>
|
||||
<a class="btn btn-sm btn-default" href="{{routes.ssoLogin}}?characterId={{id}}" target="_blank" title="new tab" rel="noopener">
|
||||
<i class="fas fa-fw fa-external-link-alt"></i>
|
||||
</a>
|
||||
<a class="btn btn-sm btn-primary" href="{{routes.ssoLogin}}?characterId={{id}}&tabId={{browserTabId}}" target="_self" title="switch character">
|
||||
<i class="fas fa-fw fa-exchange-alt"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{{/otherCharacters}}
|
||||
@@ -24,5 +25,6 @@
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -29,6 +29,6 @@
|
||||
border-radius: $border-radius-large;
|
||||
}
|
||||
.well-sm {
|
||||
padding: 9px;
|
||||
padding: 7px;
|
||||
border-radius: $border-radius-small;
|
||||
}
|
||||
|
||||
@@ -69,6 +69,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
.pf-animation-pulse-danger{
|
||||
@include animation( pulseBackgroundDanger 1s 1 );
|
||||
@include animation-timing-function( cubic-bezier(0.53, -0.03, 0.68, 0.38) );
|
||||
|
||||
.sorting_1{
|
||||
@include animation( pulseBackgroundDangerActive 1s 1 );
|
||||
@include animation-timing-function( cubic-bezier(0.53, -0.03, 0.68, 0.38) );
|
||||
}
|
||||
}
|
||||
|
||||
@include keyframes(pulseBackgroundSuccess){
|
||||
0% {}
|
||||
10% {
|
||||
@@ -103,6 +113,23 @@
|
||||
100% {}
|
||||
};
|
||||
|
||||
@include keyframes(pulseBackgroundDanger){
|
||||
0% {}
|
||||
10% {
|
||||
background-color: $red;
|
||||
color: $gray-darker;
|
||||
}
|
||||
100% {}
|
||||
};
|
||||
@include keyframes(pulseBackgroundDangerActive){
|
||||
0% {}
|
||||
10% {
|
||||
background-color: darken($red, 5%);
|
||||
color: $gray-darker;
|
||||
}
|
||||
100% {}
|
||||
};
|
||||
|
||||
// rotate =========================================================================================
|
||||
.pf-animate-rotate{
|
||||
@include transition( all 0.08s linear );
|
||||
|
||||
@@ -167,6 +167,11 @@ a{
|
||||
|
||||
// form fields custom styles ======================================================================
|
||||
.editable-input{
|
||||
|
||||
.pf-editable-name{
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
optgroup[label]{
|
||||
background-color: $gray;
|
||||
color: $gray-light;
|
||||
@@ -292,11 +297,23 @@ select:active, select:hover {
|
||||
|
||||
// "special" column styles
|
||||
td{
|
||||
&:focus-within{
|
||||
|
||||
&.editable-disabled:focus{
|
||||
// disabled xEditable td´s should not get focus style
|
||||
// -> "pointer-events = none" would be nicer but does not work because "mousedown" should work -> select row function
|
||||
outline: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
&.editable-click:not(.editable-disabled){
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:focus, &.editable-open{
|
||||
// set td as :focus even is td content is focused
|
||||
outline: 1px solid $orange-dark;
|
||||
background-color: rgba($orange-dark, .08) !important;
|
||||
outline-offset: -1px;
|
||||
background-color: rgba($orange-dark, .08);
|
||||
}
|
||||
|
||||
> .fa-circle{
|
||||
@@ -691,7 +708,7 @@ table{
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-style: solid;
|
||||
border-width: 0 0 8px 8px;
|
||||
border-width: 0 0 9px 9px;
|
||||
border-color: transparent transparent transparent $gray;
|
||||
cursor: ns-resize;
|
||||
}
|
||||
@@ -1340,18 +1357,6 @@ code {
|
||||
}
|
||||
}
|
||||
|
||||
// character switch popover
|
||||
#pf-head-character-switch{
|
||||
td{
|
||||
border: none;
|
||||
|
||||
&:first-child + td{
|
||||
// 2nd column
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// footer (map) ===================================================================================
|
||||
#pf-footer{
|
||||
position: absolute;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
// image in popover
|
||||
img{
|
||||
@include border-radius(5px);
|
||||
@include border-radius(3px);
|
||||
}
|
||||
|
||||
h4{
|
||||
@@ -103,4 +103,20 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// character popover --------------------------------------------------------------------------------------------------
|
||||
.pf-popover-character{
|
||||
.table>tbody>tr>td{
|
||||
border: none;
|
||||
|
||||
&:first-child + td{
|
||||
// 2nd column
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.well{
|
||||
margin-bottom: 0; // overwrite default
|
||||
}
|
||||
}
|
||||
@@ -31,8 +31,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
// signature table module ==================================================
|
||||
.pf-signature-table-module{
|
||||
// system signature module ==================================================
|
||||
.pf-system-signature-module{
|
||||
|
||||
.progress-label-right{
|
||||
margin-right: 20px;
|
||||
@@ -61,17 +61,8 @@
|
||||
.pf-sig-table{
|
||||
font-size: 10px;
|
||||
|
||||
.pf-sig-table-edit-desc-text{
|
||||
white-space: normal;
|
||||
|
||||
&.editable-empty{
|
||||
border-bottom: none;
|
||||
@extend .pf-dialog-icon-button;
|
||||
}
|
||||
}
|
||||
|
||||
.fa-plus{
|
||||
@extend .pf-dialog-icon-button;
|
||||
.pf-sig-table-edit-name-input{
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
// textarea field
|
||||
@@ -95,8 +86,8 @@
|
||||
padding: 3px 6px;
|
||||
}
|
||||
|
||||
.pf-sig-table-edit-name-input{
|
||||
text-transform: uppercase;
|
||||
.fa-plus{
|
||||
@extend .pf-dialog-icon-button;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,15 +24,16 @@ table.dataTable thead th.sorting_desc:after {
|
||||
|
||||
table.dataTable thead th.sorting:after {
|
||||
content: "\f0dc";
|
||||
color: $green;
|
||||
font-size: 0.8em;
|
||||
margin-top: -8px;
|
||||
}
|
||||
table.dataTable thead th.sorting_asc:after {
|
||||
content: "\f0de";
|
||||
color: $green;
|
||||
}
|
||||
table.dataTable thead th.sorting_desc:after {
|
||||
content: "\f0dd";
|
||||
color: $green;
|
||||
}
|
||||
|
||||
div.dataTables_scrollBody table.dataTable thead th.sorting:after,
|
||||
|
||||
@@ -57,11 +57,10 @@
|
||||
height: 25px;
|
||||
width: auto;
|
||||
min-width: 25px;
|
||||
text-align: center;
|
||||
|
||||
i {
|
||||
margin-top: 10px;
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.editable-inline .editableform-loading {
|
||||
|
||||
Reference in New Issue
Block a user