- UI improvements Signature table module (new <select> fields), #629

- UI improvements Signature table module (new keyboard navigation), closed #266
This commit is contained in:
Mark Friedrich
2018-08-06 22:23:43 +02:00
parent 31e9201e00
commit 1c15b573b9
33 changed files with 849 additions and 323 deletions

View File

@@ -228,8 +228,8 @@ define(['jquery'], ($) => {
5: { // Wormhole
// no *wandering* w-space -> w-space
// all holes are statics or K162
1: 'S047 - HS',
2: 'N290 - LS',
1: 'S047 - H',
2: 'N290 - L',
3: 'K329 - 0.0'
},
6: { // ORE
@@ -271,8 +271,8 @@ define(['jquery'], ($) => {
9: 'Vital Core Reservoir' //*
},
5: { // Wormhole
1: 'D792 - HS',
2: 'C140 - LS',
1: 'D792 - H',
2: 'C140 - L',
3: 'Z142 - 0.0'
},
6: { // ORE
@@ -318,10 +318,10 @@ define(['jquery'], ($) => {
9: 'Vital Core Reservoir' //*
},
5: { // Wormhole
1: 'B520 - HS',
2: 'D792 - HS',
3: 'C140 - LS',
4: 'C391 - LS',
1: 'B520 - H',
2: 'D792 - H',
3: 'C140 - L',
4: 'C391 - L',
5: 'C248 - 0.0',
6: 'Z142 - 0.0'
},
@@ -356,15 +356,15 @@ define(['jquery'], ($) => {
16: 'U574 - C6',
17: 'V753 - C6',
18: 'W237 - C6',
19: 'B274 - HS',
20: 'D792 - HS',
21: 'D845 - HS',
22: 'N110 - HS',
23: 'A239 - LS',
24: 'C391 - LS',
25: 'J244 - LS',
26: 'U201 - LS', // ??
27: 'U210 - LS',
19: 'B274 - H',
20: 'D792 - H',
21: 'D845 - H',
22: 'N110 - H',
23: 'A239 - L',
24: 'C391 - L',
25: 'J244 - L',
26: 'U201 - L', // ??
27: 'U210 - L',
28: 'C248 - 0.0',
29: 'E545 - 0.0',
30: 'K346 - 0.0',
@@ -381,8 +381,8 @@ define(['jquery'], ($) => {
4: 'O128 - C4',
5: 'M555 - C5',
6: 'B041 - C6',
7: 'A641 - HS',
8: 'R051 - LS',
7: 'A641 - H',
8: 'R051 - L',
9: 'V283 - 0.0',
10: 'T458 - Thera'
}
@@ -395,8 +395,8 @@ define(['jquery'], ($) => {
4: 'O128 - C4',
5: 'N432 - C5',
6: 'U319 - C6',
7: 'B449 - HS',
8: 'N944 - LS',
7: 'B449 - H',
8: 'N944 - L',
9: 'S199 - 0.0',
10: 'M164 - Thera'
}
@@ -409,8 +409,8 @@ define(['jquery'], ($) => {
4: 'O128 - C4',
5: 'N432 - C5',
6: 'U319 - C6',
7: 'B449 - HS',
8: 'N944 - LS',
7: 'B449 - H',
8: 'N944 - L',
9: 'S199 - 0.0',
10: 'L031 - Thera'
}

View File

@@ -406,7 +406,7 @@ define(['jquery'], ($) => {
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
8: 'A009 - SH'
},
2: { // C2
1: 'E004 - C1',
@@ -416,7 +416,7 @@ define(['jquery'], ($) => {
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
8: 'A009 - SH'
},
3: { // C3
1: 'E004 - C1',
@@ -426,7 +426,7 @@ define(['jquery'], ($) => {
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
8: 'A009 - SH'
},
4: { // C4
1: 'E004 - C1',
@@ -436,7 +436,7 @@ define(['jquery'], ($) => {
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
8: 'A009 - SH'
},
5: { // C5
1: 'E004 - C1',
@@ -446,7 +446,7 @@ define(['jquery'], ($) => {
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
8: 'A009 - SH'
},
6: { // C6
1: 'E004 - C1',
@@ -456,7 +456,7 @@ define(['jquery'], ($) => {
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
8: 'A009 - SH'
},
13: { // Shattered Wormholes (some of them are static)
1: 'E004 - C1',
@@ -466,7 +466,7 @@ define(['jquery'], ($) => {
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
8: 'A009 - SH'
}
},
// incoming wormholes
@@ -474,8 +474,8 @@ define(['jquery'], ($) => {
1: 'K162 - C1/2/3 (unknown)',
2: 'K162 - C4/5 (dangerous)',
3: 'K162 - C6 (deadly)',
4: 'K162 - HS',
5: 'K162 - LS',
4: 'K162 - H',
5: 'K162 - L',
6: 'K162 - 0.0',
7: 'K162 - Thera'
}

View File

@@ -1,6 +1,6 @@
define([
'jquery'
], function($) {
], ($) => {
'use strict';
let allCombo = {
@@ -31,12 +31,17 @@ define([
keyNames: ['CONTROL', 'V'],
alias: 'paste'
},
newSignature: {
group: 'signatures',
label: 'New Signature',
keyNames: ['ALT', '3']
},
// map ----------------------------------------------------------------------------------------------
mapSystemAdd: {
group: 'map',
label: 'Add new system',
keyNames: ['CONTROL', 'S']
label: 'New system',
keyNames: ['ALT', '2']
},
mapSystemsSelect: {
group: 'map',
@@ -409,19 +414,18 @@ define([
/**
* get a array with all available shortcut groups and their events
* @returns {Array}
* @returns {any[]}
*/
let getGroupedShortcuts = () => {
let result = $.extend(true, {}, groups);
// add combos and events to groups
let allEntries = [allCombo, allEvents];
for(let i = 0; i < allEntries.length; i++){
for(let event in allEntries[i]){
let data = allEntries[i][event];
for(let entries of allEntries){
for(let [event, data] of Object.entries(entries)){
//format keyNames for UI
let keyNames = data.keyNames.map( (key) => {
let keyNames = data.keyNames.map(key => {
if(key === 'CONTROL'){
key = 'ctrl';
}

View File

@@ -539,7 +539,7 @@ define([
let clickY = e.pageY - posY;
// check for top-left click
if(clickX <= 8 && clickY <= 8){
if(clickX <= 8 && clickY <= 8 && clickX >= 0 && clickY >= 0){
// remember height
if(! moduleElement.data('origHeight')){

View File

@@ -138,6 +138,15 @@ define([
location.reload();
});
body.watchKey('newSignature', (body) => {
let activeMap = Util.getMapModule().getActiveMap();
if(activeMap){
let mapContentElement = MapUtil.getTabContentElementByMapElement(activeMap);
let signatureModuleElement = mapContentElement.find('.' + config.systemSignatureModuleClass);
signatureModuleElement.trigger('pf:showSystemSignatureModuleAddNew');
}
});
body.watchKey('clipboardPaste', (e) => {
// just send event to the current active map
let activeMap = Util.getMapModule().getActiveMap();

View File

@@ -10,6 +10,11 @@ define([
], ($, Init, Util, MapUtil) => {
'use strict';
let config = {
// Select2
resultOptionImageClass: 'pf-result-image' // class for Select2 result option entry with image
};
/**
* format result data
* @param data
@@ -19,7 +24,7 @@ define([
if(data.loading) return data.text;
if(data.placeholder) return data.placeholder;
let markup = '<div class="clearfix">';
let markup = '<div class="clearfix ' + config.resultOptionImageClass + '">';
if(data.hasOwnProperty('children')){
// category group label
@@ -89,18 +94,16 @@ define([
*/
$.fn.initStatusSelect = function(options){
let config = {
let defaultConfig = {
minimumResultsForSearch: -1,
width: '100%',
iconClass: 'fa-circle'
};
config = $.extend({}, config, options);
options = $.extend({}, defaultConfig, options);
let formatStatusSelectionData = state => {
let markup = '<span>';
markup += '<i class="fas ' + config.iconClass + ' ' + state.class + '"></i>&nbsp;&nbsp;&nbsp;' + state.text;
markup += '</span>';
let markup = '<i class="fas ' + options.iconClass + ' ' + state.class + '"></i>&nbsp;&nbsp;&nbsp;' + state.text;
return $(markup);
};
@@ -109,9 +112,9 @@ define([
if(data.loading) return data.text;
if(data.placeholder) return data.placeholder;
let markup = '<div class="clearfix">';
let markup = '<div class="clearfix ' + config.resultOptionImageClass + '">';
markup += '<div class="col-xs-2 text-center">';
markup += '<i class="fas ' + config.iconClass + ' ' + data.class + '"></i>';
markup += '<i class="fas ' + options.iconClass + ' ' + data.class + '"></i>';
markup += '</div>';
markup += '<div class="col-xs-10">' + data.text + '</div>';
markup += '</div>';
@@ -119,12 +122,12 @@ define([
return $(markup);
};
config.templateSelection = formatStatusSelectionData;
config.templateResult = formatStatusResultData;
options.templateSelection = formatStatusSelectionData;
options.templateResult = formatStatusResultData;
return this.each(function(){
let selectElement = $(this);
selectElement.select2(config);
selectElement.select2(options);
});
};
@@ -135,10 +138,10 @@ define([
$.fn.initSystemSelect = function(options){
let selectElement = $(this);
let config = {
let defaultConfig = {
maxSelectionLength: 1
};
options = $.extend({}, config, options);
options = $.extend({}, defaultConfig, options);
let shatteredClass = Util.getSecurityClassForSystem('SH');
@@ -154,7 +157,7 @@ define([
let hideShatteredClass = !data.shattered ? 'hide' : '';
let markup = '<div class="clearfix">';
let markup = '<div class="clearfix ' + config.resultOptionImageClass + '">';
markup += '<div class="col-sm-4 pf-select-item-anchor ' + systemNameClass + '">' + data.text + '</div>';
markup += '<div class="col-sm-2 text-right ' + data.effectClass + '">';
markup += '<i class="fas fa-fw fa-square ' + hideEffectClass + '"></i>';
@@ -247,11 +250,7 @@ define([
templateResult: formatResultData,
placeholder: 'System name',
allowClear: true,
maximumSelectionLength: options.maxSelectionLength,
escapeMarkup: function(markup){
// let our custom formatter work
return markup;
}
maximumSelectionLength: options.maxSelectionLength
}).on('change', function(e){
// select changed
}).on('select2:open', function(){
@@ -337,11 +336,7 @@ define([
allowClear: false,
maximumSelectionLength: options.maxSelectionLength,
templateResult: formatCategoryTypeResultData,
templateSelection: formatSelectionData,
escapeMarkup: function(markup){
// let our custom formatter work
return markup;
}
templateSelection: formatSelectionData
}).on('change', function(e){
// select changed
@@ -435,9 +430,6 @@ define([
dropdownParent: selectElement.parents('.modal-body') ,
minimumInputLength: 3,
placeholder: '',
language: {
searching: params => '&nbsp;<i class="fas fa-sync fa-spin"></i>&nbsp;&nbsp;searching...'
},
/* alphabetic search not always fits the users need
sorter: data => {
// sort nested data options by "text" prop
@@ -448,12 +440,8 @@ define([
},*/
allowClear: options.maxSelectionLength <= 1,
maximumSelectionLength: options.maxSelectionLength,
templateResult: formatCategoryTypeResultData,
templateResult: formatCategoryTypeResultData
// templateSelection: formatSelectionData, // some issues with "clear" selection on single selects (empty option is needed)
escapeMarkup: function(markup){
// let our custom formatter work
return markup;
}
}).on('change', function(e){
// select changed
}).on('select2:open', function(){
@@ -472,8 +460,12 @@ define([
});
};
$.fn.initUniverseTypeSelect = function(options) {
/**
* init a select element as an "select2" object for system search
* @param options
* @returns {*}
*/
$.fn.initUniverseTypeSelect = function(options){
/**
* get select option data by categoryIds
@@ -531,10 +523,7 @@ define([
maximumSelectionLength: options.maxSelectionLength,
// maximumSelectionLength: options.maxSelectionLength > 1 ? options.maxSelectionLength > 1 : 0,
// minimumResultsForSearch: 5, // minimum number of results required to display the search box
templateResult: formatCategoryTypeResultData,
escapeMarkup: function(markup){
return markup;
}
templateResult: formatCategoryTypeResultData
}).on('select2:open', function(){
// clear selected system (e.g. default system)
// => improves usability (not necessary). There is a small "x" if field can be cleared manually
@@ -549,4 +538,165 @@ define([
});
};
/**
* init a select element as an "select2" object for signature group data
* @param options
* @returns {*}
*/
$.fn.initSignatureGroupSelect = function(options){
let defaultConfig = {
minimumResultsForSearch: -1,
width: '110px',
dropdownParent: this.parents('.popover-content')
};
options = $.extend({}, defaultConfig, options);
return this.each(function(){
let selectElement = $(this);
selectElement.select2(options);
// initial open dropDown
if( !parseInt(selectElement.val()) ){
// setTimeout() required because of dropDown positioning
setTimeout(() => {
selectElement.select2('open');
}, 0);
}
});
};
/**
* init a select element as an "select2" object for signature types data
* @param options
* @returns {*}
*/
$.fn.initSignatureTypeSelect = function(options){
let defaultConfig = {
minimumResultsForSearch: 6,
width: '220px',
dropdownParent: this.parents('.popover-content')
};
options = $.extend({}, defaultConfig, options);
let formatSignatureTypeSelectionData = state => {
let parts = state.text.split(' - ');
let markup = '';
if(parts.length === 2){
// wormhole data -> 2 columns
let securityClass = Util.getSecurityClassForSystem(parts[1]);
markup += '<span>' + parts[0] + '</span>&nbsp;&nbsp;';
markup += '<i class="fas fa-long-arrow-alt-right"></i>&nbsp;&nbsp;';
markup += '<span class="' + securityClass + '">' + parts[1] + '</span>';
}else{
markup += '<span>' + state.text + '</span>';
}
return $(markup);
};
let formatSignatureTypeResultData = data => {
if(data.loading) return data.text;
if(data.placeholder) return data.placeholder;
let markup = '<div class="clearfix">';
if(data.hasOwnProperty('children')){
// category group label
markup += '<div class="col-xs-9">' + data.text + '</div>';
markup += '<div class="col-xs-3 text-right">(' + data.children.length + ')</div>';
}else{
let parts = data.text.split(' - ');
if(parts.length === 2){
// wormhole data -> 2 columns
let securityClass = Util.getSecurityClassForSystem(parts[1]);
markup += '<div class="col-xs-3 text-right">' + parts[0] + '</div>';
markup += '<div class="col-xs-2 text-center"><i class="fas fa-long-arrow-alt-right"></i></div>';
markup += '<div class="col-xs-7 ' + securityClass + '">' + parts[1] + '</div>';
}else{
markup += '<div class="col-xs-12">' + data.text + '</div>';
}
}
markup += '</div>';
return $(markup);
};
let search = (params, data) => {
if($.trim(params.term) === '') return data; // If there are no search terms, return all of the data
if(typeof data.children === 'undefined') return null; // Skip if there is no 'children' property
// `data.children` contains the actual options that we are matching against
let filteredChildren = [];
for(let [idx, child] of Object.entries(data.children)){
if(child.text.toUpperCase().indexOf(params.term.toUpperCase()) === 0){
filteredChildren.push(child);
}
}
// If we matched any of the timezone group's children, then set the matched children on the group
// and return the group object
if(filteredChildren.length){
let modifiedData = $.extend({}, data, true);
modifiedData.children = filteredChildren;
// You can return modified objects from here
// This includes matching the `children` how you want in nested data sets
return modifiedData;
}
// Return `null` if the term should not be displayed
return null;
};
options.templateSelection = formatSignatureTypeSelectionData;
options.templateResult = formatSignatureTypeResultData;
options.matcher = search;
return this.each(function(){
let selectElement = $(this);
selectElement.select2(options);
// initial open dropDown
if( !parseInt(selectElement.val()) ){
// setTimeout() required because of dropDown positioning
setTimeout(() => {
selectElement.select2('open');
}, 0);
}
});
};
/**
* init a select element as an "select2" object for signature group data
* @param options
* @returns {*}
*/
$.fn.initSignatureConnectionSelect = function(options){
let defaultConfig = {
minimumResultsForSearch: -1,
width: '140px',
dropdownParent: this.parents('.popover-content')
};
options = $.extend({}, defaultConfig, options);
return this.each(function(){
let selectElement = $(this);
selectElement.select2(options);
// initial open dropDown
if( !parseInt(selectElement.val()) ){
// setTimeout() required because of dropDown positioning
setTimeout(() => {
selectElement.select2('open');
}, 0);
}
});
};
});

View File

@@ -6,7 +6,7 @@ define([
'jquery',
'easePack',
'tweenLite'
], function($) {
], ($) => {
'use strict';
let config = {

View File

@@ -5,12 +5,11 @@
define([
'jquery',
'lazylinepainter'
], function($) {
], ($) => {
'use strict';
let config = {
staticLogoId: 'pf-static-logo-svg', // id for "static" logo
logoPartTopRightClass: 'logo-ploygon-top-right', // class for logo part "top right"

View File

@@ -7,7 +7,7 @@ define([
'app/init',
'app/util',
'morris'
], function($, Init, Util, Morris) {
], ($, Init, Util, Morris) => {
'use strict';
let config = {

View File

@@ -8,7 +8,7 @@ define([
'app/util',
'app/render',
'app/map/util'
], function($, Init, Util, Render, MapUtil) {
], ($, Init, Util, Render, MapUtil) => {
'use strict';
let config = {

View File

@@ -10,7 +10,7 @@ define([
'bootbox',
'app/map/map',
'app/map/util'
], function($, Init, Util, Mustache, bootbox, Map, MapUtil) {
], ($, Init, Util, Mustache, bootbox, Map, MapUtil) => {
'use strict';
let config = {
@@ -44,8 +44,6 @@ define([
sigTableClass: 'pf-sig-table', // Table class for all Signature Tables
sigTablePrimaryClass: 'pf-sig-table-primary', // class for primary sig table
sigTableSecondaryClass: 'pf-sig-table-secondary', // class for secondary sig table
sigTableRowIdPrefix: 'pf-sig-table-row-', // id prefix for a table row <tr>
sigTableEditText: 'pf-sig-table-edit-text', // class for editable fields (text)
sigTableEditSigNameInput: 'pf-sig-table-edit-name-input', // class for editable fields (input)
sigTableEditSigGroupSelect: 'pf-sig-table-edit-group-select', // class for editable fields (sig group)
sigTableEditSigTypeSelect: 'pf-sig-table-edit-type-select', // class for editable fields (sig type)
@@ -755,7 +753,6 @@ define([
* @returns {Array}
*/
let formatSignatureData = (systemData, signatureData, options) => {
let formattedData = [];
// security check
@@ -976,7 +973,7 @@ define([
// create "empty table for new signature
let table = $('<table>', {
class: ['display', 'compact', 'nowrap', config.sigTableClass, config.sigTableSecondaryClass].join(' ')
class: ['stripe', 'row-border', 'compact', 'nowrap', config.sigTableClass, config.sigTableSecondaryClass].join(' ')
});
tableToolbarAction.append(table);
@@ -987,9 +984,9 @@ define([
let signatureTable = table.dataTable( {
data: signatureData,
paging: false,
ordering: false,
info: false,
searching: false
searching: false,
tabIndex: -1
} );
let signatureTableApi = signatureTable.api();
@@ -1008,6 +1005,48 @@ define([
.tooltip('setContent');
};
/**
* helper function - jump to "next" editable field on save
* @param field
* @param selector
* @returns {*|jQuery|HTMLElement}
*/
let getNextEditableField = (field, selector) => {
let nextEditableField = null;
if(selector){
// search specific sibling
nextEditableField = $(field).closest('td').nextAll(selector).find('.editable');
}else{
// get next sibling
nextEditableField = $(field).closest('td').next().find('.editable');
}
return $(nextEditableField);
};
/**
* helper function - get the next editable field in next table column
* @param fields
*/
let openNextEditDialogOnSave = fields => {
fields.on('save', function(e, params){
let currentField = $(this);
let nextField = getNextEditableField(currentField);
nextField.editable('show');
setTimeout(() => {
// update scanning progressbar if sig "type" has changed AND
// the current field is in the "primary" table (not the "add" new sig row)
if(
$(e.target).hasClass(config.sigTableEditSigGroupSelect) &&
$(e.target).parents('.' + config.sigTableClass).hasClass(config.sigTablePrimaryClass)
){
currentField.parents('.' + config.moduleClass).updateScannedSignaturesBar({showNotice: true});
}
}, 200);
});
};
/**
* make a table or row editable
* @param tableApi
@@ -1024,50 +1063,13 @@ define([
let sigDescriptionFields = tableElement.find('.' + config.sigTableEditSigDescriptionTextarea);
let sigConnectionFields = tableElement.find('.' + config.sigTableEditSigConnectionSelect);
// jump to "next" editable field on save
let openNextEditDialogOnSave = function(fields){
fields.on('save', function(e, a){
let currentField = $(this);
setTimeout(function() {
let nextField = getNextEditableField(currentField);
nextField.editable('show');
// update scanning progressbar if sig "type" has changed AND
// the current field is in the "primary" table (not the "add" new sig row)
if(
$(e.target).hasClass(config.sigTableEditSigGroupSelect) &&
$(e.target).parents('.' + config.sigTableClass).hasClass(config.sigTablePrimaryClass)
){
currentField.parents('.' + config.moduleClass).updateScannedSignaturesBar({showNotice: true});
}
}, 200);
});
};
// helper function - get the next editable field in next table column
let getNextEditableField = function(field, selector){
let nextEditableField = null;
if(selector){
// search specific sibling
nextEditableField = $(field).closest('td').nextAll(selector).find('.editable');
}else{
// get next sibling
nextEditableField = $(field).closest('td').next().find('.editable');
}
return $(nextEditableField);
};
/**
* add map/system specific data for each editable field in the sig-table
* @param params
* @returns {*}
*/
let modifyFieldParamsOnSend = function(params){
let modifyFieldParamsOnSend = params => {
params.systemId = systemData.id;
return params;
};
@@ -1227,13 +1229,19 @@ define([
return availableSigs;
},
success: function(response, newValue){
let signatureTypeField = $(this);
let rowElement = signatureTypeField.parents('tr');
if(response){
let signatureTypeField = $(this);
let rowElement = signatureTypeField.parents('tr');
let newRowData = response.signatures[0];
// update "updated" cell
updateSignatureCell(tableApi, rowElement, 7, newRowData.updated);
}else{
// "add new" signature -> set "+" focus for keyboard control
setTimeout(function() {
rowElement.find('.pf-table-action-cell')[0].focus();
}, 50);
}
}
});
@@ -1316,6 +1324,21 @@ define([
}
});
sigGroupFields.on('shown', function(e, editable) {
let inputField = editable.input.$input;
inputField.addClass('pf-select2').initSignatureGroupSelect();
});
sigTypeFields.on('shown', function(e, editable) {
let inputField = editable.input.$input;
inputField.addClass('pf-select2').initSignatureTypeSelect();
});
sigConnectionFields.on('shown', function(e, editable) {
let inputField = editable.input.$input;
inputField.addClass('pf-select2').initSignatureConnectionSelect();
});
// open even
sigDescriptionFields.on('shown', function(e, editable) {
// enlarge the tools-action container because the tables gets bigger
@@ -1333,6 +1356,12 @@ define([
checkConnectionConflicts();
});
$().add(sigNameFields).add(sigGroupFields).add(sigTypeFields)
.add(sigDescriptionFields).add(sigConnectionFields).on('hidden', function(e, editable) {
// re-focus element on close (keyboard navigation)
this.focus();
});
// open next field dialog -------------------------------------------------------------------------------------
openNextEditDialogOnSave(sigNameFields);
openNextEditDialogOnSave(sigGroupFields);
@@ -1537,7 +1566,7 @@ define([
// add static WH(s) for this system
if(systemData.statics){
let staticWHData = [];
for(let wormholeName of systemData.statics) {
for(let wormholeName of systemData.statics){
let wormholeData = Object.assign({}, Init.wormholes[wormholeName]);
let staticWHName = wormholeData.name + ' - ' + wormholeData.security;
@@ -1856,7 +1885,7 @@ define([
// format group filter options
let groups = Object.assign({}, config.signatureGroupsLabels);
for (let [value, label] of Object.entries(groups)){
for(let [value, label] of Object.entries(groups)){
if(label.length){
sourceOptions.push({value: label, text: label});
}
@@ -1920,6 +1949,7 @@ define([
moduleElement.append(table);
let dataTableOptions = {
tabIndex: -1,
dom: '<"row"<"col-xs-3"l><"col-xs-5"B><"col-xs-4"f>>' +
'<"row"<"col-xs-12"tr>>' +
'<"row"<"col-xs-5"i><"col-xs-7"p>>',
@@ -2019,7 +2049,7 @@ define([
searchable: true,
title: 'id',
type: 'html',
width: 30,
width: 15,
data: 'name',
render: {
_: 'render'
@@ -2035,7 +2065,7 @@ define([
searchable: true,
title: 'group',
type: 'html',
width: 50,
width: 40,
data: 'group',
render: {
_: 'group',
@@ -2149,10 +2179,20 @@ define([
let tempTableElement = this;
let rowElement = $(cell).parents('tr');
$(cell).attr('tabindex', 0).on('keydown', function(e){
e.stopPropagation();
if(e.which === 13){
$(this).trigger('click');
}
});
switch(cellData.action){
case 'add':
// add new signature ------------------------------------------------------------------
$(cell).on('click', function(e) {
e.stopPropagation();
e.preventDefault();
// submit all fields within a table row
let formFields = rowElement.find('.editable');
@@ -2249,34 +2289,63 @@ define([
});
};
/**
* open xEditable input field in "new Signature" table
* @param moduleElement
*/
let focusNewSignatureEditableField = moduleElement => {
let secondaryTable = moduleElement.find('.' + config.sigTableSecondaryClass);
secondaryTable.find('.' + config.sigTableEditSigNameInput).editable('show');
};
/**
* set module observer and look for relevant signature data to update
* @param moduleElement
* @param systemData
*/
let setModuleObserver = (moduleElement, systemData) => {
let tablePrimaryElement = moduleElement.find('.' + config.sigTablePrimaryClass);
let signatureTableApi = getDataTableInstanceByModuleElement(moduleElement, 'primary');
let primaryTable = moduleElement.find('.' + config.sigTablePrimaryClass);
let primaryTableApi = getDataTableInstanceByModuleElement(moduleElement, 'primary');
// add signature toggle ---------------------------------------------------------------------------------------
moduleElement.find('.' + config.moduleHeadlineIconAddClass).on('click', function(e){
let button = $(this);
let toggleAddSignature = (show = 'auto') => {
let button = moduleElement.find('.' + config.moduleHeadlineIconAddClass);
let toolsElement = moduleElement.find('.' + config.tableToolsActionClass);
button.toggleClass('active');
button.toggleClass('active', show === 'auto' ? undefined : show);
// set toggle animation
if(toolsElement.is(':visible')){
toolsElement.velocity('stop').velocity('reverse');
}else{
if(toolsElement.is(':visible') && (!show || show === 'auto')){
// hide container
toolsElement.velocity('stop').velocity({
opacity: 1,
height: '75px'
opacity: [0, 1],
height: [0, '70px']
},{
duration: 150,
display: 'none'
});
}else if(!toolsElement.is(':visible') && (show || show === 'auto')){
// show container
toolsElement.velocity('stop').velocity({
opacity: [1, 0],
height: ['70px', 0]
},{
duration: 150,
display: 'block',
visibility: 'visible'
complete: function(){
focusNewSignatureEditableField(moduleElement);
}
});
}else if(toolsElement.is(':visible') && show){
// still visible -> no animation
focusNewSignatureEditableField(moduleElement);
}
};
moduleElement.find('.' + config.moduleHeadlineIconAddClass).on('click', function(e){
toggleAddSignature('auto');
});
moduleElement.on('pf:showSystemSignatureModuleAddNew', function(e){
toggleAddSignature(true);
});
// signature reader dialog ------------------------------------------------------------------------------------
@@ -2291,7 +2360,7 @@ define([
});
// set multi row select ---------------------------------------------------------------------------------------
tablePrimaryElement.on('click', 'tr', {tableApi: signatureTableApi}, function(e){
primaryTable.on('click', 'tr', {tableApi: primaryTableApi}, function(e){
if(e.ctrlKey) {
$(this).toggleClass('selected');
@@ -2301,17 +2370,17 @@ define([
});
// draw event for signature table -----------------------------------------------------------------------------
signatureTableApi.on('draw.dt', function(e, settings){
primaryTableApi.on('draw.dt', function(e, settings){
// check delete button
let tableApi = $(this).dataTable().api();
checkDeleteSignaturesButton(tableApi);
});
// destroy dataTables event -----------------------------------------------------------------------------------
tablePrimaryElement.on('destroy.dt', function(){
primaryTable.on('destroy.dt', function(){
$(this).destroyTimestampCounter();
});
signatureTableApi.on('destroy.dt', function(){
primaryTableApi.on('destroy.dt', function(){
$(this).destroyTimestampCounter();
});

View File

@@ -1017,6 +1017,13 @@ define([
*/
let initDefaultSelect2Config = () => {
$.fn.select2.defaults.set('theme', 'pathfinder');
$.fn.select2.defaults.set('language', {
searching: params => '&nbsp;<i class="fas fa-sync fa-spin"></i>&nbsp;&nbsp;searching...'
});
$.fn.select2.defaults.set('escapeMarkup', markup => {
// required for HTML in options
return markup;
});
let initScrollbar = (resultsWrapper) => {
// default 'mousewheel' event set by select2 needs to be disabled
@@ -1055,10 +1062,9 @@ define([
let getResultsWrapper = (selectElement) => {
let wrapper = null;
let selectElementId = selectElement.getAttribute('data-select2-id');
if(selectElementId){
let resultsOptions = $('#select2-' + selectElementId + '-results');
if(resultsOptions.length) {
if($(selectElement).data('select2')){
let resultsOptions = $(selectElement).data('select2').$results;
if(resultsOptions.length){
let resultsWrapper = resultsOptions.parents('.select2-results');
if(resultsWrapper.length){
wrapper = resultsWrapper;
@@ -1089,7 +1095,7 @@ define([
* set default configuration for "xEditable"
*/
let initDefaultEditableConfig = () => {
// use fontAwesome buttons
// use fontAwesome buttons template
$.fn.editableform.buttons =
'<button type="submit" class="btn btn-primary btn-sm editable-submit">'+
'<i class="fa fa-fw fa-check"></i>'+
@@ -1097,6 +1103,10 @@ define([
'<button type="button" class="btn btn-default btn-sm editable-cancel">'+
'<i class="fa fa-fw fa-times"></i>'+
'</button>';
// loading spinner template
$.fn.editableform.loading =
'<div class="editableform-loading"><i class="fas fa-lg fa-sync fa-spin"></i></div>';
};
/**

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -228,8 +228,8 @@ define(['jquery'], ($) => {
5: { // Wormhole
// no *wandering* w-space -> w-space
// all holes are statics or K162
1: 'S047 - HS',
2: 'N290 - LS',
1: 'S047 - H',
2: 'N290 - L',
3: 'K329 - 0.0'
},
6: { // ORE
@@ -271,8 +271,8 @@ define(['jquery'], ($) => {
9: 'Vital Core Reservoir' //*
},
5: { // Wormhole
1: 'D792 - HS',
2: 'C140 - LS',
1: 'D792 - H',
2: 'C140 - L',
3: 'Z142 - 0.0'
},
6: { // ORE
@@ -318,10 +318,10 @@ define(['jquery'], ($) => {
9: 'Vital Core Reservoir' //*
},
5: { // Wormhole
1: 'B520 - HS',
2: 'D792 - HS',
3: 'C140 - LS',
4: 'C391 - LS',
1: 'B520 - H',
2: 'D792 - H',
3: 'C140 - L',
4: 'C391 - L',
5: 'C248 - 0.0',
6: 'Z142 - 0.0'
},
@@ -356,15 +356,15 @@ define(['jquery'], ($) => {
16: 'U574 - C6',
17: 'V753 - C6',
18: 'W237 - C6',
19: 'B274 - HS',
20: 'D792 - HS',
21: 'D845 - HS',
22: 'N110 - HS',
23: 'A239 - LS',
24: 'C391 - LS',
25: 'J244 - LS',
26: 'U201 - LS', // ??
27: 'U210 - LS',
19: 'B274 - H',
20: 'D792 - H',
21: 'D845 - H',
22: 'N110 - H',
23: 'A239 - L',
24: 'C391 - L',
25: 'J244 - L',
26: 'U201 - L', // ??
27: 'U210 - L',
28: 'C248 - 0.0',
29: 'E545 - 0.0',
30: 'K346 - 0.0',
@@ -381,8 +381,8 @@ define(['jquery'], ($) => {
4: 'O128 - C4',
5: 'M555 - C5',
6: 'B041 - C6',
7: 'A641 - HS',
8: 'R051 - LS',
7: 'A641 - H',
8: 'R051 - L',
9: 'V283 - 0.0',
10: 'T458 - Thera'
}
@@ -395,8 +395,8 @@ define(['jquery'], ($) => {
4: 'O128 - C4',
5: 'N432 - C5',
6: 'U319 - C6',
7: 'B449 - HS',
8: 'N944 - LS',
7: 'B449 - H',
8: 'N944 - L',
9: 'S199 - 0.0',
10: 'M164 - Thera'
}
@@ -409,8 +409,8 @@ define(['jquery'], ($) => {
4: 'O128 - C4',
5: 'N432 - C5',
6: 'U319 - C6',
7: 'B449 - HS',
8: 'N944 - LS',
7: 'B449 - H',
8: 'N944 - L',
9: 'S199 - 0.0',
10: 'L031 - Thera'
}

View File

@@ -406,7 +406,7 @@ define(['jquery'], ($) => {
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
8: 'A009 - SH'
},
2: { // C2
1: 'E004 - C1',
@@ -416,7 +416,7 @@ define(['jquery'], ($) => {
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
8: 'A009 - SH'
},
3: { // C3
1: 'E004 - C1',
@@ -426,7 +426,7 @@ define(['jquery'], ($) => {
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
8: 'A009 - SH'
},
4: { // C4
1: 'E004 - C1',
@@ -436,7 +436,7 @@ define(['jquery'], ($) => {
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
8: 'A009 - SH'
},
5: { // C5
1: 'E004 - C1',
@@ -446,7 +446,7 @@ define(['jquery'], ($) => {
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
8: 'A009 - SH'
},
6: { // C6
1: 'E004 - C1',
@@ -456,7 +456,7 @@ define(['jquery'], ($) => {
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
8: 'A009 - SH'
},
13: { // Shattered Wormholes (some of them are static)
1: 'E004 - C1',
@@ -466,7 +466,7 @@ define(['jquery'], ($) => {
5: 'C008 - C5',
6: 'G008 - C6',
7: 'Q003 - 0.0',
8: 'A009 - (shattered)'
8: 'A009 - SH'
}
},
// incoming wormholes
@@ -474,8 +474,8 @@ define(['jquery'], ($) => {
1: 'K162 - C1/2/3 (unknown)',
2: 'K162 - C4/5 (dangerous)',
3: 'K162 - C6 (deadly)',
4: 'K162 - HS',
5: 'K162 - LS',
4: 'K162 - H',
5: 'K162 - L',
6: 'K162 - 0.0',
7: 'K162 - Thera'
}

View File

@@ -1,6 +1,6 @@
define([
'jquery'
], function($) {
], ($) => {
'use strict';
let allCombo = {
@@ -31,12 +31,17 @@ define([
keyNames: ['CONTROL', 'V'],
alias: 'paste'
},
newSignature: {
group: 'signatures',
label: 'New Signature',
keyNames: ['ALT', '3']
},
// map ----------------------------------------------------------------------------------------------
mapSystemAdd: {
group: 'map',
label: 'Add new system',
keyNames: ['CONTROL', 'S']
label: 'New system',
keyNames: ['ALT', '2']
},
mapSystemsSelect: {
group: 'map',
@@ -409,19 +414,18 @@ define([
/**
* get a array with all available shortcut groups and their events
* @returns {Array}
* @returns {any[]}
*/
let getGroupedShortcuts = () => {
let result = $.extend(true, {}, groups);
// add combos and events to groups
let allEntries = [allCombo, allEvents];
for(let i = 0; i < allEntries.length; i++){
for(let event in allEntries[i]){
let data = allEntries[i][event];
for(let entries of allEntries){
for(let [event, data] of Object.entries(entries)){
//format keyNames for UI
let keyNames = data.keyNames.map( (key) => {
let keyNames = data.keyNames.map(key => {
if(key === 'CONTROL'){
key = 'ctrl';
}

View File

@@ -539,7 +539,7 @@ define([
let clickY = e.pageY - posY;
// check for top-left click
if(clickX <= 8 && clickY <= 8){
if(clickX <= 8 && clickY <= 8 && clickX >= 0 && clickY >= 0){
// remember height
if(! moduleElement.data('origHeight')){

View File

@@ -138,6 +138,15 @@ define([
location.reload();
});
body.watchKey('newSignature', (body) => {
let activeMap = Util.getMapModule().getActiveMap();
if(activeMap){
let mapContentElement = MapUtil.getTabContentElementByMapElement(activeMap);
let signatureModuleElement = mapContentElement.find('.' + config.systemSignatureModuleClass);
signatureModuleElement.trigger('pf:showSystemSignatureModuleAddNew');
}
});
body.watchKey('clipboardPaste', (e) => {
// just send event to the current active map
let activeMap = Util.getMapModule().getActiveMap();

View File

@@ -10,6 +10,11 @@ define([
], ($, Init, Util, MapUtil) => {
'use strict';
let config = {
// Select2
resultOptionImageClass: 'pf-result-image' // class for Select2 result option entry with image
};
/**
* format result data
* @param data
@@ -19,7 +24,7 @@ define([
if(data.loading) return data.text;
if(data.placeholder) return data.placeholder;
let markup = '<div class="clearfix">';
let markup = '<div class="clearfix ' + config.resultOptionImageClass + '">';
if(data.hasOwnProperty('children')){
// category group label
@@ -89,18 +94,16 @@ define([
*/
$.fn.initStatusSelect = function(options){
let config = {
let defaultConfig = {
minimumResultsForSearch: -1,
width: '100%',
iconClass: 'fa-circle'
};
config = $.extend({}, config, options);
options = $.extend({}, defaultConfig, options);
let formatStatusSelectionData = state => {
let markup = '<span>';
markup += '<i class="fas ' + config.iconClass + ' ' + state.class + '"></i>&nbsp;&nbsp;&nbsp;' + state.text;
markup += '</span>';
let markup = '<i class="fas ' + options.iconClass + ' ' + state.class + '"></i>&nbsp;&nbsp;&nbsp;' + state.text;
return $(markup);
};
@@ -109,9 +112,9 @@ define([
if(data.loading) return data.text;
if(data.placeholder) return data.placeholder;
let markup = '<div class="clearfix">';
let markup = '<div class="clearfix ' + config.resultOptionImageClass + '">';
markup += '<div class="col-xs-2 text-center">';
markup += '<i class="fas ' + config.iconClass + ' ' + data.class + '"></i>';
markup += '<i class="fas ' + options.iconClass + ' ' + data.class + '"></i>';
markup += '</div>';
markup += '<div class="col-xs-10">' + data.text + '</div>';
markup += '</div>';
@@ -119,12 +122,12 @@ define([
return $(markup);
};
config.templateSelection = formatStatusSelectionData;
config.templateResult = formatStatusResultData;
options.templateSelection = formatStatusSelectionData;
options.templateResult = formatStatusResultData;
return this.each(function(){
let selectElement = $(this);
selectElement.select2(config);
selectElement.select2(options);
});
};
@@ -135,10 +138,10 @@ define([
$.fn.initSystemSelect = function(options){
let selectElement = $(this);
let config = {
let defaultConfig = {
maxSelectionLength: 1
};
options = $.extend({}, config, options);
options = $.extend({}, defaultConfig, options);
let shatteredClass = Util.getSecurityClassForSystem('SH');
@@ -154,7 +157,7 @@ define([
let hideShatteredClass = !data.shattered ? 'hide' : '';
let markup = '<div class="clearfix">';
let markup = '<div class="clearfix ' + config.resultOptionImageClass + '">';
markup += '<div class="col-sm-4 pf-select-item-anchor ' + systemNameClass + '">' + data.text + '</div>';
markup += '<div class="col-sm-2 text-right ' + data.effectClass + '">';
markup += '<i class="fas fa-fw fa-square ' + hideEffectClass + '"></i>';
@@ -247,11 +250,7 @@ define([
templateResult: formatResultData,
placeholder: 'System name',
allowClear: true,
maximumSelectionLength: options.maxSelectionLength,
escapeMarkup: function(markup){
// let our custom formatter work
return markup;
}
maximumSelectionLength: options.maxSelectionLength
}).on('change', function(e){
// select changed
}).on('select2:open', function(){
@@ -337,11 +336,7 @@ define([
allowClear: false,
maximumSelectionLength: options.maxSelectionLength,
templateResult: formatCategoryTypeResultData,
templateSelection: formatSelectionData,
escapeMarkup: function(markup){
// let our custom formatter work
return markup;
}
templateSelection: formatSelectionData
}).on('change', function(e){
// select changed
@@ -435,9 +430,6 @@ define([
dropdownParent: selectElement.parents('.modal-body') ,
minimumInputLength: 3,
placeholder: '',
language: {
searching: params => '&nbsp;<i class="fas fa-sync fa-spin"></i>&nbsp;&nbsp;searching...'
},
/* alphabetic search not always fits the users need
sorter: data => {
// sort nested data options by "text" prop
@@ -448,12 +440,8 @@ define([
},*/
allowClear: options.maxSelectionLength <= 1,
maximumSelectionLength: options.maxSelectionLength,
templateResult: formatCategoryTypeResultData,
templateResult: formatCategoryTypeResultData
// templateSelection: formatSelectionData, // some issues with "clear" selection on single selects (empty option is needed)
escapeMarkup: function(markup){
// let our custom formatter work
return markup;
}
}).on('change', function(e){
// select changed
}).on('select2:open', function(){
@@ -472,8 +460,12 @@ define([
});
};
$.fn.initUniverseTypeSelect = function(options) {
/**
* init a select element as an "select2" object for system search
* @param options
* @returns {*}
*/
$.fn.initUniverseTypeSelect = function(options){
/**
* get select option data by categoryIds
@@ -531,10 +523,7 @@ define([
maximumSelectionLength: options.maxSelectionLength,
// maximumSelectionLength: options.maxSelectionLength > 1 ? options.maxSelectionLength > 1 : 0,
// minimumResultsForSearch: 5, // minimum number of results required to display the search box
templateResult: formatCategoryTypeResultData,
escapeMarkup: function(markup){
return markup;
}
templateResult: formatCategoryTypeResultData
}).on('select2:open', function(){
// clear selected system (e.g. default system)
// => improves usability (not necessary). There is a small "x" if field can be cleared manually
@@ -549,4 +538,165 @@ define([
});
};
/**
* init a select element as an "select2" object for signature group data
* @param options
* @returns {*}
*/
$.fn.initSignatureGroupSelect = function(options){
let defaultConfig = {
minimumResultsForSearch: -1,
width: '110px',
dropdownParent: this.parents('.popover-content')
};
options = $.extend({}, defaultConfig, options);
return this.each(function(){
let selectElement = $(this);
selectElement.select2(options);
// initial open dropDown
if( !parseInt(selectElement.val()) ){
// setTimeout() required because of dropDown positioning
setTimeout(() => {
selectElement.select2('open');
}, 0);
}
});
};
/**
* init a select element as an "select2" object for signature types data
* @param options
* @returns {*}
*/
$.fn.initSignatureTypeSelect = function(options){
let defaultConfig = {
minimumResultsForSearch: 6,
width: '220px',
dropdownParent: this.parents('.popover-content')
};
options = $.extend({}, defaultConfig, options);
let formatSignatureTypeSelectionData = state => {
let parts = state.text.split(' - ');
let markup = '';
if(parts.length === 2){
// wormhole data -> 2 columns
let securityClass = Util.getSecurityClassForSystem(parts[1]);
markup += '<span>' + parts[0] + '</span>&nbsp;&nbsp;';
markup += '<i class="fas fa-long-arrow-alt-right"></i>&nbsp;&nbsp;';
markup += '<span class="' + securityClass + '">' + parts[1] + '</span>';
}else{
markup += '<span>' + state.text + '</span>';
}
return $(markup);
};
let formatSignatureTypeResultData = data => {
if(data.loading) return data.text;
if(data.placeholder) return data.placeholder;
let markup = '<div class="clearfix">';
if(data.hasOwnProperty('children')){
// category group label
markup += '<div class="col-xs-9">' + data.text + '</div>';
markup += '<div class="col-xs-3 text-right">(' + data.children.length + ')</div>';
}else{
let parts = data.text.split(' - ');
if(parts.length === 2){
// wormhole data -> 2 columns
let securityClass = Util.getSecurityClassForSystem(parts[1]);
markup += '<div class="col-xs-3 text-right">' + parts[0] + '</div>';
markup += '<div class="col-xs-2 text-center"><i class="fas fa-long-arrow-alt-right"></i></div>';
markup += '<div class="col-xs-7 ' + securityClass + '">' + parts[1] + '</div>';
}else{
markup += '<div class="col-xs-12">' + data.text + '</div>';
}
}
markup += '</div>';
return $(markup);
};
let search = (params, data) => {
if($.trim(params.term) === '') return data; // If there are no search terms, return all of the data
if(typeof data.children === 'undefined') return null; // Skip if there is no 'children' property
// `data.children` contains the actual options that we are matching against
let filteredChildren = [];
for(let [idx, child] of Object.entries(data.children)){
if(child.text.toUpperCase().indexOf(params.term.toUpperCase()) === 0){
filteredChildren.push(child);
}
}
// If we matched any of the timezone group's children, then set the matched children on the group
// and return the group object
if(filteredChildren.length){
let modifiedData = $.extend({}, data, true);
modifiedData.children = filteredChildren;
// You can return modified objects from here
// This includes matching the `children` how you want in nested data sets
return modifiedData;
}
// Return `null` if the term should not be displayed
return null;
};
options.templateSelection = formatSignatureTypeSelectionData;
options.templateResult = formatSignatureTypeResultData;
options.matcher = search;
return this.each(function(){
let selectElement = $(this);
selectElement.select2(options);
// initial open dropDown
if( !parseInt(selectElement.val()) ){
// setTimeout() required because of dropDown positioning
setTimeout(() => {
selectElement.select2('open');
}, 0);
}
});
};
/**
* init a select element as an "select2" object for signature group data
* @param options
* @returns {*}
*/
$.fn.initSignatureConnectionSelect = function(options){
let defaultConfig = {
minimumResultsForSearch: -1,
width: '140px',
dropdownParent: this.parents('.popover-content')
};
options = $.extend({}, defaultConfig, options);
return this.each(function(){
let selectElement = $(this);
selectElement.select2(options);
// initial open dropDown
if( !parseInt(selectElement.val()) ){
// setTimeout() required because of dropDown positioning
setTimeout(() => {
selectElement.select2('open');
}, 0);
}
});
};
});

View File

@@ -6,7 +6,7 @@ define([
'jquery',
'easePack',
'tweenLite'
], function($) {
], ($) => {
'use strict';
let config = {

View File

@@ -5,12 +5,11 @@
define([
'jquery',
'lazylinepainter'
], function($) {
], ($) => {
'use strict';
let config = {
staticLogoId: 'pf-static-logo-svg', // id for "static" logo
logoPartTopRightClass: 'logo-ploygon-top-right', // class for logo part "top right"

View File

@@ -7,7 +7,7 @@ define([
'app/init',
'app/util',
'morris'
], function($, Init, Util, Morris) {
], ($, Init, Util, Morris) => {
'use strict';
let config = {

View File

@@ -8,7 +8,7 @@ define([
'app/util',
'app/render',
'app/map/util'
], function($, Init, Util, Render, MapUtil) {
], ($, Init, Util, Render, MapUtil) => {
'use strict';
let config = {

View File

@@ -10,7 +10,7 @@ define([
'bootbox',
'app/map/map',
'app/map/util'
], function($, Init, Util, Mustache, bootbox, Map, MapUtil) {
], ($, Init, Util, Mustache, bootbox, Map, MapUtil) => {
'use strict';
let config = {
@@ -44,8 +44,6 @@ define([
sigTableClass: 'pf-sig-table', // Table class for all Signature Tables
sigTablePrimaryClass: 'pf-sig-table-primary', // class for primary sig table
sigTableSecondaryClass: 'pf-sig-table-secondary', // class for secondary sig table
sigTableRowIdPrefix: 'pf-sig-table-row-', // id prefix for a table row <tr>
sigTableEditText: 'pf-sig-table-edit-text', // class for editable fields (text)
sigTableEditSigNameInput: 'pf-sig-table-edit-name-input', // class for editable fields (input)
sigTableEditSigGroupSelect: 'pf-sig-table-edit-group-select', // class for editable fields (sig group)
sigTableEditSigTypeSelect: 'pf-sig-table-edit-type-select', // class for editable fields (sig type)
@@ -755,7 +753,6 @@ define([
* @returns {Array}
*/
let formatSignatureData = (systemData, signatureData, options) => {
let formattedData = [];
// security check
@@ -976,7 +973,7 @@ define([
// create "empty table for new signature
let table = $('<table>', {
class: ['display', 'compact', 'nowrap', config.sigTableClass, config.sigTableSecondaryClass].join(' ')
class: ['stripe', 'row-border', 'compact', 'nowrap', config.sigTableClass, config.sigTableSecondaryClass].join(' ')
});
tableToolbarAction.append(table);
@@ -987,9 +984,9 @@ define([
let signatureTable = table.dataTable( {
data: signatureData,
paging: false,
ordering: false,
info: false,
searching: false
searching: false,
tabIndex: -1
} );
let signatureTableApi = signatureTable.api();
@@ -1008,6 +1005,48 @@ define([
.tooltip('setContent');
};
/**
* helper function - jump to "next" editable field on save
* @param field
* @param selector
* @returns {*|jQuery|HTMLElement}
*/
let getNextEditableField = (field, selector) => {
let nextEditableField = null;
if(selector){
// search specific sibling
nextEditableField = $(field).closest('td').nextAll(selector).find('.editable');
}else{
// get next sibling
nextEditableField = $(field).closest('td').next().find('.editable');
}
return $(nextEditableField);
};
/**
* helper function - get the next editable field in next table column
* @param fields
*/
let openNextEditDialogOnSave = fields => {
fields.on('save', function(e, params){
let currentField = $(this);
let nextField = getNextEditableField(currentField);
nextField.editable('show');
setTimeout(() => {
// update scanning progressbar if sig "type" has changed AND
// the current field is in the "primary" table (not the "add" new sig row)
if(
$(e.target).hasClass(config.sigTableEditSigGroupSelect) &&
$(e.target).parents('.' + config.sigTableClass).hasClass(config.sigTablePrimaryClass)
){
currentField.parents('.' + config.moduleClass).updateScannedSignaturesBar({showNotice: true});
}
}, 200);
});
};
/**
* make a table or row editable
* @param tableApi
@@ -1024,50 +1063,13 @@ define([
let sigDescriptionFields = tableElement.find('.' + config.sigTableEditSigDescriptionTextarea);
let sigConnectionFields = tableElement.find('.' + config.sigTableEditSigConnectionSelect);
// jump to "next" editable field on save
let openNextEditDialogOnSave = function(fields){
fields.on('save', function(e, a){
let currentField = $(this);
setTimeout(function() {
let nextField = getNextEditableField(currentField);
nextField.editable('show');
// update scanning progressbar if sig "type" has changed AND
// the current field is in the "primary" table (not the "add" new sig row)
if(
$(e.target).hasClass(config.sigTableEditSigGroupSelect) &&
$(e.target).parents('.' + config.sigTableClass).hasClass(config.sigTablePrimaryClass)
){
currentField.parents('.' + config.moduleClass).updateScannedSignaturesBar({showNotice: true});
}
}, 200);
});
};
// helper function - get the next editable field in next table column
let getNextEditableField = function(field, selector){
let nextEditableField = null;
if(selector){
// search specific sibling
nextEditableField = $(field).closest('td').nextAll(selector).find('.editable');
}else{
// get next sibling
nextEditableField = $(field).closest('td').next().find('.editable');
}
return $(nextEditableField);
};
/**
* add map/system specific data for each editable field in the sig-table
* @param params
* @returns {*}
*/
let modifyFieldParamsOnSend = function(params){
let modifyFieldParamsOnSend = params => {
params.systemId = systemData.id;
return params;
};
@@ -1227,13 +1229,19 @@ define([
return availableSigs;
},
success: function(response, newValue){
let signatureTypeField = $(this);
let rowElement = signatureTypeField.parents('tr');
if(response){
let signatureTypeField = $(this);
let rowElement = signatureTypeField.parents('tr');
let newRowData = response.signatures[0];
// update "updated" cell
updateSignatureCell(tableApi, rowElement, 7, newRowData.updated);
}else{
// "add new" signature -> set "+" focus for keyboard control
setTimeout(function() {
rowElement.find('.pf-table-action-cell')[0].focus();
}, 50);
}
}
});
@@ -1316,6 +1324,21 @@ define([
}
});
sigGroupFields.on('shown', function(e, editable) {
let inputField = editable.input.$input;
inputField.addClass('pf-select2').initSignatureGroupSelect();
});
sigTypeFields.on('shown', function(e, editable) {
let inputField = editable.input.$input;
inputField.addClass('pf-select2').initSignatureTypeSelect();
});
sigConnectionFields.on('shown', function(e, editable) {
let inputField = editable.input.$input;
inputField.addClass('pf-select2').initSignatureConnectionSelect();
});
// open even
sigDescriptionFields.on('shown', function(e, editable) {
// enlarge the tools-action container because the tables gets bigger
@@ -1333,6 +1356,12 @@ define([
checkConnectionConflicts();
});
$().add(sigNameFields).add(sigGroupFields).add(sigTypeFields)
.add(sigDescriptionFields).add(sigConnectionFields).on('hidden', function(e, editable) {
// re-focus element on close (keyboard navigation)
this.focus();
});
// open next field dialog -------------------------------------------------------------------------------------
openNextEditDialogOnSave(sigNameFields);
openNextEditDialogOnSave(sigGroupFields);
@@ -1537,7 +1566,7 @@ define([
// add static WH(s) for this system
if(systemData.statics){
let staticWHData = [];
for(let wormholeName of systemData.statics) {
for(let wormholeName of systemData.statics){
let wormholeData = Object.assign({}, Init.wormholes[wormholeName]);
let staticWHName = wormholeData.name + ' - ' + wormholeData.security;
@@ -1856,7 +1885,7 @@ define([
// format group filter options
let groups = Object.assign({}, config.signatureGroupsLabels);
for (let [value, label] of Object.entries(groups)){
for(let [value, label] of Object.entries(groups)){
if(label.length){
sourceOptions.push({value: label, text: label});
}
@@ -1920,6 +1949,7 @@ define([
moduleElement.append(table);
let dataTableOptions = {
tabIndex: -1,
dom: '<"row"<"col-xs-3"l><"col-xs-5"B><"col-xs-4"f>>' +
'<"row"<"col-xs-12"tr>>' +
'<"row"<"col-xs-5"i><"col-xs-7"p>>',
@@ -2019,7 +2049,7 @@ define([
searchable: true,
title: 'id',
type: 'html',
width: 30,
width: 15,
data: 'name',
render: {
_: 'render'
@@ -2035,7 +2065,7 @@ define([
searchable: true,
title: 'group',
type: 'html',
width: 50,
width: 40,
data: 'group',
render: {
_: 'group',
@@ -2149,10 +2179,20 @@ define([
let tempTableElement = this;
let rowElement = $(cell).parents('tr');
$(cell).attr('tabindex', 0).on('keydown', function(e){
e.stopPropagation();
if(e.which === 13){
$(this).trigger('click');
}
});
switch(cellData.action){
case 'add':
// add new signature ------------------------------------------------------------------
$(cell).on('click', function(e) {
e.stopPropagation();
e.preventDefault();
// submit all fields within a table row
let formFields = rowElement.find('.editable');
@@ -2249,34 +2289,63 @@ define([
});
};
/**
* open xEditable input field in "new Signature" table
* @param moduleElement
*/
let focusNewSignatureEditableField = moduleElement => {
let secondaryTable = moduleElement.find('.' + config.sigTableSecondaryClass);
secondaryTable.find('.' + config.sigTableEditSigNameInput).editable('show');
};
/**
* set module observer and look for relevant signature data to update
* @param moduleElement
* @param systemData
*/
let setModuleObserver = (moduleElement, systemData) => {
let tablePrimaryElement = moduleElement.find('.' + config.sigTablePrimaryClass);
let signatureTableApi = getDataTableInstanceByModuleElement(moduleElement, 'primary');
let primaryTable = moduleElement.find('.' + config.sigTablePrimaryClass);
let primaryTableApi = getDataTableInstanceByModuleElement(moduleElement, 'primary');
// add signature toggle ---------------------------------------------------------------------------------------
moduleElement.find('.' + config.moduleHeadlineIconAddClass).on('click', function(e){
let button = $(this);
let toggleAddSignature = (show = 'auto') => {
let button = moduleElement.find('.' + config.moduleHeadlineIconAddClass);
let toolsElement = moduleElement.find('.' + config.tableToolsActionClass);
button.toggleClass('active');
button.toggleClass('active', show === 'auto' ? undefined : show);
// set toggle animation
if(toolsElement.is(':visible')){
toolsElement.velocity('stop').velocity('reverse');
}else{
if(toolsElement.is(':visible') && (!show || show === 'auto')){
// hide container
toolsElement.velocity('stop').velocity({
opacity: 1,
height: '75px'
opacity: [0, 1],
height: [0, '70px']
},{
duration: 150,
display: 'none'
});
}else if(!toolsElement.is(':visible') && (show || show === 'auto')){
// show container
toolsElement.velocity('stop').velocity({
opacity: [1, 0],
height: ['70px', 0]
},{
duration: 150,
display: 'block',
visibility: 'visible'
complete: function(){
focusNewSignatureEditableField(moduleElement);
}
});
}else if(toolsElement.is(':visible') && show){
// still visible -> no animation
focusNewSignatureEditableField(moduleElement);
}
};
moduleElement.find('.' + config.moduleHeadlineIconAddClass).on('click', function(e){
toggleAddSignature('auto');
});
moduleElement.on('pf:showSystemSignatureModuleAddNew', function(e){
toggleAddSignature(true);
});
// signature reader dialog ------------------------------------------------------------------------------------
@@ -2291,7 +2360,7 @@ define([
});
// set multi row select ---------------------------------------------------------------------------------------
tablePrimaryElement.on('click', 'tr', {tableApi: signatureTableApi}, function(e){
primaryTable.on('click', 'tr', {tableApi: primaryTableApi}, function(e){
if(e.ctrlKey) {
$(this).toggleClass('selected');
@@ -2301,17 +2370,17 @@ define([
});
// draw event for signature table -----------------------------------------------------------------------------
signatureTableApi.on('draw.dt', function(e, settings){
primaryTableApi.on('draw.dt', function(e, settings){
// check delete button
let tableApi = $(this).dataTable().api();
checkDeleteSignaturesButton(tableApi);
});
// destroy dataTables event -----------------------------------------------------------------------------------
tablePrimaryElement.on('destroy.dt', function(){
primaryTable.on('destroy.dt', function(){
$(this).destroyTimestampCounter();
});
signatureTableApi.on('destroy.dt', function(){
primaryTableApi.on('destroy.dt', function(){
$(this).destroyTimestampCounter();
});

View File

@@ -1017,6 +1017,13 @@ define([
*/
let initDefaultSelect2Config = () => {
$.fn.select2.defaults.set('theme', 'pathfinder');
$.fn.select2.defaults.set('language', {
searching: params => '&nbsp;<i class="fas fa-sync fa-spin"></i>&nbsp;&nbsp;searching...'
});
$.fn.select2.defaults.set('escapeMarkup', markup => {
// required for HTML in options
return markup;
});
let initScrollbar = (resultsWrapper) => {
// default 'mousewheel' event set by select2 needs to be disabled
@@ -1055,10 +1062,9 @@ define([
let getResultsWrapper = (selectElement) => {
let wrapper = null;
let selectElementId = selectElement.getAttribute('data-select2-id');
if(selectElementId){
let resultsOptions = $('#select2-' + selectElementId + '-results');
if(resultsOptions.length) {
if($(selectElement).data('select2')){
let resultsOptions = $(selectElement).data('select2').$results;
if(resultsOptions.length){
let resultsWrapper = resultsOptions.parents('.select2-results');
if(resultsWrapper.length){
wrapper = resultsWrapper;
@@ -1089,7 +1095,7 @@ define([
* set default configuration for "xEditable"
*/
let initDefaultEditableConfig = () => {
// use fontAwesome buttons
// use fontAwesome buttons template
$.fn.editableform.buttons =
'<button type="submit" class="btn btn-primary btn-sm editable-submit">'+
'<i class="fa fa-fw fa-check"></i>'+
@@ -1097,6 +1103,10 @@ define([
'<button type="button" class="btn btn-default btn-sm editable-cancel">'+
'<i class="fa fa-fw fa-times"></i>'+
'</button>';
// loading spinner template
$.fn.editableform.loading =
'<div class="editableform-loading"><i class="fas fa-lg fa-sync fa-spin"></i></div>';
};
/**

View File

@@ -44,7 +44,7 @@ label {
font-weight:normal;
}
*:focus {
*:not(td):focus {
outline: 0 !important;
}

View File

@@ -212,10 +212,13 @@ select:active, select:hover {
.select2-results{
[class*="col-"]{
// smaller and less padding
line-height: 22px;
padding-left: 3px;
padding-right: 3px;
}
.clearfix.pf-result-image [class*="col-"]{
line-height: 22px; // options with images need more height
}
}
.select2{
@@ -236,6 +239,11 @@ select:active, select:hover {
// global dataTable styles ========================================================================
.dataTables_wrapper{
.dataTables_length select{
margin: 0 3px; // <select> for page size
}
.dt-buttons{
.dt-button{
padding: 0 5px; // overwrite default
@@ -269,12 +277,20 @@ select:active, select:hover {
}
}
tr.group{
background-color: rgba($gray-darker, 0.4);
tr {
&.group{
background-color: rgba($gray-darker, 0.4);
}
}
// "special" column styles
td{
&:focus-within{
// set td as :focus even is td content is focused
outline: 1px solid $orange-dark;
background-color: rgba($orange-dark, .1) !important;
outline-offset: -1px;
}
> .fa-circle{
font-size: 9px !important; // should not be "so big" (10px default)
@@ -445,11 +461,11 @@ table{
}
.pf-table-tools-action{
will-change: height, opacity, display;
will-change: height, opacity;
opacity: 0; // triggered by js
display: none; // triggered by js
height: 0;
visibility: hidden;
overflow: hidden;
}
// landing indicator overlay ======================================================================

View File

@@ -38,6 +38,12 @@
vertical-align: middle !important;
}
}
.select2-container{
// Select2 within popover (xEditable field)
margin-top: -1px; // strange UI bug 1px off
margin-left: -1px; // strange UI bug 1px off
}
}
// smaller variant ----------------------------------------------------------------------------------------------------

View File

@@ -84,6 +84,22 @@
text-transform: uppercase;
}
}
.pf-sig-table-secondary{
// columns should be "inline" with primary table
// -> therefore "sortable" must be true even if columns should not be sortable -> now "disable" sortable by CSS
th{
pointer-events: none;
&:after{
display: none !important;
}
&.pf-table-counter-cell{
color: transparent; // hide label for counter columns -> no data here
}
}
}
}
// system graph module =====================================================

View File

@@ -13,7 +13,7 @@
width: 100%;
z-index: 1051;
z-index: 1080;
}
.select2-results {

View File

@@ -46,6 +46,7 @@
.select2-results__option {
padding: 3px 6px;
min-height: 24px; // options with empty string '' should not collapse
&[role=group] {
padding: 0;

View File

@@ -57,6 +57,11 @@
height: 25px;
width: auto;
min-width: 25px;
text-align: center;
i {
margin-top: 10px;
}
}
.editable-inline .editableform-loading {