442
js/app/key.js
Normal file
442
js/app/key.js
Normal file
@@ -0,0 +1,442 @@
|
||||
define([
|
||||
'jquery'
|
||||
], function($) {
|
||||
'use strict';
|
||||
|
||||
let allCombo = {
|
||||
// global -------------------------------------------------------------------------------------------
|
||||
tabReload: {
|
||||
group: 'global',
|
||||
label: 'Close open dialog',
|
||||
keyNames: ['ESC']
|
||||
},
|
||||
// signature ----------------------------------------------------------------------------------------
|
||||
signatureSelect: {
|
||||
group: 'signatures',
|
||||
label: 'Select multiple rows',
|
||||
keyNames: ['CONTROL', 'CLICK']
|
||||
}
|
||||
};
|
||||
|
||||
let allEvents = {
|
||||
// global -------------------------------------------------------------------------------------------
|
||||
tabReload: {
|
||||
group: 'global',
|
||||
label: 'Reload tab',
|
||||
keyNames: ['CONTROL', 'R']
|
||||
},
|
||||
signaturePaste: {
|
||||
group: 'global',
|
||||
label: 'Paste signatures from clipboard',
|
||||
keyNames: ['CONTROL', 'V'],
|
||||
alias: 'paste'
|
||||
},
|
||||
|
||||
// map ----------------------------------------------------------------------------------------------
|
||||
mapSystemAdd: {
|
||||
group: 'map',
|
||||
label: 'Add new system',
|
||||
keyNames: ['CONTROL', 'S']
|
||||
},
|
||||
mapSystemsSelect: {
|
||||
group: 'map',
|
||||
label: 'Select all systems',
|
||||
keyNames: ['CONTROL', 'A']
|
||||
},
|
||||
mapSystemsDelete: {
|
||||
group: 'map',
|
||||
label: 'Delete selected systems',
|
||||
keyNames: ['CONTROL', 'D']
|
||||
}
|
||||
};
|
||||
|
||||
let groups = {
|
||||
global: {
|
||||
label: 'Global'
|
||||
},
|
||||
map: {
|
||||
label: 'Map'
|
||||
},
|
||||
signatures: {
|
||||
label: 'Signature'
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* enables some console.log() information
|
||||
* @type {boolean}
|
||||
*/
|
||||
let debug = false;
|
||||
|
||||
/**
|
||||
* check interval for "new" active keys
|
||||
* @type {number}
|
||||
*/
|
||||
let keyWatchPeriod = 100;
|
||||
|
||||
/**
|
||||
* DOM data key for an element that lists all active events (comma separated)
|
||||
* @type {string}
|
||||
*/
|
||||
let dataKeyEvents = 'key-events';
|
||||
|
||||
/**
|
||||
* DOM data key prefix whether domElement that holds the trigger needs to be "focused"
|
||||
* @type {string}
|
||||
*/
|
||||
let dataKeyFocusPrefix = 'key-focus-';
|
||||
|
||||
/**
|
||||
* DOM data key that holds the callback function for that element
|
||||
* @type {string}
|
||||
*/
|
||||
let dataKeyCallbackPrefix = 'key-callback-';
|
||||
|
||||
/**
|
||||
* check if module is initiated
|
||||
*/
|
||||
let isInit = false;
|
||||
|
||||
/**
|
||||
* global key map holds all active (hold down) keys
|
||||
* @type {{}}
|
||||
*/
|
||||
let map = {};
|
||||
|
||||
/**
|
||||
* show debug information in console
|
||||
* @param msg
|
||||
* @param element
|
||||
*/
|
||||
let debugWatchKey = (msg, element) => {
|
||||
if(debug){
|
||||
console.info(msg, element);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* get all active (hold down) keys at this moment
|
||||
* @returns {Array}
|
||||
*/
|
||||
let getActiveKeys = () => {
|
||||
return Object.keys(map);
|
||||
};
|
||||
|
||||
/**
|
||||
* callback function that compares two arrays
|
||||
* @param element
|
||||
* @param index
|
||||
* @param array
|
||||
*/
|
||||
let compareKeyLists = function(element, index, array) {
|
||||
return this.find(x => x === element);
|
||||
};
|
||||
|
||||
/**
|
||||
* get event names that COULD lead to a "full" event (not all keys pressed yet)
|
||||
* @param keyList
|
||||
* @returns {Array}
|
||||
*/
|
||||
let checkEventNames = (keyList) => {
|
||||
let incompleteEvents = [];
|
||||
for(let event in allEvents){
|
||||
// check if "some" or "all" keys are pressed for en event
|
||||
if( keyList.every(compareKeyLists, allEvents[event].keyNames) ){
|
||||
incompleteEvents.push(event);
|
||||
}
|
||||
}
|
||||
|
||||
return incompleteEvents;
|
||||
};
|
||||
|
||||
/**
|
||||
* get all event names
|
||||
* @returns {Array}
|
||||
*/
|
||||
let getAllEventNames = () => {
|
||||
let eventNames = [];
|
||||
for(let event in allEvents){
|
||||
eventNames.push(event);
|
||||
}
|
||||
return eventNames;
|
||||
};
|
||||
|
||||
/**
|
||||
* get all event names that matches a given keyList
|
||||
* @param keyList
|
||||
* @param checkEvents
|
||||
* @returns {Array}
|
||||
*/
|
||||
let getMatchingEventNames = (keyList, checkEvents) => {
|
||||
checkEvents = checkEvents || getAllEventNames();
|
||||
let events = [];
|
||||
|
||||
for(let event of checkEvents){
|
||||
// check if both key arrays are equal
|
||||
if(
|
||||
allEvents[event].keyNames.every(compareKeyLists, keyList) &&
|
||||
keyList.every(compareKeyLists, allEvents[event].keyNames)
|
||||
){
|
||||
events.push(event);
|
||||
}
|
||||
}
|
||||
|
||||
return events;
|
||||
};
|
||||
|
||||
/**
|
||||
* init global keyWatch interval and check for event trigger (hotKey combinations)
|
||||
*/
|
||||
let init = () => {
|
||||
if( !isInit ){
|
||||
// key watch loop -------------------------------------------------------------------------------
|
||||
let prevActiveKeys = [];
|
||||
|
||||
/**
|
||||
*
|
||||
* @param e
|
||||
* @returns {number} 0: no keys hold, 1: invalid match, 2: partial match, 3: match, 4: alias match, 5: event(s) fired
|
||||
*/
|
||||
let checkForEvents = (e) => {
|
||||
let status = 0;
|
||||
|
||||
// get all pressed keys
|
||||
let activeKeys = getActiveKeys();
|
||||
debugWatchKey('activeKeys', activeKeys);
|
||||
|
||||
// check if "active" keys has changes since last loop
|
||||
if(activeKeys.length){
|
||||
// check for "incomplete" events (not all keys pressed yet)
|
||||
let incompleteEvents = checkEventNames(activeKeys);
|
||||
if(incompleteEvents.length){
|
||||
// "some" event keys pressed OR "all" keys pressed
|
||||
status = 2;
|
||||
|
||||
// check if key combo matches a registered (valid) event
|
||||
let events = getMatchingEventNames(activeKeys, incompleteEvents);
|
||||
if(events.length){
|
||||
status = 3;
|
||||
// check events if there are attached elements to it
|
||||
events.forEach((event) => {
|
||||
// skip events that has an alias and should not be triggered by key combo
|
||||
if( !allEvents[event].alias ){
|
||||
if(allEvents[event].elements){
|
||||
// search for callback functions attached to each element
|
||||
allEvents[event].elements.forEach((domElement) => {
|
||||
let domElementObj = $(domElement);
|
||||
// check if event on this element requires active "focus"
|
||||
let optFocus = domElementObj.data(dataKeyFocusPrefix + event);
|
||||
|
||||
if( !(
|
||||
optFocus &&
|
||||
document.activeElement !== domElement
|
||||
)
|
||||
){
|
||||
// execute callback if valid
|
||||
let callback = domElementObj.data(dataKeyCallbackPrefix + event);
|
||||
if(typeof callback === 'function'){
|
||||
status = 5;
|
||||
callback.call(domElement, domElement, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}else{
|
||||
status = 4;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}else{
|
||||
// invalid combo
|
||||
status = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// store current keys for next loop check
|
||||
prevActiveKeys = activeKeys;
|
||||
|
||||
return status;
|
||||
};
|
||||
|
||||
// set key-events -------------------------------------------------------------------------------
|
||||
let evKeyDown = (e) => {
|
||||
// exclude some HTML Tags from watcher
|
||||
if(
|
||||
e.target.tagName !== 'INPUT' &&
|
||||
e.target.tagName !== 'TEXTAREA'
|
||||
){
|
||||
let key = e.key.toUpperCase();
|
||||
map[key] = true;
|
||||
|
||||
// check for any shortcut combo that triggers an event
|
||||
let status = checkForEvents(e);
|
||||
|
||||
if(
|
||||
status === 2 ||
|
||||
status === 3 ||
|
||||
status === 5
|
||||
){
|
||||
// prevent SOME browser default actions -> we want 'Pathfinder' shortcuts :)
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let evKeyUp = (e) => {
|
||||
let key = e.key.toUpperCase();
|
||||
|
||||
if(map.hasOwnProperty(key)){
|
||||
delete map[key];
|
||||
}
|
||||
};
|
||||
|
||||
let container = $('body');
|
||||
container.on('keydown', evKeyDown);
|
||||
container.on('keyup', evKeyUp);
|
||||
|
||||
// global dom remove listener -------------------------------------------------------------------
|
||||
// -> check whether the removed element had an event listener active and removes them.
|
||||
document.body.addEventListener ('DOMNodeRemoved', function(e){
|
||||
if(typeof e.target.getAttribute === 'function'){
|
||||
let eventNames = e.target.getAttribute(dataKeyEvents);
|
||||
if(eventNames){
|
||||
eventNames.split(',').forEach((event) => {
|
||||
let index = allEvents[event].elements.indexOf(e.target);
|
||||
if(index > -1){
|
||||
// remove element from event list
|
||||
allEvents[event].elements.splice(index, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
|
||||
isInit = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* add a new "shortCut" combination (event) to a DOM element
|
||||
* @param event
|
||||
* @param callback
|
||||
* @param options
|
||||
*/
|
||||
$.fn.watchKey = function(event, callback, options){
|
||||
|
||||
// default options for keyWatcher on elements
|
||||
let defaultOptions = {
|
||||
focus: false, // element must be focused (active)
|
||||
bubbling: true // elements deeper (children) in the DOM can bubble the event up
|
||||
};
|
||||
|
||||
let customOptions = $.extend(true, {}, defaultOptions, options );
|
||||
|
||||
return this.each((i, domElement) => {
|
||||
let element = $(domElement);
|
||||
|
||||
// init global key events
|
||||
init();
|
||||
|
||||
// check if event is "valid" (exists) and is not already set for this element
|
||||
let validEvent = false;
|
||||
if(allEvents[event].elements){
|
||||
if(allEvents[event].elements.indexOf(domElement) === -1){
|
||||
validEvent = true;
|
||||
}else{
|
||||
console.warn('Event "' + event + '" already set');
|
||||
}
|
||||
}else{
|
||||
validEvent = true;
|
||||
allEvents[event].elements = [];
|
||||
}
|
||||
|
||||
if(validEvent){
|
||||
// store callback options to dom element
|
||||
if(customOptions.focus){
|
||||
let dataAttr = dataKeyFocusPrefix + event;
|
||||
element.data(dataAttr, true);
|
||||
|
||||
// check if DOM element has "tabindex" attr -> required to manually set focus() to it
|
||||
if(!domElement.hasAttribute('tabindex')){
|
||||
domElement.setAttribute('tabindex', 0);
|
||||
}
|
||||
|
||||
// element requires a "focus" listener
|
||||
element.off('click.focusKeyWatcher').on('click.focusKeyWatcher', function(e){
|
||||
if(
|
||||
e.target === this ||
|
||||
customOptions.bubbling
|
||||
){
|
||||
this.focus();
|
||||
debugWatchKey('focus set:', this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// check if is key combo has a native JS event that should be used instead
|
||||
if(allEvents[event].alias){
|
||||
element.on(allEvents[event].alias, callback);
|
||||
}else{
|
||||
// store callback function to dom element
|
||||
let dataAttr = dataKeyCallbackPrefix + event;
|
||||
element.data(dataAttr, callback);
|
||||
}
|
||||
|
||||
// add eventName to dom element as attribute ----------------------------------------------------
|
||||
let currentEventNames = element.attr(dataKeyEvents) ? element.attr(dataKeyEvents).split(',') : [];
|
||||
currentEventNames.push(event);
|
||||
element.attr(dataKeyEvents, currentEventNames.join(','));
|
||||
|
||||
// store domElement to event (global)
|
||||
allEvents[event].elements.push(domElement);
|
||||
|
||||
debugWatchKey('new event "' + event + '" registered', domElement);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* get a array with all available shortcut groups and their events
|
||||
* @returns {Array}
|
||||
*/
|
||||
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];
|
||||
|
||||
//format keyNames for UI
|
||||
let keyNames = data.keyNames.map( (key) => {
|
||||
if(key === 'CONTROL'){
|
||||
key = 'ctrl';
|
||||
}
|
||||
return key;
|
||||
});
|
||||
|
||||
let newEventData = {
|
||||
label: data.label,
|
||||
keyNames: keyNames
|
||||
};
|
||||
|
||||
if( result[data.group].events ){
|
||||
result[data.group].events.push(newEventData);
|
||||
}else{
|
||||
result[data.group].events = [newEventData];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert obj into array
|
||||
result = Object.values(result);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
return {
|
||||
getGroupedShortcuts: getGroupedShortcuts
|
||||
};
|
||||
});
|
||||
@@ -22,10 +22,6 @@ define([
|
||||
|
||||
let config = {
|
||||
zIndexCounter: 110,
|
||||
newSystemOffset: {
|
||||
x: 130,
|
||||
y: 0
|
||||
},
|
||||
|
||||
mapSnapToGrid: false, // "Snap to Grid" feature for drag&drop systems on map (optional)
|
||||
mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable)
|
||||
@@ -1372,6 +1368,205 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* save a new system and add it to the map
|
||||
* @param map
|
||||
* @param requestData
|
||||
* @param sourceSystem
|
||||
* @param callback
|
||||
*/
|
||||
let saveSystem = function(map, requestData, sourceSystem, callback){
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Init.path.saveSystem,
|
||||
data: requestData,
|
||||
dataType: 'json',
|
||||
context: {
|
||||
map: map,
|
||||
sourceSystem: sourceSystem
|
||||
}
|
||||
}).done(function(newSystemData){
|
||||
Util.showNotify({title: 'New system', text: newSystemData.name, type: 'success'});
|
||||
|
||||
// draw new system to map
|
||||
drawSystem(this.map, newSystemData, this.sourceSystem);
|
||||
|
||||
// re/arrange systems (prevent overlapping)
|
||||
MagnetizerWrapper.setElements(this.map);
|
||||
|
||||
if(callback){
|
||||
callback();
|
||||
}
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
let reason = status + ' ' + error;
|
||||
Util.showNotify({title: jqXHR.status + ': saveSystem', text: reason, type: 'warning'});
|
||||
$(document).setProgramStatus('problem');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* open "new system" dialog and add the system to map
|
||||
* optional the new system is connected to a "sourceSystem" (if available)
|
||||
*
|
||||
* @param map
|
||||
* @param options
|
||||
*/
|
||||
let showNewSystemDialog = function(map, options){
|
||||
let mapContainer = $(map.getContainer());
|
||||
|
||||
// format system status for form select -------------------------------------------------------------
|
||||
let systemStatus = {};
|
||||
// "default" selection (id = 0) prevents status from being overwritten
|
||||
// -> e.g. keep status information if system was just inactive (active = 0)
|
||||
systemStatus[0] = 'default';
|
||||
|
||||
$.each(Init.systemStatus, function(status, statusData){
|
||||
systemStatus[statusData.id] = statusData.label;
|
||||
});
|
||||
|
||||
// default system status -> first status entry
|
||||
let defaultSystemStatus = 0;
|
||||
|
||||
// get current map data -----------------------------------------------------------------------------
|
||||
let mapData = mapContainer.getMapDataFromClient({forceData: true});
|
||||
let mapSystems = mapData.data.systems;
|
||||
let mapSystemCount = mapSystems.length;
|
||||
let mapTypeName = mapContainer.data('typeName');
|
||||
let maxAllowedSystems = Init.mapTypes[mapTypeName].defaultConfig.max_systems;
|
||||
|
||||
// show error if system max count reached -----------------------------------------------------------
|
||||
if(mapSystemCount >= maxAllowedSystems){
|
||||
Util.showNotify({title: 'Max system count exceeded', text: 'Limit of ' + maxAllowedSystems + ' systems reached', type: 'warning'});
|
||||
return;
|
||||
}
|
||||
|
||||
// disable systems that are already on it -----------------------------------------------------------
|
||||
let mapSystemIds = [];
|
||||
for(let i = 0; i < mapSystems.length; i++ ){
|
||||
mapSystemIds.push( mapSystems[i].systemId );
|
||||
}
|
||||
|
||||
// dialog data --------------------------------------------------------------------------------------
|
||||
let data = {
|
||||
id: config.systemDialogId,
|
||||
selectClass: config.systemDialogSelectClass
|
||||
};
|
||||
|
||||
// set current position as "default" system to add --------------------------------------------------
|
||||
let currentCharacterLog = Util.getCurrentCharacterLog();
|
||||
|
||||
if(
|
||||
currentCharacterLog !== false &&
|
||||
mapSystemIds.indexOf( currentCharacterLog.system.id ) === -1
|
||||
){
|
||||
// current system is NOT already on this map
|
||||
// set current position as "default" system to add
|
||||
data.currentSystem = currentCharacterLog.system;
|
||||
}
|
||||
|
||||
requirejs(['text!templates/dialog/system.html', 'mustache'], function(template, Mustache) {
|
||||
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
let systemDialog = bootbox.dialog({
|
||||
title: 'Add new system',
|
||||
message: content,
|
||||
buttons: {
|
||||
close: {
|
||||
label: 'cancel',
|
||||
className: 'btn-default'
|
||||
},
|
||||
success: {
|
||||
label: '<i class="fa fa-fw fa-check"></i> save',
|
||||
className: 'btn-success',
|
||||
callback: function (e) {
|
||||
// get form Values
|
||||
let form = $('#' + config.systemDialogId).find('form');
|
||||
|
||||
let systemDialogData = $(form).getFormValues();
|
||||
|
||||
// validate form
|
||||
form.validator('validate');
|
||||
|
||||
// check whether the form is valid
|
||||
let formValid = form.isValidForm();
|
||||
|
||||
if(formValid === false){
|
||||
// don't close dialog
|
||||
return false;
|
||||
}
|
||||
|
||||
// calculate new system position ------------------------------------------------
|
||||
let newPosition = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
|
||||
let sourceSystem = null;
|
||||
|
||||
// add new position
|
||||
if(options.sourceSystem !== undefined){
|
||||
|
||||
sourceSystem = options.sourceSystem;
|
||||
|
||||
// get new position
|
||||
newPosition = System.calculateNewSystemPosition(sourceSystem);
|
||||
}else{
|
||||
// check mouse cursor position (add system to map)
|
||||
newPosition = {
|
||||
x: options.position.x,
|
||||
y: options.position.y
|
||||
};
|
||||
}
|
||||
|
||||
systemDialogData.position = newPosition;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
let requestData = {
|
||||
systemData: systemDialogData,
|
||||
mapData: {
|
||||
id: mapContainer.data('id')
|
||||
}
|
||||
};
|
||||
|
||||
saveSystem(map, requestData, sourceSystem, function(){
|
||||
bootbox.hideAll();
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// init dialog
|
||||
systemDialog.on('shown.bs.modal', function(e) {
|
||||
|
||||
let modalContent = $('#' + config.systemDialogId);
|
||||
|
||||
// init system select live search - some delay until modal transition has finished
|
||||
let selectElement = modalContent.find('.' + config.systemDialogSelectClass);
|
||||
selectElement.delay(240).initSystemSelect({
|
||||
key: 'systemId',
|
||||
disabledOptions: mapSystemIds
|
||||
});
|
||||
});
|
||||
|
||||
// init system status select
|
||||
let modalFields = $('.bootbox .modal-dialog').find('.pf-editable-system-status');
|
||||
|
||||
modalFields.editable({
|
||||
mode: 'inline',
|
||||
emptytext: 'unknown',
|
||||
onblur: 'submit',
|
||||
showbuttons: false,
|
||||
source: systemStatus,
|
||||
value: defaultSystemStatus,
|
||||
inputclass: config.systemDialogSelectClass
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* make a system name/alias editable by x-editable
|
||||
* @param system
|
||||
@@ -1806,169 +2001,6 @@ define([
|
||||
return activeOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* open "new system" dialog and add the system to map
|
||||
* optional the new system is connected to a "sourceSystem" (if available)
|
||||
*
|
||||
* @param map
|
||||
* @param options
|
||||
*/
|
||||
let showNewSystemDialog = function(map, options){
|
||||
let mapContainer = $(map.getContainer());
|
||||
|
||||
// format system status for form select -------------------------------------------------------------
|
||||
let systemStatus = {};
|
||||
// "default" selection (id = 0) prevents status from being overwritten
|
||||
// -> e.g. keep status information if system was just inactive (active = 0)
|
||||
systemStatus[0] = 'default';
|
||||
|
||||
$.each(Init.systemStatus, function(status, statusData){
|
||||
systemStatus[statusData.id] = statusData.label;
|
||||
});
|
||||
|
||||
// default system status -> first status entry
|
||||
let defaultSystemStatus = 0;
|
||||
|
||||
// get current map data -----------------------------------------------------------------------------
|
||||
let mapData = mapContainer.getMapDataFromClient({forceData: true});
|
||||
let mapSystems = mapData.data.systems;
|
||||
let mapSystemCount = mapSystems.length;
|
||||
let mapTypeName = mapContainer.data('typeName');
|
||||
let maxAllowedSystems = Init.mapTypes[mapTypeName].defaultConfig.max_systems;
|
||||
|
||||
// show error if system max count reached -----------------------------------------------------------
|
||||
if(mapSystemCount >= maxAllowedSystems){
|
||||
Util.showNotify({title: 'Max system count exceeded', text: 'Limit of ' + maxAllowedSystems + ' systems reached', type: 'warning'});
|
||||
return;
|
||||
}
|
||||
|
||||
// disable systems that are already on it -----------------------------------------------------------
|
||||
let mapSystemIds = [];
|
||||
for(let i = 0; i < mapSystems.length; i++ ){
|
||||
mapSystemIds.push( mapSystems[i].systemId );
|
||||
}
|
||||
|
||||
// dialog data --------------------------------------------------------------------------------------
|
||||
let data = {
|
||||
id: config.systemDialogId,
|
||||
selectClass: config.systemDialogSelectClass
|
||||
};
|
||||
|
||||
// set current position as "default" system to add --------------------------------------------------
|
||||
let currentCharacterLog = Util.getCurrentCharacterLog();
|
||||
|
||||
if(
|
||||
currentCharacterLog !== false &&
|
||||
mapSystemIds.indexOf( currentCharacterLog.system.id ) === -1
|
||||
){
|
||||
// current system is NOT already on this map
|
||||
// set current position as "default" system to add
|
||||
data.currentSystem = currentCharacterLog.system;
|
||||
}
|
||||
|
||||
requirejs(['text!templates/dialog/system.html', 'mustache'], function(template, Mustache) {
|
||||
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
let systemDialog = bootbox.dialog({
|
||||
title: 'Add new system',
|
||||
message: content,
|
||||
buttons: {
|
||||
close: {
|
||||
label: 'cancel',
|
||||
className: 'btn-default'
|
||||
},
|
||||
success: {
|
||||
label: '<i class="fa fa-fw fa-check"></i> save',
|
||||
className: 'btn-success',
|
||||
callback: function (e) {
|
||||
// get form Values
|
||||
let form = $('#' + config.systemDialogId).find('form');
|
||||
|
||||
let systemDialogData = $(form).getFormValues();
|
||||
|
||||
// validate form
|
||||
form.validator('validate');
|
||||
|
||||
// check whether the form is valid
|
||||
let formValid = form.isValidForm();
|
||||
|
||||
if(formValid === false){
|
||||
// don't close dialog
|
||||
return false;
|
||||
}
|
||||
|
||||
// calculate new system position ------------------------------------------------
|
||||
let newPosition = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
|
||||
let sourceSystem = null;
|
||||
|
||||
// add new position
|
||||
if(options.sourceSystem !== undefined){
|
||||
|
||||
sourceSystem = options.sourceSystem;
|
||||
|
||||
// get new position
|
||||
newPosition = calculateNewSystemPosition(sourceSystem);
|
||||
}else{
|
||||
// check mouse cursor position (add system to map)
|
||||
newPosition = {
|
||||
x: options.position.x,
|
||||
y: options.position.y
|
||||
};
|
||||
}
|
||||
|
||||
systemDialogData.position = newPosition;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
let requestData = {
|
||||
systemData: systemDialogData,
|
||||
mapData: {
|
||||
id: mapContainer.data('id')
|
||||
}
|
||||
};
|
||||
|
||||
saveSystem(map, requestData, sourceSystem, function(){
|
||||
bootbox.hideAll();
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// init dialog
|
||||
systemDialog.on('shown.bs.modal', function(e) {
|
||||
|
||||
let modalContent = $('#' + config.systemDialogId);
|
||||
|
||||
// init system select live search - some delay until modal transition has finished
|
||||
let selectElement = modalContent.find('.' + config.systemDialogSelectClass);
|
||||
selectElement.delay(240).initSystemSelect({
|
||||
key: 'systemId',
|
||||
disabledOptions: mapSystemIds
|
||||
});
|
||||
});
|
||||
|
||||
// init system status select
|
||||
let modalFields = $('.bootbox .modal-dialog').find('.pf-editable-system-status');
|
||||
|
||||
modalFields.editable({
|
||||
mode: 'inline',
|
||||
emptytext: 'unknown',
|
||||
onblur: 'submit',
|
||||
showbuttons: false,
|
||||
source: systemStatus,
|
||||
value: defaultSystemStatus,
|
||||
inputclass: config.systemDialogSelectClass
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* set up all actions that can be preformed on a system
|
||||
* @param map
|
||||
@@ -2354,6 +2386,28 @@ define([
|
||||
$(tabContentElement).trigger('pf:drawSystemModules');
|
||||
};
|
||||
|
||||
/**
|
||||
* select all (selectable) systems on a mapElement
|
||||
*/
|
||||
$.fn.selectAllSystems = function(){
|
||||
return this.each(function(){
|
||||
let mapElement = $(this);
|
||||
let map = getMapInstance(mapElement.data('id'));
|
||||
|
||||
let allSystems = mapElement.find('.' + config.systemClass + ':not(.' + config.systemSelectedClass + ')');
|
||||
|
||||
// filter non-locked systems
|
||||
allSystems = allSystems.filter(function(i, el){
|
||||
return ( $(el).data('locked') !== true );
|
||||
});
|
||||
|
||||
allSystems.toggleSelectSystem(map);
|
||||
|
||||
Util.showNotify({title: allSystems.length + ' systems selected', type: 'success'});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* toggle selectable status of a system
|
||||
*/
|
||||
@@ -2376,15 +2430,6 @@ define([
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* get all selected (NOT active) systems in a map
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.getSelectedSystems = function(){
|
||||
let mapElement = $(this);
|
||||
return mapElement.find('.' + config.systemSelectedClass);
|
||||
};
|
||||
|
||||
/**
|
||||
* toggle log status of a system
|
||||
* @param poke
|
||||
@@ -2613,17 +2658,7 @@ define([
|
||||
showNewSystemDialog(currentMap, {position: position});
|
||||
break;
|
||||
case 'select_all':
|
||||
|
||||
let allSystems = currentMapElement.find('.' + config.systemClass + ':not(.' + config.systemSelectedClass + ')');
|
||||
|
||||
// filter non-locked systems
|
||||
allSystems = allSystems.filter(function(i, el){
|
||||
return ( $(el).data('locked') !== true );
|
||||
});
|
||||
|
||||
allSystems.toggleSelectSystem(currentMap);
|
||||
|
||||
Util.showNotify({title: allSystems.length + ' systems selected', type: 'success'});
|
||||
currentMapElement.selectAllSystems();
|
||||
break;
|
||||
case 'filter_wh':
|
||||
case 'filter_stargate':
|
||||
@@ -2890,65 +2925,6 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* save a new system and add it to the map
|
||||
* @param map
|
||||
* @param requestData
|
||||
* @param sourceSystem
|
||||
* @param callback
|
||||
*/
|
||||
let saveSystem = function(map, requestData, sourceSystem, callback){
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Init.path.saveSystem,
|
||||
data: requestData,
|
||||
dataType: 'json',
|
||||
context: {
|
||||
map: map,
|
||||
sourceSystem: sourceSystem
|
||||
}
|
||||
}).done(function(newSystemData){
|
||||
Util.showNotify({title: 'New system', text: newSystemData.name, type: 'success'});
|
||||
|
||||
// draw new system to map
|
||||
drawSystem(this.map, newSystemData, this.sourceSystem);
|
||||
|
||||
// re/arrange systems (prevent overlapping)
|
||||
MagnetizerWrapper.setElements(this.map);
|
||||
|
||||
if(callback){
|
||||
callback();
|
||||
}
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
let reason = status + ' ' + error;
|
||||
Util.showNotify({title: jqXHR.status + ': saveSystem', text: reason, type: 'warning'});
|
||||
$(document).setProgramStatus('problem');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* calculate the x/y coordinates for a new system - relativ to a source system
|
||||
* @param sourceSystem
|
||||
* @returns {{x: *, y: *}}
|
||||
*/
|
||||
let calculateNewSystemPosition = function(sourceSystem){
|
||||
|
||||
// related system is available
|
||||
let currentX = sourceSystem.css('left');
|
||||
let currentY = sourceSystem.css('top');
|
||||
|
||||
// remove "px"
|
||||
currentX = parseInt( currentX.substring(0, currentX.length - 2) );
|
||||
currentY = parseInt( currentY.substring(0, currentY.length - 2) );
|
||||
|
||||
let newPosition = {
|
||||
x: currentX + config.newSystemOffset.x,
|
||||
y: currentY + config.newSystemOffset.y
|
||||
};
|
||||
|
||||
return newPosition;
|
||||
};
|
||||
|
||||
/**
|
||||
* updates all systems on map with current user Data (all users on this map)
|
||||
* update the Data of the user that is currently viewing the map (if available)
|
||||
@@ -3244,9 +3220,13 @@ define([
|
||||
// init custom scrollbars and add overlay
|
||||
parentElement.initMapScrollbar();
|
||||
|
||||
let mapElement = $(mapConfig.map.getContainer());
|
||||
|
||||
// set shortcuts
|
||||
parentElement.find('.' + config.mapWrapperClass).setMapShortcuts();
|
||||
|
||||
// show static overlay actions
|
||||
let mapElement = mapConfig.map.getContainer();
|
||||
let mapOverlay = $(mapElement).getMapOverlay('info');
|
||||
let mapOverlay = mapElement.getMapOverlay('info');
|
||||
mapOverlay.updateOverlayIcon('systemRegion', 'show');
|
||||
mapOverlay.updateOverlayIcon('connection', 'show');
|
||||
mapOverlay.updateOverlayIcon('connectionEol', 'show');
|
||||
@@ -3344,7 +3324,8 @@ define([
|
||||
return {
|
||||
getMapInstance: getMapInstance,
|
||||
clearMapInstance: clearMapInstance,
|
||||
getDataByConnection: getDataByConnection
|
||||
getDataByConnection: getDataByConnection,
|
||||
showNewSystemDialog: showNewSystemDialog
|
||||
};
|
||||
|
||||
});
|
||||
@@ -13,6 +13,11 @@ define([
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
newSystemOffset: {
|
||||
x: 130,
|
||||
y: 0
|
||||
},
|
||||
|
||||
systemActiveClass: 'pf-system-active' // class for an active system in a map
|
||||
};
|
||||
|
||||
@@ -193,8 +198,32 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* calculate the x/y coordinates for a new system - relativ to a source system
|
||||
* @param sourceSystem
|
||||
* @returns {{x: *, y: *}}
|
||||
*/
|
||||
let calculateNewSystemPosition = function(sourceSystem){
|
||||
|
||||
// related system is available
|
||||
let currentX = sourceSystem.css('left');
|
||||
let currentY = sourceSystem.css('top');
|
||||
|
||||
// remove "px"
|
||||
currentX = parseInt( currentX.substring(0, currentX.length - 2) );
|
||||
currentY = parseInt( currentY.substring(0, currentY.length - 2) );
|
||||
|
||||
let newPosition = {
|
||||
x: currentX + config.newSystemOffset.x,
|
||||
y: currentY + config.newSystemOffset.y
|
||||
};
|
||||
|
||||
return newPosition;
|
||||
};
|
||||
|
||||
return {
|
||||
deleteSystems: deleteSystems,
|
||||
removeSystems: removeSystems
|
||||
removeSystems: removeSystems,
|
||||
calculateNewSystemPosition: calculateNewSystemPosition
|
||||
};
|
||||
});
|
||||
@@ -5,8 +5,9 @@
|
||||
define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util'
|
||||
], function($, Init, Util) {
|
||||
'app/util',
|
||||
'bootbox'
|
||||
], function($, Init, Util, bootbox) {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
@@ -17,9 +18,12 @@ define([
|
||||
mapLocalStoragePrefix: 'map_', // prefix for map data local storage key
|
||||
mapTabContentClass: 'pf-map-tab-content', // Tab-Content element (parent element)
|
||||
|
||||
mapClass: 'pf-map', // class for all maps
|
||||
mapGridClass: 'pf-grid-small', // class for map grid snapping
|
||||
|
||||
systemIdPrefix: 'pf-system-', // id prefix for a system
|
||||
systemClass: 'pf-system', // class for all systems
|
||||
mapGridClass: 'pf-grid-small' // class for map grid snapping
|
||||
systemSelectedClass: 'pf-system-selected' // class for selected systems in a map
|
||||
};
|
||||
|
||||
// map menu options
|
||||
@@ -198,6 +202,15 @@ define([
|
||||
return this.find('.' + config.systemClass);
|
||||
};
|
||||
|
||||
/**
|
||||
* get all selected (NOT active) systems in a map
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.getSelectedSystems = function(){
|
||||
let mapElement = $(this);
|
||||
return mapElement.find('.' + config.systemSelectedClass);
|
||||
};
|
||||
|
||||
/**
|
||||
* search connections by systems
|
||||
* @param {Object} map - jsPlumb
|
||||
@@ -577,6 +590,40 @@ define([
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* set map "shortcut" events
|
||||
*/
|
||||
$.fn.setMapShortcuts = function(){
|
||||
return this.each((i, mapWrapper) => {
|
||||
mapWrapper = $(mapWrapper);
|
||||
let mapElement = mapWrapper.findMapElement();
|
||||
|
||||
// dynamic require Map module -> otherwise there is a require(), loop
|
||||
let Map = require('app/map/map');
|
||||
let map = Map.getMapInstance( mapElement.data('id'));
|
||||
|
||||
mapWrapper.watchKey('mapSystemAdd', (mapWrapper) => {
|
||||
console.log('mapSystemAdd');
|
||||
Map.showNewSystemDialog(map, {position: {x: 0, y: 0}});
|
||||
},{focus: true});
|
||||
|
||||
mapWrapper.watchKey('mapSystemsSelect', (mapWrapper) => {
|
||||
mapElement.selectAllSystems();
|
||||
},{focus: true});
|
||||
|
||||
mapWrapper.watchKey('mapSystemsDelete', (mapWrapper) => {
|
||||
console.log('mapSystemsDelete');
|
||||
let selectedSystems = mapElement.getSelectedSystems();
|
||||
$.fn.showDeleteSystemDialog(map, selectedSystems);
|
||||
},{focus: true});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.findMapElement = function(){
|
||||
return $(this).find('.' + config.mapClass);
|
||||
};
|
||||
|
||||
/**
|
||||
* get systemId string (selector
|
||||
* @param mapId
|
||||
|
||||
@@ -10,6 +10,7 @@ define([
|
||||
'app/logging',
|
||||
'app/page',
|
||||
'app/map/worker',
|
||||
'app/key',
|
||||
'app/ui/form_element',
|
||||
'app/module_map'
|
||||
], ($, Init, Util, Render, Logging, Page, MapWorker) => {
|
||||
@@ -30,7 +31,7 @@ define([
|
||||
|
||||
// load page
|
||||
// load info (maintenance) info panel (if scheduled)
|
||||
$('body').loadPageStructure();
|
||||
$('body').loadPageStructure().setGlobalShortcuts();
|
||||
|
||||
// show app information in browser console
|
||||
Util.showVersionInfo();
|
||||
|
||||
146
js/app/page.js
146
js/app/page.js
@@ -16,6 +16,7 @@ define([
|
||||
'dialog/map_info',
|
||||
'dialog/account_settings',
|
||||
'dialog/manual',
|
||||
'dialog/shortcuts',
|
||||
'dialog/map_settings',
|
||||
'dialog/system_effects',
|
||||
'dialog/jump_info',
|
||||
@@ -62,7 +63,10 @@ define([
|
||||
menuHeadMenuLogoClass: 'pf-head-menu-logo', // class for main menu logo
|
||||
|
||||
// helper element
|
||||
dynamicElementWrapperId: 'pf-dialog-wrapper'
|
||||
dynamicElementWrapperId: 'pf-dialog-wrapper',
|
||||
|
||||
// system signature module
|
||||
systemSigModuleClass: 'pf-sig-table-module', // module wrapper (signatures)
|
||||
};
|
||||
|
||||
let programStatusCounter = 0; // current count down in s until next status change is possible
|
||||
@@ -74,49 +78,83 @@ define([
|
||||
* @returns {*|jQuery|HTMLElement}
|
||||
*/
|
||||
$.fn.loadPageStructure = function(){
|
||||
let body = $(this);
|
||||
return this.each((i, body) => {
|
||||
body = $(body);
|
||||
|
||||
// menu left
|
||||
body.prepend(
|
||||
$('<div>', {
|
||||
class: [config.pageSlidebarClass, config.pageSlidebarLeftClass, 'sb-style-push', 'sb-width-custom'].join(' ')
|
||||
}).attr('data-sb-width', config.pageSlideLeftWidth)
|
||||
);
|
||||
|
||||
// menu right
|
||||
body.prepend(
|
||||
$('<div>', {
|
||||
class: [config.pageSlidebarClass, config.pageSlidebarRightClass, 'sb-style-push', 'sb-width-custom'].join(' ')
|
||||
}).attr('data-sb-width', config.pageSlideRightWidth)
|
||||
);
|
||||
|
||||
// main page
|
||||
body.prepend(
|
||||
$('<div>', {
|
||||
id: config.pageId,
|
||||
class: config.pageClass
|
||||
}).append(
|
||||
Util.getMapModule()
|
||||
).append(
|
||||
// menu left
|
||||
body.prepend(
|
||||
$('<div>', {
|
||||
id: config.dynamicElementWrapperId
|
||||
})
|
||||
)
|
||||
);
|
||||
class: [config.pageSlidebarClass, config.pageSlidebarLeftClass, 'sb-style-push', 'sb-width-custom'].join(' ')
|
||||
}).attr('data-sb-width', config.pageSlideLeftWidth)
|
||||
);
|
||||
|
||||
// load header / footer
|
||||
$('.' + config.pageClass).loadHeader().loadFooter();
|
||||
// menu right
|
||||
body.prepend(
|
||||
$('<div>', {
|
||||
class: [config.pageSlidebarClass, config.pageSlidebarRightClass, 'sb-style-push', 'sb-width-custom'].join(' ')
|
||||
}).attr('data-sb-width', config.pageSlideRightWidth)
|
||||
);
|
||||
|
||||
// load left menu
|
||||
$('.' + config.pageSlidebarLeftClass).loadLeftMenu();
|
||||
// main page
|
||||
body.prepend(
|
||||
$('<div>', {
|
||||
id: config.pageId,
|
||||
class: config.pageClass
|
||||
}).append(
|
||||
Util.getMapModule()
|
||||
).append(
|
||||
$('<div>', {
|
||||
id: config.dynamicElementWrapperId
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
// load right menu
|
||||
$('.' + config.pageSlidebarRightClass).loadRightMenu();
|
||||
// load header / footer
|
||||
$('.' + config.pageClass).loadHeader().loadFooter();
|
||||
|
||||
// set document observer for global events
|
||||
setDocumentObserver();
|
||||
// load left menu
|
||||
$('.' + config.pageSlidebarLeftClass).loadLeftMenu();
|
||||
|
||||
return body;
|
||||
// load right menu
|
||||
$('.' + config.pageSlidebarRightClass).loadRightMenu();
|
||||
|
||||
// set document observer for global events
|
||||
setDocumentObserver();
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.setGlobalShortcuts = function(){
|
||||
return this.each((i, body) => {
|
||||
body = $(body);
|
||||
|
||||
console.log('setGlobalShortcuts');
|
||||
|
||||
body.watchKey('tabReload', (body) => {
|
||||
location.reload();
|
||||
});
|
||||
|
||||
body.watchKey('signaturePaste', (e) => {
|
||||
let moduleElement = $('.' + config.systemSigModuleClass);
|
||||
|
||||
// check if there is a signature module active (system clicked)
|
||||
if(moduleElement.length){
|
||||
e = e.originalEvent;
|
||||
let targetElement = $(e.target);
|
||||
|
||||
// do not read clipboard if pasting into form elements
|
||||
if(
|
||||
targetElement.prop('tagName').toLowerCase() !== 'input' &&
|
||||
targetElement.prop('tagName').toLowerCase() !== 'textarea' || (
|
||||
targetElement.is('input[type="search"]') // Datatables "search" field bubbles `paste.DT` event :(
|
||||
)
|
||||
){
|
||||
let clipboard = (e.originalEvent || e).clipboardData.getData('text/plain');
|
||||
moduleElement.trigger('pf:updateSystemSignatureModuleByClipboard', [clipboard]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -355,6 +393,22 @@ define([
|
||||
).on('click', function(){
|
||||
$(document).triggerMenuEvent('Manual');
|
||||
})
|
||||
).append(
|
||||
$('<a>', {
|
||||
class: 'list-group-item list-group-item-info',
|
||||
href: '#'
|
||||
}).html(' Shortcuts').prepend(
|
||||
$('<i>',{
|
||||
class: 'fa fa-keyboard-o fa-fw'
|
||||
})
|
||||
).append(
|
||||
$('<span>',{
|
||||
class: 'badge bg-color bg-color-gray txt-color txt-color-warning',
|
||||
text: 'beta'
|
||||
})
|
||||
).on('click', function(){
|
||||
$(document).triggerMenuEvent('Shortcuts');
|
||||
})
|
||||
).append(
|
||||
$('<a>', {
|
||||
class: 'list-group-item list-group-item-info',
|
||||
@@ -586,6 +640,18 @@ define([
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on('pf:menuShowTaskManager', function(e, data){
|
||||
// show log dialog
|
||||
Logging.showDialog();
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on('pf:menuShortcuts', function(e, data){
|
||||
// show shortcuts dialog
|
||||
$.fn.showShortcutsDialog();
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on('pf:menuShowSettingsDialog', function(e){
|
||||
// show character select dialog
|
||||
$.fn.showSettingsDialog();
|
||||
@@ -626,12 +692,6 @@ define([
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on('pf:menuShowTaskManager', function(e, data){
|
||||
// show log dialog
|
||||
Logging.showDialog();
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on('pf:menuLogout', function(e, data){
|
||||
|
||||
let clearCookies = false;
|
||||
|
||||
@@ -9,9 +9,10 @@ define([
|
||||
'app/render',
|
||||
'bootbox',
|
||||
], function($, Init, Util, Render, bootbox) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var config = {
|
||||
let config = {
|
||||
// jump info dialog
|
||||
jumpInfoDialogClass: 'pf-jump-info-dialog' // class for jump info dialog
|
||||
};
|
||||
@@ -22,12 +23,10 @@ define([
|
||||
$.fn.showJumpInfoDialog = function(){
|
||||
|
||||
requirejs(['text!templates/dialog/jump_info.html', 'mustache'], function(template, Mustache) {
|
||||
let data = {};
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
var data = {};
|
||||
|
||||
var content = Mustache.render(template, data);
|
||||
|
||||
var signatureReaderDialog = bootbox.dialog({
|
||||
let signatureReaderDialog = bootbox.dialog({
|
||||
className: config.jumpInfoDialogClass,
|
||||
title: 'Wormhole jump information',
|
||||
message: content
|
||||
|
||||
@@ -12,7 +12,7 @@ define([
|
||||
|
||||
'use strict';
|
||||
|
||||
var config = {
|
||||
let config = {
|
||||
// global dialog
|
||||
dialogNavigationClass: 'pf-dialog-navigation-list', // class for dialog navigation bar
|
||||
dialogNavigationListItemClass: 'pf-dialog-navigation-list-item', // class for map manual li main navigation elements
|
||||
@@ -28,7 +28,7 @@ define([
|
||||
|
||||
requirejs(['text!templates/dialog/map_manual.html', 'mustache'], function(template, Mustache) {
|
||||
|
||||
var data = {
|
||||
let data = {
|
||||
dialogNavigationClass: config.dialogNavigationClass,
|
||||
dialogNavLiClass: config.dialogNavigationListItemClass,
|
||||
scrollspyId: config.mapManualScrollspyId,
|
||||
@@ -36,10 +36,10 @@ define([
|
||||
mapCounterClass : Init.classes.pieChart.pieChartMapCounterClass
|
||||
};
|
||||
|
||||
var content = Mustache.render(template, data);
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
// show dialog
|
||||
var mapManualDialog = bootbox.dialog({
|
||||
let mapManualDialog = bootbox.dialog({
|
||||
title: 'Manual',
|
||||
message: content,
|
||||
size: 'large',
|
||||
@@ -56,15 +56,15 @@ define([
|
||||
});
|
||||
|
||||
// modal offset top
|
||||
var modalOffsetTop = 200;
|
||||
let modalOffsetTop = 200;
|
||||
|
||||
// disable on scroll event
|
||||
var disableOnScrollEvent = false;
|
||||
let disableOnScrollEvent = false;
|
||||
|
||||
// scroll breakpoints
|
||||
var scrolLBreakpointElements = null;
|
||||
let scrolLBreakpointElements = null;
|
||||
// scroll navigation links
|
||||
var scrollNavLiElements = null;
|
||||
let scrollNavLiElements = null;
|
||||
|
||||
mapManualDialog.on('shown.bs.modal', function(e) {
|
||||
// modal on open
|
||||
@@ -72,13 +72,13 @@ define([
|
||||
scrollNavLiElements = $('.' + config.dialogNavigationListItemClass);
|
||||
});
|
||||
|
||||
var scrollspyElement = $('#' + config.mapManualScrollspyId);
|
||||
let scrollspyElement = $('#' + config.mapManualScrollspyId);
|
||||
|
||||
var whileScrolling = function(){
|
||||
let whileScrolling = function(){
|
||||
|
||||
if(disableOnScrollEvent === false){
|
||||
for(var i = 0; i < scrolLBreakpointElements.length; i++){
|
||||
var offset = $(scrolLBreakpointElements[i]).offset().top;
|
||||
for(let i = 0; i < scrolLBreakpointElements.length; i++){
|
||||
let offset = $(scrolLBreakpointElements[i]).offset().top;
|
||||
|
||||
if( (offset - modalOffsetTop) > 0){
|
||||
|
||||
@@ -116,11 +116,11 @@ define([
|
||||
scrollspyElement.find('.' + data.mapCounterClass).initMapUpdateCounter();
|
||||
|
||||
// set navigation button observer
|
||||
var mainNavigationLinks = $('.' + config.dialogNavigationClass).find('a');
|
||||
let mainNavigationLinks = $('.' + config.dialogNavigationClass).find('a');
|
||||
// text anchor links
|
||||
var subNavigationLinks = scrollspyElement.find('a[data-target]');
|
||||
let subNavigationLinks = scrollspyElement.find('a[data-target]');
|
||||
|
||||
var navigationLinks = mainNavigationLinks.add(subNavigationLinks);
|
||||
let navigationLinks = mainNavigationLinks.add(subNavigationLinks);
|
||||
|
||||
navigationLinks.on('click', function(e){
|
||||
e.preventDefault();
|
||||
@@ -130,7 +130,7 @@ define([
|
||||
// scroll to anchor
|
||||
scrollspyElement.mCustomScrollbar('scrollTo', $(this).attr('data-target'));
|
||||
|
||||
var mainNavigationLiElement = $(this).parent('.' + config.dialogNavigationListItemClass);
|
||||
let mainNavigationLiElement = $(this).parent('.' + config.dialogNavigationListItemClass);
|
||||
|
||||
|
||||
whileScrolling();
|
||||
|
||||
@@ -12,7 +12,7 @@ define([
|
||||
|
||||
'use strict';
|
||||
|
||||
var config = {
|
||||
let config = {
|
||||
|
||||
// shutdown dialog
|
||||
notificationDialogId: 'pf-notification-dialog', // id for "notification" dialog
|
||||
@@ -23,8 +23,8 @@ define([
|
||||
* show/animate dialog page content
|
||||
* @param dialog
|
||||
*/
|
||||
var showPageContent = function(dialog){
|
||||
var headlineElement = dialog.find('h1');
|
||||
let showPageContent = function(dialog){
|
||||
let headlineElement = dialog.find('h1');
|
||||
|
||||
headlineElement.delay(300).velocity('transition.shrinkIn', {
|
||||
duration: 500
|
||||
@@ -45,7 +45,7 @@ define([
|
||||
$.fn.showNotificationDialog = function(dialogData){
|
||||
|
||||
// check if there is already a notification dialog open
|
||||
var notificationDialogClassDialoges = $('.' + config.notificationDialogClass);
|
||||
let notificationDialogClassDialoges = $('.' + config.notificationDialogClass);
|
||||
|
||||
if(notificationDialogClassDialoges.length === 0){
|
||||
|
||||
@@ -54,15 +54,15 @@ define([
|
||||
|
||||
requirejs(['text!templates/dialog/notification.html', 'mustache'], function(template, Mustache) {
|
||||
|
||||
var data = {
|
||||
let data = {
|
||||
id: config.notificationDialogId,
|
||||
content: dialogData.content
|
||||
};
|
||||
|
||||
var content = Mustache.render(template, data);
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
// show dialog
|
||||
var shutdownDialog = bootbox.dialog({
|
||||
let shutdownDialog = bootbox.dialog({
|
||||
title: dialogData.content.title,
|
||||
message: content,
|
||||
className: config.notificationDialogClass,
|
||||
@@ -72,7 +72,7 @@ define([
|
||||
|
||||
shutdownDialog.on('shown.bs.modal', function(e) {
|
||||
// remove close button
|
||||
var dialog = $(this);
|
||||
let dialog = $(this);
|
||||
|
||||
dialog.find('.bootbox-close-button').remove();
|
||||
dialog.find('button').blur();
|
||||
|
||||
50
js/app/ui/dialog/shortcuts.js
Normal file
50
js/app/ui/dialog/shortcuts.js
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* shortcuts dialog
|
||||
*/
|
||||
|
||||
define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util',
|
||||
'app/render',
|
||||
'bootbox',
|
||||
'app/key',
|
||||
], function($, Init, Util, Render, bootbox, Key) {
|
||||
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
// map dialog
|
||||
shortcutsDialogId: 'pf-shortcuts-dialog', // id for shortcuts dialog
|
||||
};
|
||||
|
||||
/**
|
||||
* shows the map manual modal dialog
|
||||
*/
|
||||
$.fn.showShortcutsDialog = function(){
|
||||
requirejs(['text!templates/dialog/shortcuts.html', 'mustache'], function(template, Mustache){
|
||||
|
||||
let data = {
|
||||
id: config.shortcutsDialogId,
|
||||
shortcuts: Key.getGroupedShortcuts()
|
||||
};
|
||||
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
// show dialog
|
||||
let shortcutsDialog = bootbox.dialog({
|
||||
title: 'Keyboard Shortcuts',
|
||||
message: content,
|
||||
size: 'large',
|
||||
buttons: {
|
||||
success: {
|
||||
label: 'close',
|
||||
className: 'btn-default'
|
||||
}
|
||||
},
|
||||
show: true
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
});
|
||||
@@ -13,12 +13,12 @@ define([
|
||||
], function($, Init, Util, Render, bootbox, MapUtil) {
|
||||
'use strict';
|
||||
|
||||
var config = {
|
||||
let config = {
|
||||
// system effect dialog
|
||||
systemEffectDialogWrapperClass: 'pf-system-effect-dialog-wrapper' // class for system effect dialog
|
||||
};
|
||||
|
||||
var cache = {
|
||||
let cache = {
|
||||
systemEffectDialog: false // system effect info dialog
|
||||
};
|
||||
|
||||
@@ -30,31 +30,31 @@ define([
|
||||
// cache table structure
|
||||
if(!cache.systemEffectDialog){
|
||||
|
||||
var dialogWrapperElement = $('<div>', {
|
||||
let dialogWrapperElement = $('<div>', {
|
||||
class: config.systemEffectDialogWrapperClass
|
||||
});
|
||||
|
||||
var systemEffectData = Util.getSystemEffectData();
|
||||
let systemEffectData = Util.getSystemEffectData();
|
||||
|
||||
$.each( systemEffectData.wh, function( effectName, effectData ) {
|
||||
|
||||
var table = $('<table>', {
|
||||
let table = $('<table>', {
|
||||
class: ['table', 'table-condensed'].join(' ')
|
||||
});
|
||||
|
||||
var tbody = $('<tbody>');
|
||||
var thead = $('<thead>');
|
||||
let tbody = $('<tbody>');
|
||||
let thead = $('<thead>');
|
||||
|
||||
var rows = [];
|
||||
let rows = [];
|
||||
|
||||
// get formatted system effect name
|
||||
var systemEffectName = MapUtil.getEffectInfoForSystem(effectName, 'name');
|
||||
var systemEffectClass = MapUtil.getEffectInfoForSystem(effectName, 'class');
|
||||
let systemEffectName = MapUtil.getEffectInfoForSystem(effectName, 'name');
|
||||
let systemEffectClass = MapUtil.getEffectInfoForSystem(effectName, 'class');
|
||||
|
||||
$.each( effectData, function( areaId, areaData ) {
|
||||
|
||||
var systemType = 'C' + areaId;
|
||||
var securityClass = Util.getSecurityClassForSystem( systemType );
|
||||
let systemType = 'C' + areaId;
|
||||
let securityClass = Util.getSecurityClassForSystem( systemType );
|
||||
|
||||
if(areaId === '1'){
|
||||
rows.push( $('<tr>') );
|
||||
|
||||
@@ -15,7 +15,7 @@ define([
|
||||
* init a select element as "select2" for map selection
|
||||
*/
|
||||
$.fn.initMapSelect = function(){
|
||||
var selectElement = $(this);
|
||||
let selectElement = $(this);
|
||||
|
||||
$.when(
|
||||
selectElement.select2({
|
||||
@@ -31,9 +31,9 @@ define([
|
||||
* @param options
|
||||
*/
|
||||
$.fn.initSystemSelect = function(options){
|
||||
var selectElement = $(this);
|
||||
let selectElement = $(this);
|
||||
|
||||
var config = {
|
||||
let config = {
|
||||
maxSelectionLength: 1
|
||||
};
|
||||
options = $.extend({}, config, options);
|
||||
@@ -46,12 +46,12 @@ define([
|
||||
}
|
||||
|
||||
// show effect info just for wormholes
|
||||
var hideEffectClass = '';
|
||||
let hideEffectClass = '';
|
||||
if(data.effect === ''){
|
||||
hideEffectClass = 'hide';
|
||||
}
|
||||
|
||||
var markup = '<div class="clearfix">';
|
||||
let markup = '<div class="clearfix">';
|
||||
markup += '<div class="col-sm-5 pf-select-item-anchor">' + data.text + '</div>';
|
||||
markup += '<div class="col-sm-2 text-right ' + data.effectClass + '">';
|
||||
markup += '<i class="fa fa-fw fa-square ' + hideEffectClass + '"></i>';
|
||||
@@ -83,12 +83,12 @@ define([
|
||||
results: data.map( function(item){
|
||||
|
||||
// "systemId" or "name"
|
||||
var id = item[options.key];
|
||||
var disabled = false;
|
||||
var trueSec = parseFloat(item.trueSec);
|
||||
var secClass = Util.getSecurityClassForSystem(item.security);
|
||||
var trueSecClass = Util.getTrueSecClassForSystem( trueSec );
|
||||
var effectClass = MapUtil.getEffectInfoForSystem(item.effect, 'class');
|
||||
let id = item[options.key];
|
||||
let disabled = false;
|
||||
let trueSec = parseFloat(item.trueSec);
|
||||
let secClass = Util.getSecurityClassForSystem(item.security);
|
||||
let trueSecClass = Util.getTrueSecClassForSystem( trueSec );
|
||||
let effectClass = MapUtil.getEffectInfoForSystem(item.effect, 'class');
|
||||
|
||||
// check if system is dialed
|
||||
if(
|
||||
@@ -126,7 +126,7 @@ define([
|
||||
error: function (jqXHR, status, error) {
|
||||
if( !Util.isXHRAborted(jqXHR) ){
|
||||
|
||||
var reason = status + ' ' + jqXHR.status + ': ' + error;
|
||||
let reason = status + ' ' + jqXHR.status + ': ' + error;
|
||||
Util.showNotify({title: 'System select warning', text: reason + ' deleted', type: 'warning'});
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ define([
|
||||
|
||||
return this.each(function(){
|
||||
|
||||
var selectElement = $(this);
|
||||
let selectElement = $(this);
|
||||
|
||||
// format result data
|
||||
function formatResultData (data) {
|
||||
@@ -172,7 +172,7 @@ define([
|
||||
|
||||
// check if an option is already selected
|
||||
// do not show the same result twice
|
||||
var currentValues = selectElement.val();
|
||||
let currentValues = selectElement.val();
|
||||
|
||||
if(
|
||||
currentValues &&
|
||||
@@ -181,8 +181,8 @@ define([
|
||||
return ;
|
||||
}
|
||||
|
||||
var imagePath = '';
|
||||
var previewContent = '';
|
||||
let imagePath = '';
|
||||
let previewContent = '';
|
||||
|
||||
switch(options.type){
|
||||
case 'character':
|
||||
@@ -199,7 +199,7 @@ define([
|
||||
break;
|
||||
}
|
||||
|
||||
var markup = '<div class="clearfix">';
|
||||
let markup = '<div class="clearfix">';
|
||||
markup += '<div class="col-sm-2">' + previewContent + '</div>';
|
||||
markup += '<div class="col-sm-10">' + data.text + '</div></div>';
|
||||
|
||||
@@ -213,7 +213,7 @@ define([
|
||||
return data.text;
|
||||
}
|
||||
|
||||
var markup = '<div class="clearfix">';
|
||||
let markup = '<div class="clearfix">';
|
||||
markup += '<div class="col-sm-10">' + data.text + '</div></div>';
|
||||
|
||||
return markup;
|
||||
@@ -248,7 +248,7 @@ define([
|
||||
error: function (jqXHR, status, error) {
|
||||
if( !Util.isXHRAborted(jqXHR) ){
|
||||
|
||||
var reason = status + ' ' + jqXHR.status + ': ' + error;
|
||||
let reason = status + ' ' + jqXHR.status + ': ' + error;
|
||||
Util.showNotify({title: 'Access select warning', text: reason + ' deleted', type: 'warning'});
|
||||
}
|
||||
|
||||
|
||||
@@ -2206,20 +2206,8 @@ define([
|
||||
});
|
||||
|
||||
// event listener for global "paste" signatures into the page -------------------------------------------------
|
||||
$('body').off('paste').on('paste', function(e){
|
||||
let targetElement = $(e.target);
|
||||
|
||||
// do not read clipboard if pasting into form elements
|
||||
if(
|
||||
targetElement.prop('tagName').toLowerCase() !== 'input' &&
|
||||
targetElement.prop('tagName').toLowerCase() !== 'textarea' || (
|
||||
targetElement.is('input[type="search"]') // Datatables "search" field bubbles `paste.DT` event :(
|
||||
)
|
||||
){
|
||||
let clipboard = (e.originalEvent || e).clipboardData.getData('text/plain');
|
||||
|
||||
moduleElement.updateSignatureTableByClipboard(systemData, clipboard, {});
|
||||
}
|
||||
moduleElement.on('pf:updateSystemSignatureModuleByClipboard', function(e, clipboard){
|
||||
$(this).updateSignatureTableByClipboard(systemData, clipboard, {});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
442
public/js/v1.2.1/app/key.js
Normal file
442
public/js/v1.2.1/app/key.js
Normal file
@@ -0,0 +1,442 @@
|
||||
define([
|
||||
'jquery'
|
||||
], function($) {
|
||||
'use strict';
|
||||
|
||||
let allCombo = {
|
||||
// global -------------------------------------------------------------------------------------------
|
||||
tabReload: {
|
||||
group: 'global',
|
||||
label: 'Close open dialog',
|
||||
keyNames: ['ESC']
|
||||
},
|
||||
// signature ----------------------------------------------------------------------------------------
|
||||
signatureSelect: {
|
||||
group: 'signatures',
|
||||
label: 'Select multiple rows',
|
||||
keyNames: ['CONTROL', 'CLICK']
|
||||
}
|
||||
};
|
||||
|
||||
let allEvents = {
|
||||
// global -------------------------------------------------------------------------------------------
|
||||
tabReload: {
|
||||
group: 'global',
|
||||
label: 'Reload tab',
|
||||
keyNames: ['CONTROL', 'R']
|
||||
},
|
||||
signaturePaste: {
|
||||
group: 'global',
|
||||
label: 'Paste signatures from clipboard',
|
||||
keyNames: ['CONTROL', 'V'],
|
||||
alias: 'paste'
|
||||
},
|
||||
|
||||
// map ----------------------------------------------------------------------------------------------
|
||||
mapSystemAdd: {
|
||||
group: 'map',
|
||||
label: 'Add new system',
|
||||
keyNames: ['CONTROL', 'S']
|
||||
},
|
||||
mapSystemsSelect: {
|
||||
group: 'map',
|
||||
label: 'Select all systems',
|
||||
keyNames: ['CONTROL', 'A']
|
||||
},
|
||||
mapSystemsDelete: {
|
||||
group: 'map',
|
||||
label: 'Delete selected systems',
|
||||
keyNames: ['CONTROL', 'D']
|
||||
}
|
||||
};
|
||||
|
||||
let groups = {
|
||||
global: {
|
||||
label: 'Global'
|
||||
},
|
||||
map: {
|
||||
label: 'Map'
|
||||
},
|
||||
signatures: {
|
||||
label: 'Signature'
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* enables some console.log() information
|
||||
* @type {boolean}
|
||||
*/
|
||||
let debug = false;
|
||||
|
||||
/**
|
||||
* check interval for "new" active keys
|
||||
* @type {number}
|
||||
*/
|
||||
let keyWatchPeriod = 100;
|
||||
|
||||
/**
|
||||
* DOM data key for an element that lists all active events (comma separated)
|
||||
* @type {string}
|
||||
*/
|
||||
let dataKeyEvents = 'key-events';
|
||||
|
||||
/**
|
||||
* DOM data key prefix whether domElement that holds the trigger needs to be "focused"
|
||||
* @type {string}
|
||||
*/
|
||||
let dataKeyFocusPrefix = 'key-focus-';
|
||||
|
||||
/**
|
||||
* DOM data key that holds the callback function for that element
|
||||
* @type {string}
|
||||
*/
|
||||
let dataKeyCallbackPrefix = 'key-callback-';
|
||||
|
||||
/**
|
||||
* check if module is initiated
|
||||
*/
|
||||
let isInit = false;
|
||||
|
||||
/**
|
||||
* global key map holds all active (hold down) keys
|
||||
* @type {{}}
|
||||
*/
|
||||
let map = {};
|
||||
|
||||
/**
|
||||
* show debug information in console
|
||||
* @param msg
|
||||
* @param element
|
||||
*/
|
||||
let debugWatchKey = (msg, element) => {
|
||||
if(debug){
|
||||
console.info(msg, element);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* get all active (hold down) keys at this moment
|
||||
* @returns {Array}
|
||||
*/
|
||||
let getActiveKeys = () => {
|
||||
return Object.keys(map);
|
||||
};
|
||||
|
||||
/**
|
||||
* callback function that compares two arrays
|
||||
* @param element
|
||||
* @param index
|
||||
* @param array
|
||||
*/
|
||||
let compareKeyLists = function(element, index, array) {
|
||||
return this.find(x => x === element);
|
||||
};
|
||||
|
||||
/**
|
||||
* get event names that COULD lead to a "full" event (not all keys pressed yet)
|
||||
* @param keyList
|
||||
* @returns {Array}
|
||||
*/
|
||||
let checkEventNames = (keyList) => {
|
||||
let incompleteEvents = [];
|
||||
for(let event in allEvents){
|
||||
// check if "some" or "all" keys are pressed for en event
|
||||
if( keyList.every(compareKeyLists, allEvents[event].keyNames) ){
|
||||
incompleteEvents.push(event);
|
||||
}
|
||||
}
|
||||
|
||||
return incompleteEvents;
|
||||
};
|
||||
|
||||
/**
|
||||
* get all event names
|
||||
* @returns {Array}
|
||||
*/
|
||||
let getAllEventNames = () => {
|
||||
let eventNames = [];
|
||||
for(let event in allEvents){
|
||||
eventNames.push(event);
|
||||
}
|
||||
return eventNames;
|
||||
};
|
||||
|
||||
/**
|
||||
* get all event names that matches a given keyList
|
||||
* @param keyList
|
||||
* @param checkEvents
|
||||
* @returns {Array}
|
||||
*/
|
||||
let getMatchingEventNames = (keyList, checkEvents) => {
|
||||
checkEvents = checkEvents || getAllEventNames();
|
||||
let events = [];
|
||||
|
||||
for(let event of checkEvents){
|
||||
// check if both key arrays are equal
|
||||
if(
|
||||
allEvents[event].keyNames.every(compareKeyLists, keyList) &&
|
||||
keyList.every(compareKeyLists, allEvents[event].keyNames)
|
||||
){
|
||||
events.push(event);
|
||||
}
|
||||
}
|
||||
|
||||
return events;
|
||||
};
|
||||
|
||||
/**
|
||||
* init global keyWatch interval and check for event trigger (hotKey combinations)
|
||||
*/
|
||||
let init = () => {
|
||||
if( !isInit ){
|
||||
// key watch loop -------------------------------------------------------------------------------
|
||||
let prevActiveKeys = [];
|
||||
|
||||
/**
|
||||
*
|
||||
* @param e
|
||||
* @returns {number} 0: no keys hold, 1: invalid match, 2: partial match, 3: match, 4: alias match, 5: event(s) fired
|
||||
*/
|
||||
let checkForEvents = (e) => {
|
||||
let status = 0;
|
||||
|
||||
// get all pressed keys
|
||||
let activeKeys = getActiveKeys();
|
||||
debugWatchKey('activeKeys', activeKeys);
|
||||
|
||||
// check if "active" keys has changes since last loop
|
||||
if(activeKeys.length){
|
||||
// check for "incomplete" events (not all keys pressed yet)
|
||||
let incompleteEvents = checkEventNames(activeKeys);
|
||||
if(incompleteEvents.length){
|
||||
// "some" event keys pressed OR "all" keys pressed
|
||||
status = 2;
|
||||
|
||||
// check if key combo matches a registered (valid) event
|
||||
let events = getMatchingEventNames(activeKeys, incompleteEvents);
|
||||
if(events.length){
|
||||
status = 3;
|
||||
// check events if there are attached elements to it
|
||||
events.forEach((event) => {
|
||||
// skip events that has an alias and should not be triggered by key combo
|
||||
if( !allEvents[event].alias ){
|
||||
if(allEvents[event].elements){
|
||||
// search for callback functions attached to each element
|
||||
allEvents[event].elements.forEach((domElement) => {
|
||||
let domElementObj = $(domElement);
|
||||
// check if event on this element requires active "focus"
|
||||
let optFocus = domElementObj.data(dataKeyFocusPrefix + event);
|
||||
|
||||
if( !(
|
||||
optFocus &&
|
||||
document.activeElement !== domElement
|
||||
)
|
||||
){
|
||||
// execute callback if valid
|
||||
let callback = domElementObj.data(dataKeyCallbackPrefix + event);
|
||||
if(typeof callback === 'function'){
|
||||
status = 5;
|
||||
callback.call(domElement, domElement, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}else{
|
||||
status = 4;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}else{
|
||||
// invalid combo
|
||||
status = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// store current keys for next loop check
|
||||
prevActiveKeys = activeKeys;
|
||||
|
||||
return status;
|
||||
};
|
||||
|
||||
// set key-events -------------------------------------------------------------------------------
|
||||
let evKeyDown = (e) => {
|
||||
// exclude some HTML Tags from watcher
|
||||
if(
|
||||
e.target.tagName !== 'INPUT' &&
|
||||
e.target.tagName !== 'TEXTAREA'
|
||||
){
|
||||
let key = e.key.toUpperCase();
|
||||
map[key] = true;
|
||||
|
||||
// check for any shortcut combo that triggers an event
|
||||
let status = checkForEvents(e);
|
||||
|
||||
if(
|
||||
status === 2 ||
|
||||
status === 3 ||
|
||||
status === 5
|
||||
){
|
||||
// prevent SOME browser default actions -> we want 'Pathfinder' shortcuts :)
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let evKeyUp = (e) => {
|
||||
let key = e.key.toUpperCase();
|
||||
|
||||
if(map.hasOwnProperty(key)){
|
||||
delete map[key];
|
||||
}
|
||||
};
|
||||
|
||||
let container = $('body');
|
||||
container.on('keydown', evKeyDown);
|
||||
container.on('keyup', evKeyUp);
|
||||
|
||||
// global dom remove listener -------------------------------------------------------------------
|
||||
// -> check whether the removed element had an event listener active and removes them.
|
||||
document.body.addEventListener ('DOMNodeRemoved', function(e){
|
||||
if(typeof e.target.getAttribute === 'function'){
|
||||
let eventNames = e.target.getAttribute(dataKeyEvents);
|
||||
if(eventNames){
|
||||
eventNames.split(',').forEach((event) => {
|
||||
let index = allEvents[event].elements.indexOf(e.target);
|
||||
if(index > -1){
|
||||
// remove element from event list
|
||||
allEvents[event].elements.splice(index, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
|
||||
isInit = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* add a new "shortCut" combination (event) to a DOM element
|
||||
* @param event
|
||||
* @param callback
|
||||
* @param options
|
||||
*/
|
||||
$.fn.watchKey = function(event, callback, options){
|
||||
|
||||
// default options for keyWatcher on elements
|
||||
let defaultOptions = {
|
||||
focus: false, // element must be focused (active)
|
||||
bubbling: true // elements deeper (children) in the DOM can bubble the event up
|
||||
};
|
||||
|
||||
let customOptions = $.extend(true, {}, defaultOptions, options );
|
||||
|
||||
return this.each((i, domElement) => {
|
||||
let element = $(domElement);
|
||||
|
||||
// init global key events
|
||||
init();
|
||||
|
||||
// check if event is "valid" (exists) and is not already set for this element
|
||||
let validEvent = false;
|
||||
if(allEvents[event].elements){
|
||||
if(allEvents[event].elements.indexOf(domElement) === -1){
|
||||
validEvent = true;
|
||||
}else{
|
||||
console.warn('Event "' + event + '" already set');
|
||||
}
|
||||
}else{
|
||||
validEvent = true;
|
||||
allEvents[event].elements = [];
|
||||
}
|
||||
|
||||
if(validEvent){
|
||||
// store callback options to dom element
|
||||
if(customOptions.focus){
|
||||
let dataAttr = dataKeyFocusPrefix + event;
|
||||
element.data(dataAttr, true);
|
||||
|
||||
// check if DOM element has "tabindex" attr -> required to manually set focus() to it
|
||||
if(!domElement.hasAttribute('tabindex')){
|
||||
domElement.setAttribute('tabindex', 0);
|
||||
}
|
||||
|
||||
// element requires a "focus" listener
|
||||
element.off('click.focusKeyWatcher').on('click.focusKeyWatcher', function(e){
|
||||
if(
|
||||
e.target === this ||
|
||||
customOptions.bubbling
|
||||
){
|
||||
this.focus();
|
||||
debugWatchKey('focus set:', this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// check if is key combo has a native JS event that should be used instead
|
||||
if(allEvents[event].alias){
|
||||
element.on(allEvents[event].alias, callback);
|
||||
}else{
|
||||
// store callback function to dom element
|
||||
let dataAttr = dataKeyCallbackPrefix + event;
|
||||
element.data(dataAttr, callback);
|
||||
}
|
||||
|
||||
// add eventName to dom element as attribute ----------------------------------------------------
|
||||
let currentEventNames = element.attr(dataKeyEvents) ? element.attr(dataKeyEvents).split(',') : [];
|
||||
currentEventNames.push(event);
|
||||
element.attr(dataKeyEvents, currentEventNames.join(','));
|
||||
|
||||
// store domElement to event (global)
|
||||
allEvents[event].elements.push(domElement);
|
||||
|
||||
debugWatchKey('new event "' + event + '" registered', domElement);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* get a array with all available shortcut groups and their events
|
||||
* @returns {Array}
|
||||
*/
|
||||
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];
|
||||
|
||||
//format keyNames for UI
|
||||
let keyNames = data.keyNames.map( (key) => {
|
||||
if(key === 'CONTROL'){
|
||||
key = 'ctrl';
|
||||
}
|
||||
return key;
|
||||
});
|
||||
|
||||
let newEventData = {
|
||||
label: data.label,
|
||||
keyNames: keyNames
|
||||
};
|
||||
|
||||
if( result[data.group].events ){
|
||||
result[data.group].events.push(newEventData);
|
||||
}else{
|
||||
result[data.group].events = [newEventData];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert obj into array
|
||||
result = Object.values(result);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
return {
|
||||
getGroupedShortcuts: getGroupedShortcuts
|
||||
};
|
||||
});
|
||||
@@ -22,10 +22,6 @@ define([
|
||||
|
||||
let config = {
|
||||
zIndexCounter: 110,
|
||||
newSystemOffset: {
|
||||
x: 130,
|
||||
y: 0
|
||||
},
|
||||
|
||||
mapSnapToGrid: false, // "Snap to Grid" feature for drag&drop systems on map (optional)
|
||||
mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable)
|
||||
@@ -1372,6 +1368,205 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* save a new system and add it to the map
|
||||
* @param map
|
||||
* @param requestData
|
||||
* @param sourceSystem
|
||||
* @param callback
|
||||
*/
|
||||
let saveSystem = function(map, requestData, sourceSystem, callback){
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Init.path.saveSystem,
|
||||
data: requestData,
|
||||
dataType: 'json',
|
||||
context: {
|
||||
map: map,
|
||||
sourceSystem: sourceSystem
|
||||
}
|
||||
}).done(function(newSystemData){
|
||||
Util.showNotify({title: 'New system', text: newSystemData.name, type: 'success'});
|
||||
|
||||
// draw new system to map
|
||||
drawSystem(this.map, newSystemData, this.sourceSystem);
|
||||
|
||||
// re/arrange systems (prevent overlapping)
|
||||
MagnetizerWrapper.setElements(this.map);
|
||||
|
||||
if(callback){
|
||||
callback();
|
||||
}
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
let reason = status + ' ' + error;
|
||||
Util.showNotify({title: jqXHR.status + ': saveSystem', text: reason, type: 'warning'});
|
||||
$(document).setProgramStatus('problem');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* open "new system" dialog and add the system to map
|
||||
* optional the new system is connected to a "sourceSystem" (if available)
|
||||
*
|
||||
* @param map
|
||||
* @param options
|
||||
*/
|
||||
let showNewSystemDialog = function(map, options){
|
||||
let mapContainer = $(map.getContainer());
|
||||
|
||||
// format system status for form select -------------------------------------------------------------
|
||||
let systemStatus = {};
|
||||
// "default" selection (id = 0) prevents status from being overwritten
|
||||
// -> e.g. keep status information if system was just inactive (active = 0)
|
||||
systemStatus[0] = 'default';
|
||||
|
||||
$.each(Init.systemStatus, function(status, statusData){
|
||||
systemStatus[statusData.id] = statusData.label;
|
||||
});
|
||||
|
||||
// default system status -> first status entry
|
||||
let defaultSystemStatus = 0;
|
||||
|
||||
// get current map data -----------------------------------------------------------------------------
|
||||
let mapData = mapContainer.getMapDataFromClient({forceData: true});
|
||||
let mapSystems = mapData.data.systems;
|
||||
let mapSystemCount = mapSystems.length;
|
||||
let mapTypeName = mapContainer.data('typeName');
|
||||
let maxAllowedSystems = Init.mapTypes[mapTypeName].defaultConfig.max_systems;
|
||||
|
||||
// show error if system max count reached -----------------------------------------------------------
|
||||
if(mapSystemCount >= maxAllowedSystems){
|
||||
Util.showNotify({title: 'Max system count exceeded', text: 'Limit of ' + maxAllowedSystems + ' systems reached', type: 'warning'});
|
||||
return;
|
||||
}
|
||||
|
||||
// disable systems that are already on it -----------------------------------------------------------
|
||||
let mapSystemIds = [];
|
||||
for(let i = 0; i < mapSystems.length; i++ ){
|
||||
mapSystemIds.push( mapSystems[i].systemId );
|
||||
}
|
||||
|
||||
// dialog data --------------------------------------------------------------------------------------
|
||||
let data = {
|
||||
id: config.systemDialogId,
|
||||
selectClass: config.systemDialogSelectClass
|
||||
};
|
||||
|
||||
// set current position as "default" system to add --------------------------------------------------
|
||||
let currentCharacterLog = Util.getCurrentCharacterLog();
|
||||
|
||||
if(
|
||||
currentCharacterLog !== false &&
|
||||
mapSystemIds.indexOf( currentCharacterLog.system.id ) === -1
|
||||
){
|
||||
// current system is NOT already on this map
|
||||
// set current position as "default" system to add
|
||||
data.currentSystem = currentCharacterLog.system;
|
||||
}
|
||||
|
||||
requirejs(['text!templates/dialog/system.html', 'mustache'], function(template, Mustache) {
|
||||
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
let systemDialog = bootbox.dialog({
|
||||
title: 'Add new system',
|
||||
message: content,
|
||||
buttons: {
|
||||
close: {
|
||||
label: 'cancel',
|
||||
className: 'btn-default'
|
||||
},
|
||||
success: {
|
||||
label: '<i class="fa fa-fw fa-check"></i> save',
|
||||
className: 'btn-success',
|
||||
callback: function (e) {
|
||||
// get form Values
|
||||
let form = $('#' + config.systemDialogId).find('form');
|
||||
|
||||
let systemDialogData = $(form).getFormValues();
|
||||
|
||||
// validate form
|
||||
form.validator('validate');
|
||||
|
||||
// check whether the form is valid
|
||||
let formValid = form.isValidForm();
|
||||
|
||||
if(formValid === false){
|
||||
// don't close dialog
|
||||
return false;
|
||||
}
|
||||
|
||||
// calculate new system position ------------------------------------------------
|
||||
let newPosition = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
|
||||
let sourceSystem = null;
|
||||
|
||||
// add new position
|
||||
if(options.sourceSystem !== undefined){
|
||||
|
||||
sourceSystem = options.sourceSystem;
|
||||
|
||||
// get new position
|
||||
newPosition = System.calculateNewSystemPosition(sourceSystem);
|
||||
}else{
|
||||
// check mouse cursor position (add system to map)
|
||||
newPosition = {
|
||||
x: options.position.x,
|
||||
y: options.position.y
|
||||
};
|
||||
}
|
||||
|
||||
systemDialogData.position = newPosition;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
let requestData = {
|
||||
systemData: systemDialogData,
|
||||
mapData: {
|
||||
id: mapContainer.data('id')
|
||||
}
|
||||
};
|
||||
|
||||
saveSystem(map, requestData, sourceSystem, function(){
|
||||
bootbox.hideAll();
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// init dialog
|
||||
systemDialog.on('shown.bs.modal', function(e) {
|
||||
|
||||
let modalContent = $('#' + config.systemDialogId);
|
||||
|
||||
// init system select live search - some delay until modal transition has finished
|
||||
let selectElement = modalContent.find('.' + config.systemDialogSelectClass);
|
||||
selectElement.delay(240).initSystemSelect({
|
||||
key: 'systemId',
|
||||
disabledOptions: mapSystemIds
|
||||
});
|
||||
});
|
||||
|
||||
// init system status select
|
||||
let modalFields = $('.bootbox .modal-dialog').find('.pf-editable-system-status');
|
||||
|
||||
modalFields.editable({
|
||||
mode: 'inline',
|
||||
emptytext: 'unknown',
|
||||
onblur: 'submit',
|
||||
showbuttons: false,
|
||||
source: systemStatus,
|
||||
value: defaultSystemStatus,
|
||||
inputclass: config.systemDialogSelectClass
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* make a system name/alias editable by x-editable
|
||||
* @param system
|
||||
@@ -1806,169 +2001,6 @@ define([
|
||||
return activeOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* open "new system" dialog and add the system to map
|
||||
* optional the new system is connected to a "sourceSystem" (if available)
|
||||
*
|
||||
* @param map
|
||||
* @param options
|
||||
*/
|
||||
let showNewSystemDialog = function(map, options){
|
||||
let mapContainer = $(map.getContainer());
|
||||
|
||||
// format system status for form select -------------------------------------------------------------
|
||||
let systemStatus = {};
|
||||
// "default" selection (id = 0) prevents status from being overwritten
|
||||
// -> e.g. keep status information if system was just inactive (active = 0)
|
||||
systemStatus[0] = 'default';
|
||||
|
||||
$.each(Init.systemStatus, function(status, statusData){
|
||||
systemStatus[statusData.id] = statusData.label;
|
||||
});
|
||||
|
||||
// default system status -> first status entry
|
||||
let defaultSystemStatus = 0;
|
||||
|
||||
// get current map data -----------------------------------------------------------------------------
|
||||
let mapData = mapContainer.getMapDataFromClient({forceData: true});
|
||||
let mapSystems = mapData.data.systems;
|
||||
let mapSystemCount = mapSystems.length;
|
||||
let mapTypeName = mapContainer.data('typeName');
|
||||
let maxAllowedSystems = Init.mapTypes[mapTypeName].defaultConfig.max_systems;
|
||||
|
||||
// show error if system max count reached -----------------------------------------------------------
|
||||
if(mapSystemCount >= maxAllowedSystems){
|
||||
Util.showNotify({title: 'Max system count exceeded', text: 'Limit of ' + maxAllowedSystems + ' systems reached', type: 'warning'});
|
||||
return;
|
||||
}
|
||||
|
||||
// disable systems that are already on it -----------------------------------------------------------
|
||||
let mapSystemIds = [];
|
||||
for(let i = 0; i < mapSystems.length; i++ ){
|
||||
mapSystemIds.push( mapSystems[i].systemId );
|
||||
}
|
||||
|
||||
// dialog data --------------------------------------------------------------------------------------
|
||||
let data = {
|
||||
id: config.systemDialogId,
|
||||
selectClass: config.systemDialogSelectClass
|
||||
};
|
||||
|
||||
// set current position as "default" system to add --------------------------------------------------
|
||||
let currentCharacterLog = Util.getCurrentCharacterLog();
|
||||
|
||||
if(
|
||||
currentCharacterLog !== false &&
|
||||
mapSystemIds.indexOf( currentCharacterLog.system.id ) === -1
|
||||
){
|
||||
// current system is NOT already on this map
|
||||
// set current position as "default" system to add
|
||||
data.currentSystem = currentCharacterLog.system;
|
||||
}
|
||||
|
||||
requirejs(['text!templates/dialog/system.html', 'mustache'], function(template, Mustache) {
|
||||
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
let systemDialog = bootbox.dialog({
|
||||
title: 'Add new system',
|
||||
message: content,
|
||||
buttons: {
|
||||
close: {
|
||||
label: 'cancel',
|
||||
className: 'btn-default'
|
||||
},
|
||||
success: {
|
||||
label: '<i class="fa fa-fw fa-check"></i> save',
|
||||
className: 'btn-success',
|
||||
callback: function (e) {
|
||||
// get form Values
|
||||
let form = $('#' + config.systemDialogId).find('form');
|
||||
|
||||
let systemDialogData = $(form).getFormValues();
|
||||
|
||||
// validate form
|
||||
form.validator('validate');
|
||||
|
||||
// check whether the form is valid
|
||||
let formValid = form.isValidForm();
|
||||
|
||||
if(formValid === false){
|
||||
// don't close dialog
|
||||
return false;
|
||||
}
|
||||
|
||||
// calculate new system position ------------------------------------------------
|
||||
let newPosition = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
|
||||
let sourceSystem = null;
|
||||
|
||||
// add new position
|
||||
if(options.sourceSystem !== undefined){
|
||||
|
||||
sourceSystem = options.sourceSystem;
|
||||
|
||||
// get new position
|
||||
newPosition = calculateNewSystemPosition(sourceSystem);
|
||||
}else{
|
||||
// check mouse cursor position (add system to map)
|
||||
newPosition = {
|
||||
x: options.position.x,
|
||||
y: options.position.y
|
||||
};
|
||||
}
|
||||
|
||||
systemDialogData.position = newPosition;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
let requestData = {
|
||||
systemData: systemDialogData,
|
||||
mapData: {
|
||||
id: mapContainer.data('id')
|
||||
}
|
||||
};
|
||||
|
||||
saveSystem(map, requestData, sourceSystem, function(){
|
||||
bootbox.hideAll();
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// init dialog
|
||||
systemDialog.on('shown.bs.modal', function(e) {
|
||||
|
||||
let modalContent = $('#' + config.systemDialogId);
|
||||
|
||||
// init system select live search - some delay until modal transition has finished
|
||||
let selectElement = modalContent.find('.' + config.systemDialogSelectClass);
|
||||
selectElement.delay(240).initSystemSelect({
|
||||
key: 'systemId',
|
||||
disabledOptions: mapSystemIds
|
||||
});
|
||||
});
|
||||
|
||||
// init system status select
|
||||
let modalFields = $('.bootbox .modal-dialog').find('.pf-editable-system-status');
|
||||
|
||||
modalFields.editable({
|
||||
mode: 'inline',
|
||||
emptytext: 'unknown',
|
||||
onblur: 'submit',
|
||||
showbuttons: false,
|
||||
source: systemStatus,
|
||||
value: defaultSystemStatus,
|
||||
inputclass: config.systemDialogSelectClass
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* set up all actions that can be preformed on a system
|
||||
* @param map
|
||||
@@ -2354,6 +2386,28 @@ define([
|
||||
$(tabContentElement).trigger('pf:drawSystemModules');
|
||||
};
|
||||
|
||||
/**
|
||||
* select all (selectable) systems on a mapElement
|
||||
*/
|
||||
$.fn.selectAllSystems = function(){
|
||||
return this.each(function(){
|
||||
let mapElement = $(this);
|
||||
let map = getMapInstance(mapElement.data('id'));
|
||||
|
||||
let allSystems = mapElement.find('.' + config.systemClass + ':not(.' + config.systemSelectedClass + ')');
|
||||
|
||||
// filter non-locked systems
|
||||
allSystems = allSystems.filter(function(i, el){
|
||||
return ( $(el).data('locked') !== true );
|
||||
});
|
||||
|
||||
allSystems.toggleSelectSystem(map);
|
||||
|
||||
Util.showNotify({title: allSystems.length + ' systems selected', type: 'success'});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* toggle selectable status of a system
|
||||
*/
|
||||
@@ -2376,15 +2430,6 @@ define([
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* get all selected (NOT active) systems in a map
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.getSelectedSystems = function(){
|
||||
let mapElement = $(this);
|
||||
return mapElement.find('.' + config.systemSelectedClass);
|
||||
};
|
||||
|
||||
/**
|
||||
* toggle log status of a system
|
||||
* @param poke
|
||||
@@ -2613,17 +2658,7 @@ define([
|
||||
showNewSystemDialog(currentMap, {position: position});
|
||||
break;
|
||||
case 'select_all':
|
||||
|
||||
let allSystems = currentMapElement.find('.' + config.systemClass + ':not(.' + config.systemSelectedClass + ')');
|
||||
|
||||
// filter non-locked systems
|
||||
allSystems = allSystems.filter(function(i, el){
|
||||
return ( $(el).data('locked') !== true );
|
||||
});
|
||||
|
||||
allSystems.toggleSelectSystem(currentMap);
|
||||
|
||||
Util.showNotify({title: allSystems.length + ' systems selected', type: 'success'});
|
||||
currentMapElement.selectAllSystems();
|
||||
break;
|
||||
case 'filter_wh':
|
||||
case 'filter_stargate':
|
||||
@@ -2890,65 +2925,6 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* save a new system and add it to the map
|
||||
* @param map
|
||||
* @param requestData
|
||||
* @param sourceSystem
|
||||
* @param callback
|
||||
*/
|
||||
let saveSystem = function(map, requestData, sourceSystem, callback){
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Init.path.saveSystem,
|
||||
data: requestData,
|
||||
dataType: 'json',
|
||||
context: {
|
||||
map: map,
|
||||
sourceSystem: sourceSystem
|
||||
}
|
||||
}).done(function(newSystemData){
|
||||
Util.showNotify({title: 'New system', text: newSystemData.name, type: 'success'});
|
||||
|
||||
// draw new system to map
|
||||
drawSystem(this.map, newSystemData, this.sourceSystem);
|
||||
|
||||
// re/arrange systems (prevent overlapping)
|
||||
MagnetizerWrapper.setElements(this.map);
|
||||
|
||||
if(callback){
|
||||
callback();
|
||||
}
|
||||
}).fail(function( jqXHR, status, error) {
|
||||
let reason = status + ' ' + error;
|
||||
Util.showNotify({title: jqXHR.status + ': saveSystem', text: reason, type: 'warning'});
|
||||
$(document).setProgramStatus('problem');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* calculate the x/y coordinates for a new system - relativ to a source system
|
||||
* @param sourceSystem
|
||||
* @returns {{x: *, y: *}}
|
||||
*/
|
||||
let calculateNewSystemPosition = function(sourceSystem){
|
||||
|
||||
// related system is available
|
||||
let currentX = sourceSystem.css('left');
|
||||
let currentY = sourceSystem.css('top');
|
||||
|
||||
// remove "px"
|
||||
currentX = parseInt( currentX.substring(0, currentX.length - 2) );
|
||||
currentY = parseInt( currentY.substring(0, currentY.length - 2) );
|
||||
|
||||
let newPosition = {
|
||||
x: currentX + config.newSystemOffset.x,
|
||||
y: currentY + config.newSystemOffset.y
|
||||
};
|
||||
|
||||
return newPosition;
|
||||
};
|
||||
|
||||
/**
|
||||
* updates all systems on map with current user Data (all users on this map)
|
||||
* update the Data of the user that is currently viewing the map (if available)
|
||||
@@ -3244,9 +3220,13 @@ define([
|
||||
// init custom scrollbars and add overlay
|
||||
parentElement.initMapScrollbar();
|
||||
|
||||
let mapElement = $(mapConfig.map.getContainer());
|
||||
|
||||
// set shortcuts
|
||||
parentElement.find('.' + config.mapWrapperClass).setMapShortcuts();
|
||||
|
||||
// show static overlay actions
|
||||
let mapElement = mapConfig.map.getContainer();
|
||||
let mapOverlay = $(mapElement).getMapOverlay('info');
|
||||
let mapOverlay = mapElement.getMapOverlay('info');
|
||||
mapOverlay.updateOverlayIcon('systemRegion', 'show');
|
||||
mapOverlay.updateOverlayIcon('connection', 'show');
|
||||
mapOverlay.updateOverlayIcon('connectionEol', 'show');
|
||||
@@ -3344,7 +3324,8 @@ define([
|
||||
return {
|
||||
getMapInstance: getMapInstance,
|
||||
clearMapInstance: clearMapInstance,
|
||||
getDataByConnection: getDataByConnection
|
||||
getDataByConnection: getDataByConnection,
|
||||
showNewSystemDialog: showNewSystemDialog
|
||||
};
|
||||
|
||||
});
|
||||
@@ -13,6 +13,11 @@ define([
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
newSystemOffset: {
|
||||
x: 130,
|
||||
y: 0
|
||||
},
|
||||
|
||||
systemActiveClass: 'pf-system-active' // class for an active system in a map
|
||||
};
|
||||
|
||||
@@ -193,8 +198,32 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* calculate the x/y coordinates for a new system - relativ to a source system
|
||||
* @param sourceSystem
|
||||
* @returns {{x: *, y: *}}
|
||||
*/
|
||||
let calculateNewSystemPosition = function(sourceSystem){
|
||||
|
||||
// related system is available
|
||||
let currentX = sourceSystem.css('left');
|
||||
let currentY = sourceSystem.css('top');
|
||||
|
||||
// remove "px"
|
||||
currentX = parseInt( currentX.substring(0, currentX.length - 2) );
|
||||
currentY = parseInt( currentY.substring(0, currentY.length - 2) );
|
||||
|
||||
let newPosition = {
|
||||
x: currentX + config.newSystemOffset.x,
|
||||
y: currentY + config.newSystemOffset.y
|
||||
};
|
||||
|
||||
return newPosition;
|
||||
};
|
||||
|
||||
return {
|
||||
deleteSystems: deleteSystems,
|
||||
removeSystems: removeSystems
|
||||
removeSystems: removeSystems,
|
||||
calculateNewSystemPosition: calculateNewSystemPosition
|
||||
};
|
||||
});
|
||||
@@ -5,8 +5,9 @@
|
||||
define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util'
|
||||
], function($, Init, Util) {
|
||||
'app/util',
|
||||
'bootbox'
|
||||
], function($, Init, Util, bootbox) {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
@@ -17,9 +18,12 @@ define([
|
||||
mapLocalStoragePrefix: 'map_', // prefix for map data local storage key
|
||||
mapTabContentClass: 'pf-map-tab-content', // Tab-Content element (parent element)
|
||||
|
||||
mapClass: 'pf-map', // class for all maps
|
||||
mapGridClass: 'pf-grid-small', // class for map grid snapping
|
||||
|
||||
systemIdPrefix: 'pf-system-', // id prefix for a system
|
||||
systemClass: 'pf-system', // class for all systems
|
||||
mapGridClass: 'pf-grid-small' // class for map grid snapping
|
||||
systemSelectedClass: 'pf-system-selected' // class for selected systems in a map
|
||||
};
|
||||
|
||||
// map menu options
|
||||
@@ -198,6 +202,15 @@ define([
|
||||
return this.find('.' + config.systemClass);
|
||||
};
|
||||
|
||||
/**
|
||||
* get all selected (NOT active) systems in a map
|
||||
* @returns {*}
|
||||
*/
|
||||
$.fn.getSelectedSystems = function(){
|
||||
let mapElement = $(this);
|
||||
return mapElement.find('.' + config.systemSelectedClass);
|
||||
};
|
||||
|
||||
/**
|
||||
* search connections by systems
|
||||
* @param {Object} map - jsPlumb
|
||||
@@ -577,6 +590,40 @@ define([
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* set map "shortcut" events
|
||||
*/
|
||||
$.fn.setMapShortcuts = function(){
|
||||
return this.each((i, mapWrapper) => {
|
||||
mapWrapper = $(mapWrapper);
|
||||
let mapElement = mapWrapper.findMapElement();
|
||||
|
||||
// dynamic require Map module -> otherwise there is a require(), loop
|
||||
let Map = require('app/map/map');
|
||||
let map = Map.getMapInstance( mapElement.data('id'));
|
||||
|
||||
mapWrapper.watchKey('mapSystemAdd', (mapWrapper) => {
|
||||
console.log('mapSystemAdd');
|
||||
Map.showNewSystemDialog(map, {position: {x: 0, y: 0}});
|
||||
},{focus: true});
|
||||
|
||||
mapWrapper.watchKey('mapSystemsSelect', (mapWrapper) => {
|
||||
mapElement.selectAllSystems();
|
||||
},{focus: true});
|
||||
|
||||
mapWrapper.watchKey('mapSystemsDelete', (mapWrapper) => {
|
||||
console.log('mapSystemsDelete');
|
||||
let selectedSystems = mapElement.getSelectedSystems();
|
||||
$.fn.showDeleteSystemDialog(map, selectedSystems);
|
||||
},{focus: true});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.findMapElement = function(){
|
||||
return $(this).find('.' + config.mapClass);
|
||||
};
|
||||
|
||||
/**
|
||||
* get systemId string (selector
|
||||
* @param mapId
|
||||
|
||||
@@ -10,6 +10,7 @@ define([
|
||||
'app/logging',
|
||||
'app/page',
|
||||
'app/map/worker',
|
||||
'app/key',
|
||||
'app/ui/form_element',
|
||||
'app/module_map'
|
||||
], ($, Init, Util, Render, Logging, Page, MapWorker) => {
|
||||
@@ -30,7 +31,7 @@ define([
|
||||
|
||||
// load page
|
||||
// load info (maintenance) info panel (if scheduled)
|
||||
$('body').loadPageStructure();
|
||||
$('body').loadPageStructure().setGlobalShortcuts();
|
||||
|
||||
// show app information in browser console
|
||||
Util.showVersionInfo();
|
||||
|
||||
@@ -16,6 +16,7 @@ define([
|
||||
'dialog/map_info',
|
||||
'dialog/account_settings',
|
||||
'dialog/manual',
|
||||
'dialog/shortcuts',
|
||||
'dialog/map_settings',
|
||||
'dialog/system_effects',
|
||||
'dialog/jump_info',
|
||||
@@ -62,7 +63,10 @@ define([
|
||||
menuHeadMenuLogoClass: 'pf-head-menu-logo', // class for main menu logo
|
||||
|
||||
// helper element
|
||||
dynamicElementWrapperId: 'pf-dialog-wrapper'
|
||||
dynamicElementWrapperId: 'pf-dialog-wrapper',
|
||||
|
||||
// system signature module
|
||||
systemSigModuleClass: 'pf-sig-table-module', // module wrapper (signatures)
|
||||
};
|
||||
|
||||
let programStatusCounter = 0; // current count down in s until next status change is possible
|
||||
@@ -74,49 +78,83 @@ define([
|
||||
* @returns {*|jQuery|HTMLElement}
|
||||
*/
|
||||
$.fn.loadPageStructure = function(){
|
||||
let body = $(this);
|
||||
return this.each((i, body) => {
|
||||
body = $(body);
|
||||
|
||||
// menu left
|
||||
body.prepend(
|
||||
$('<div>', {
|
||||
class: [config.pageSlidebarClass, config.pageSlidebarLeftClass, 'sb-style-push', 'sb-width-custom'].join(' ')
|
||||
}).attr('data-sb-width', config.pageSlideLeftWidth)
|
||||
);
|
||||
|
||||
// menu right
|
||||
body.prepend(
|
||||
$('<div>', {
|
||||
class: [config.pageSlidebarClass, config.pageSlidebarRightClass, 'sb-style-push', 'sb-width-custom'].join(' ')
|
||||
}).attr('data-sb-width', config.pageSlideRightWidth)
|
||||
);
|
||||
|
||||
// main page
|
||||
body.prepend(
|
||||
$('<div>', {
|
||||
id: config.pageId,
|
||||
class: config.pageClass
|
||||
}).append(
|
||||
Util.getMapModule()
|
||||
).append(
|
||||
// menu left
|
||||
body.prepend(
|
||||
$('<div>', {
|
||||
id: config.dynamicElementWrapperId
|
||||
})
|
||||
)
|
||||
);
|
||||
class: [config.pageSlidebarClass, config.pageSlidebarLeftClass, 'sb-style-push', 'sb-width-custom'].join(' ')
|
||||
}).attr('data-sb-width', config.pageSlideLeftWidth)
|
||||
);
|
||||
|
||||
// load header / footer
|
||||
$('.' + config.pageClass).loadHeader().loadFooter();
|
||||
// menu right
|
||||
body.prepend(
|
||||
$('<div>', {
|
||||
class: [config.pageSlidebarClass, config.pageSlidebarRightClass, 'sb-style-push', 'sb-width-custom'].join(' ')
|
||||
}).attr('data-sb-width', config.pageSlideRightWidth)
|
||||
);
|
||||
|
||||
// load left menu
|
||||
$('.' + config.pageSlidebarLeftClass).loadLeftMenu();
|
||||
// main page
|
||||
body.prepend(
|
||||
$('<div>', {
|
||||
id: config.pageId,
|
||||
class: config.pageClass
|
||||
}).append(
|
||||
Util.getMapModule()
|
||||
).append(
|
||||
$('<div>', {
|
||||
id: config.dynamicElementWrapperId
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
// load right menu
|
||||
$('.' + config.pageSlidebarRightClass).loadRightMenu();
|
||||
// load header / footer
|
||||
$('.' + config.pageClass).loadHeader().loadFooter();
|
||||
|
||||
// set document observer for global events
|
||||
setDocumentObserver();
|
||||
// load left menu
|
||||
$('.' + config.pageSlidebarLeftClass).loadLeftMenu();
|
||||
|
||||
return body;
|
||||
// load right menu
|
||||
$('.' + config.pageSlidebarRightClass).loadRightMenu();
|
||||
|
||||
// set document observer for global events
|
||||
setDocumentObserver();
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.setGlobalShortcuts = function(){
|
||||
return this.each((i, body) => {
|
||||
body = $(body);
|
||||
|
||||
console.log('setGlobalShortcuts');
|
||||
|
||||
body.watchKey('tabReload', (body) => {
|
||||
location.reload();
|
||||
});
|
||||
|
||||
body.watchKey('signaturePaste', (e) => {
|
||||
let moduleElement = $('.' + config.systemSigModuleClass);
|
||||
|
||||
// check if there is a signature module active (system clicked)
|
||||
if(moduleElement.length){
|
||||
e = e.originalEvent;
|
||||
let targetElement = $(e.target);
|
||||
|
||||
// do not read clipboard if pasting into form elements
|
||||
if(
|
||||
targetElement.prop('tagName').toLowerCase() !== 'input' &&
|
||||
targetElement.prop('tagName').toLowerCase() !== 'textarea' || (
|
||||
targetElement.is('input[type="search"]') // Datatables "search" field bubbles `paste.DT` event :(
|
||||
)
|
||||
){
|
||||
let clipboard = (e.originalEvent || e).clipboardData.getData('text/plain');
|
||||
moduleElement.trigger('pf:updateSystemSignatureModuleByClipboard', [clipboard]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -355,6 +393,22 @@ define([
|
||||
).on('click', function(){
|
||||
$(document).triggerMenuEvent('Manual');
|
||||
})
|
||||
).append(
|
||||
$('<a>', {
|
||||
class: 'list-group-item list-group-item-info',
|
||||
href: '#'
|
||||
}).html(' Shortcuts').prepend(
|
||||
$('<i>',{
|
||||
class: 'fa fa-keyboard-o fa-fw'
|
||||
})
|
||||
).append(
|
||||
$('<span>',{
|
||||
class: 'badge bg-color bg-color-gray txt-color txt-color-warning',
|
||||
text: 'beta'
|
||||
})
|
||||
).on('click', function(){
|
||||
$(document).triggerMenuEvent('Shortcuts');
|
||||
})
|
||||
).append(
|
||||
$('<a>', {
|
||||
class: 'list-group-item list-group-item-info',
|
||||
@@ -586,6 +640,18 @@ define([
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on('pf:menuShowTaskManager', function(e, data){
|
||||
// show log dialog
|
||||
Logging.showDialog();
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on('pf:menuShortcuts', function(e, data){
|
||||
// show shortcuts dialog
|
||||
$.fn.showShortcutsDialog();
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on('pf:menuShowSettingsDialog', function(e){
|
||||
// show character select dialog
|
||||
$.fn.showSettingsDialog();
|
||||
@@ -626,12 +692,6 @@ define([
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on('pf:menuShowTaskManager', function(e, data){
|
||||
// show log dialog
|
||||
Logging.showDialog();
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on('pf:menuLogout', function(e, data){
|
||||
|
||||
let clearCookies = false;
|
||||
|
||||
@@ -9,9 +9,10 @@ define([
|
||||
'app/render',
|
||||
'bootbox',
|
||||
], function($, Init, Util, Render, bootbox) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var config = {
|
||||
let config = {
|
||||
// jump info dialog
|
||||
jumpInfoDialogClass: 'pf-jump-info-dialog' // class for jump info dialog
|
||||
};
|
||||
@@ -22,12 +23,10 @@ define([
|
||||
$.fn.showJumpInfoDialog = function(){
|
||||
|
||||
requirejs(['text!templates/dialog/jump_info.html', 'mustache'], function(template, Mustache) {
|
||||
let data = {};
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
var data = {};
|
||||
|
||||
var content = Mustache.render(template, data);
|
||||
|
||||
var signatureReaderDialog = bootbox.dialog({
|
||||
let signatureReaderDialog = bootbox.dialog({
|
||||
className: config.jumpInfoDialogClass,
|
||||
title: 'Wormhole jump information',
|
||||
message: content
|
||||
|
||||
@@ -12,7 +12,7 @@ define([
|
||||
|
||||
'use strict';
|
||||
|
||||
var config = {
|
||||
let config = {
|
||||
// global dialog
|
||||
dialogNavigationClass: 'pf-dialog-navigation-list', // class for dialog navigation bar
|
||||
dialogNavigationListItemClass: 'pf-dialog-navigation-list-item', // class for map manual li main navigation elements
|
||||
@@ -28,7 +28,7 @@ define([
|
||||
|
||||
requirejs(['text!templates/dialog/map_manual.html', 'mustache'], function(template, Mustache) {
|
||||
|
||||
var data = {
|
||||
let data = {
|
||||
dialogNavigationClass: config.dialogNavigationClass,
|
||||
dialogNavLiClass: config.dialogNavigationListItemClass,
|
||||
scrollspyId: config.mapManualScrollspyId,
|
||||
@@ -36,10 +36,10 @@ define([
|
||||
mapCounterClass : Init.classes.pieChart.pieChartMapCounterClass
|
||||
};
|
||||
|
||||
var content = Mustache.render(template, data);
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
// show dialog
|
||||
var mapManualDialog = bootbox.dialog({
|
||||
let mapManualDialog = bootbox.dialog({
|
||||
title: 'Manual',
|
||||
message: content,
|
||||
size: 'large',
|
||||
@@ -56,15 +56,15 @@ define([
|
||||
});
|
||||
|
||||
// modal offset top
|
||||
var modalOffsetTop = 200;
|
||||
let modalOffsetTop = 200;
|
||||
|
||||
// disable on scroll event
|
||||
var disableOnScrollEvent = false;
|
||||
let disableOnScrollEvent = false;
|
||||
|
||||
// scroll breakpoints
|
||||
var scrolLBreakpointElements = null;
|
||||
let scrolLBreakpointElements = null;
|
||||
// scroll navigation links
|
||||
var scrollNavLiElements = null;
|
||||
let scrollNavLiElements = null;
|
||||
|
||||
mapManualDialog.on('shown.bs.modal', function(e) {
|
||||
// modal on open
|
||||
@@ -72,13 +72,13 @@ define([
|
||||
scrollNavLiElements = $('.' + config.dialogNavigationListItemClass);
|
||||
});
|
||||
|
||||
var scrollspyElement = $('#' + config.mapManualScrollspyId);
|
||||
let scrollspyElement = $('#' + config.mapManualScrollspyId);
|
||||
|
||||
var whileScrolling = function(){
|
||||
let whileScrolling = function(){
|
||||
|
||||
if(disableOnScrollEvent === false){
|
||||
for(var i = 0; i < scrolLBreakpointElements.length; i++){
|
||||
var offset = $(scrolLBreakpointElements[i]).offset().top;
|
||||
for(let i = 0; i < scrolLBreakpointElements.length; i++){
|
||||
let offset = $(scrolLBreakpointElements[i]).offset().top;
|
||||
|
||||
if( (offset - modalOffsetTop) > 0){
|
||||
|
||||
@@ -116,11 +116,11 @@ define([
|
||||
scrollspyElement.find('.' + data.mapCounterClass).initMapUpdateCounter();
|
||||
|
||||
// set navigation button observer
|
||||
var mainNavigationLinks = $('.' + config.dialogNavigationClass).find('a');
|
||||
let mainNavigationLinks = $('.' + config.dialogNavigationClass).find('a');
|
||||
// text anchor links
|
||||
var subNavigationLinks = scrollspyElement.find('a[data-target]');
|
||||
let subNavigationLinks = scrollspyElement.find('a[data-target]');
|
||||
|
||||
var navigationLinks = mainNavigationLinks.add(subNavigationLinks);
|
||||
let navigationLinks = mainNavigationLinks.add(subNavigationLinks);
|
||||
|
||||
navigationLinks.on('click', function(e){
|
||||
e.preventDefault();
|
||||
@@ -130,7 +130,7 @@ define([
|
||||
// scroll to anchor
|
||||
scrollspyElement.mCustomScrollbar('scrollTo', $(this).attr('data-target'));
|
||||
|
||||
var mainNavigationLiElement = $(this).parent('.' + config.dialogNavigationListItemClass);
|
||||
let mainNavigationLiElement = $(this).parent('.' + config.dialogNavigationListItemClass);
|
||||
|
||||
|
||||
whileScrolling();
|
||||
|
||||
@@ -12,7 +12,7 @@ define([
|
||||
|
||||
'use strict';
|
||||
|
||||
var config = {
|
||||
let config = {
|
||||
|
||||
// shutdown dialog
|
||||
notificationDialogId: 'pf-notification-dialog', // id for "notification" dialog
|
||||
@@ -23,8 +23,8 @@ define([
|
||||
* show/animate dialog page content
|
||||
* @param dialog
|
||||
*/
|
||||
var showPageContent = function(dialog){
|
||||
var headlineElement = dialog.find('h1');
|
||||
let showPageContent = function(dialog){
|
||||
let headlineElement = dialog.find('h1');
|
||||
|
||||
headlineElement.delay(300).velocity('transition.shrinkIn', {
|
||||
duration: 500
|
||||
@@ -45,7 +45,7 @@ define([
|
||||
$.fn.showNotificationDialog = function(dialogData){
|
||||
|
||||
// check if there is already a notification dialog open
|
||||
var notificationDialogClassDialoges = $('.' + config.notificationDialogClass);
|
||||
let notificationDialogClassDialoges = $('.' + config.notificationDialogClass);
|
||||
|
||||
if(notificationDialogClassDialoges.length === 0){
|
||||
|
||||
@@ -54,15 +54,15 @@ define([
|
||||
|
||||
requirejs(['text!templates/dialog/notification.html', 'mustache'], function(template, Mustache) {
|
||||
|
||||
var data = {
|
||||
let data = {
|
||||
id: config.notificationDialogId,
|
||||
content: dialogData.content
|
||||
};
|
||||
|
||||
var content = Mustache.render(template, data);
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
// show dialog
|
||||
var shutdownDialog = bootbox.dialog({
|
||||
let shutdownDialog = bootbox.dialog({
|
||||
title: dialogData.content.title,
|
||||
message: content,
|
||||
className: config.notificationDialogClass,
|
||||
@@ -72,7 +72,7 @@ define([
|
||||
|
||||
shutdownDialog.on('shown.bs.modal', function(e) {
|
||||
// remove close button
|
||||
var dialog = $(this);
|
||||
let dialog = $(this);
|
||||
|
||||
dialog.find('.bootbox-close-button').remove();
|
||||
dialog.find('button').blur();
|
||||
|
||||
50
public/js/v1.2.1/app/ui/dialog/shortcuts.js
Normal file
50
public/js/v1.2.1/app/ui/dialog/shortcuts.js
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* shortcuts dialog
|
||||
*/
|
||||
|
||||
define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util',
|
||||
'app/render',
|
||||
'bootbox',
|
||||
'app/key',
|
||||
], function($, Init, Util, Render, bootbox, Key) {
|
||||
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
// map dialog
|
||||
shortcutsDialogId: 'pf-shortcuts-dialog', // id for shortcuts dialog
|
||||
};
|
||||
|
||||
/**
|
||||
* shows the map manual modal dialog
|
||||
*/
|
||||
$.fn.showShortcutsDialog = function(){
|
||||
requirejs(['text!templates/dialog/shortcuts.html', 'mustache'], function(template, Mustache){
|
||||
|
||||
let data = {
|
||||
id: config.shortcutsDialogId,
|
||||
shortcuts: Key.getGroupedShortcuts()
|
||||
};
|
||||
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
// show dialog
|
||||
let shortcutsDialog = bootbox.dialog({
|
||||
title: 'Keyboard Shortcuts',
|
||||
message: content,
|
||||
size: 'large',
|
||||
buttons: {
|
||||
success: {
|
||||
label: 'close',
|
||||
className: 'btn-default'
|
||||
}
|
||||
},
|
||||
show: true
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
});
|
||||
@@ -13,12 +13,12 @@ define([
|
||||
], function($, Init, Util, Render, bootbox, MapUtil) {
|
||||
'use strict';
|
||||
|
||||
var config = {
|
||||
let config = {
|
||||
// system effect dialog
|
||||
systemEffectDialogWrapperClass: 'pf-system-effect-dialog-wrapper' // class for system effect dialog
|
||||
};
|
||||
|
||||
var cache = {
|
||||
let cache = {
|
||||
systemEffectDialog: false // system effect info dialog
|
||||
};
|
||||
|
||||
@@ -30,31 +30,31 @@ define([
|
||||
// cache table structure
|
||||
if(!cache.systemEffectDialog){
|
||||
|
||||
var dialogWrapperElement = $('<div>', {
|
||||
let dialogWrapperElement = $('<div>', {
|
||||
class: config.systemEffectDialogWrapperClass
|
||||
});
|
||||
|
||||
var systemEffectData = Util.getSystemEffectData();
|
||||
let systemEffectData = Util.getSystemEffectData();
|
||||
|
||||
$.each( systemEffectData.wh, function( effectName, effectData ) {
|
||||
|
||||
var table = $('<table>', {
|
||||
let table = $('<table>', {
|
||||
class: ['table', 'table-condensed'].join(' ')
|
||||
});
|
||||
|
||||
var tbody = $('<tbody>');
|
||||
var thead = $('<thead>');
|
||||
let tbody = $('<tbody>');
|
||||
let thead = $('<thead>');
|
||||
|
||||
var rows = [];
|
||||
let rows = [];
|
||||
|
||||
// get formatted system effect name
|
||||
var systemEffectName = MapUtil.getEffectInfoForSystem(effectName, 'name');
|
||||
var systemEffectClass = MapUtil.getEffectInfoForSystem(effectName, 'class');
|
||||
let systemEffectName = MapUtil.getEffectInfoForSystem(effectName, 'name');
|
||||
let systemEffectClass = MapUtil.getEffectInfoForSystem(effectName, 'class');
|
||||
|
||||
$.each( effectData, function( areaId, areaData ) {
|
||||
|
||||
var systemType = 'C' + areaId;
|
||||
var securityClass = Util.getSecurityClassForSystem( systemType );
|
||||
let systemType = 'C' + areaId;
|
||||
let securityClass = Util.getSecurityClassForSystem( systemType );
|
||||
|
||||
if(areaId === '1'){
|
||||
rows.push( $('<tr>') );
|
||||
|
||||
@@ -15,7 +15,7 @@ define([
|
||||
* init a select element as "select2" for map selection
|
||||
*/
|
||||
$.fn.initMapSelect = function(){
|
||||
var selectElement = $(this);
|
||||
let selectElement = $(this);
|
||||
|
||||
$.when(
|
||||
selectElement.select2({
|
||||
@@ -31,9 +31,9 @@ define([
|
||||
* @param options
|
||||
*/
|
||||
$.fn.initSystemSelect = function(options){
|
||||
var selectElement = $(this);
|
||||
let selectElement = $(this);
|
||||
|
||||
var config = {
|
||||
let config = {
|
||||
maxSelectionLength: 1
|
||||
};
|
||||
options = $.extend({}, config, options);
|
||||
@@ -46,12 +46,12 @@ define([
|
||||
}
|
||||
|
||||
// show effect info just for wormholes
|
||||
var hideEffectClass = '';
|
||||
let hideEffectClass = '';
|
||||
if(data.effect === ''){
|
||||
hideEffectClass = 'hide';
|
||||
}
|
||||
|
||||
var markup = '<div class="clearfix">';
|
||||
let markup = '<div class="clearfix">';
|
||||
markup += '<div class="col-sm-5 pf-select-item-anchor">' + data.text + '</div>';
|
||||
markup += '<div class="col-sm-2 text-right ' + data.effectClass + '">';
|
||||
markup += '<i class="fa fa-fw fa-square ' + hideEffectClass + '"></i>';
|
||||
@@ -83,12 +83,12 @@ define([
|
||||
results: data.map( function(item){
|
||||
|
||||
// "systemId" or "name"
|
||||
var id = item[options.key];
|
||||
var disabled = false;
|
||||
var trueSec = parseFloat(item.trueSec);
|
||||
var secClass = Util.getSecurityClassForSystem(item.security);
|
||||
var trueSecClass = Util.getTrueSecClassForSystem( trueSec );
|
||||
var effectClass = MapUtil.getEffectInfoForSystem(item.effect, 'class');
|
||||
let id = item[options.key];
|
||||
let disabled = false;
|
||||
let trueSec = parseFloat(item.trueSec);
|
||||
let secClass = Util.getSecurityClassForSystem(item.security);
|
||||
let trueSecClass = Util.getTrueSecClassForSystem( trueSec );
|
||||
let effectClass = MapUtil.getEffectInfoForSystem(item.effect, 'class');
|
||||
|
||||
// check if system is dialed
|
||||
if(
|
||||
@@ -126,7 +126,7 @@ define([
|
||||
error: function (jqXHR, status, error) {
|
||||
if( !Util.isXHRAborted(jqXHR) ){
|
||||
|
||||
var reason = status + ' ' + jqXHR.status + ': ' + error;
|
||||
let reason = status + ' ' + jqXHR.status + ': ' + error;
|
||||
Util.showNotify({title: 'System select warning', text: reason + ' deleted', type: 'warning'});
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ define([
|
||||
|
||||
return this.each(function(){
|
||||
|
||||
var selectElement = $(this);
|
||||
let selectElement = $(this);
|
||||
|
||||
// format result data
|
||||
function formatResultData (data) {
|
||||
@@ -172,7 +172,7 @@ define([
|
||||
|
||||
// check if an option is already selected
|
||||
// do not show the same result twice
|
||||
var currentValues = selectElement.val();
|
||||
let currentValues = selectElement.val();
|
||||
|
||||
if(
|
||||
currentValues &&
|
||||
@@ -181,8 +181,8 @@ define([
|
||||
return ;
|
||||
}
|
||||
|
||||
var imagePath = '';
|
||||
var previewContent = '';
|
||||
let imagePath = '';
|
||||
let previewContent = '';
|
||||
|
||||
switch(options.type){
|
||||
case 'character':
|
||||
@@ -199,7 +199,7 @@ define([
|
||||
break;
|
||||
}
|
||||
|
||||
var markup = '<div class="clearfix">';
|
||||
let markup = '<div class="clearfix">';
|
||||
markup += '<div class="col-sm-2">' + previewContent + '</div>';
|
||||
markup += '<div class="col-sm-10">' + data.text + '</div></div>';
|
||||
|
||||
@@ -213,7 +213,7 @@ define([
|
||||
return data.text;
|
||||
}
|
||||
|
||||
var markup = '<div class="clearfix">';
|
||||
let markup = '<div class="clearfix">';
|
||||
markup += '<div class="col-sm-10">' + data.text + '</div></div>';
|
||||
|
||||
return markup;
|
||||
@@ -248,7 +248,7 @@ define([
|
||||
error: function (jqXHR, status, error) {
|
||||
if( !Util.isXHRAborted(jqXHR) ){
|
||||
|
||||
var reason = status + ' ' + jqXHR.status + ': ' + error;
|
||||
let reason = status + ' ' + jqXHR.status + ': ' + error;
|
||||
Util.showNotify({title: 'Access select warning', text: reason + ' deleted', type: 'warning'});
|
||||
}
|
||||
|
||||
|
||||
@@ -2206,20 +2206,8 @@ define([
|
||||
});
|
||||
|
||||
// event listener for global "paste" signatures into the page -------------------------------------------------
|
||||
$('body').off('paste').on('paste', function(e){
|
||||
let targetElement = $(e.target);
|
||||
|
||||
// do not read clipboard if pasting into form elements
|
||||
if(
|
||||
targetElement.prop('tagName').toLowerCase() !== 'input' &&
|
||||
targetElement.prop('tagName').toLowerCase() !== 'textarea' || (
|
||||
targetElement.is('input[type="search"]') // Datatables "search" field bubbles `paste.DT` event :(
|
||||
)
|
||||
){
|
||||
let clipboard = (e.originalEvent || e).clipboardData.getData('text/plain');
|
||||
|
||||
moduleElement.updateSignatureTableByClipboard(systemData, clipboard, {});
|
||||
}
|
||||
moduleElement.on('pf:updateSystemSignatureModuleByClipboard', function(e, clipboard){
|
||||
$(this).updateSignatureTableByClipboard(systemData, clipboard, {});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
22
public/templates/dialog/shortcuts.html
Normal file
22
public/templates/dialog/shortcuts.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<div id="{{id}}" class="row">
|
||||
{{#shortcuts}}
|
||||
<div class="col-sm-6">
|
||||
<h4>{{label}}</h4>
|
||||
|
||||
<table class="table table-condensed">
|
||||
<tbody>
|
||||
{{#events}}
|
||||
<tr>
|
||||
<td>{{label}}</td>
|
||||
<td class="text-right">
|
||||
{{#keyNames}}
|
||||
<kbd>{{.}}</kbd> <i class="fa fa-fw fa-plus"></i>
|
||||
{{/keyNames}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/events}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{/shortcuts}}
|
||||
</div>
|
||||
@@ -111,7 +111,6 @@
|
||||
<th class="bg-color bg-color-grayDarker"></th>
|
||||
<th class="bg-color bg-color-tealDarker txt-color txt-color-orange"></th>
|
||||
</tr>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -121,6 +121,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
// shortcuts dialog ===========================================================
|
||||
#pf-shortcuts-dialog{
|
||||
td kbd:last-of-type{
|
||||
& + i {
|
||||
display: none
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// map manual dialog ==========================================================
|
||||
#pf-manual-scrollspy{
|
||||
position: relative;
|
||||
|
||||
@@ -56,6 +56,11 @@ $mapWidth: 2500px ;
|
||||
style: solid;
|
||||
color: $gray-dark;
|
||||
}
|
||||
|
||||
&:focus{
|
||||
border: 1px solid $gray;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user