Files
pathfinder/js/app/ui/system_info.js
Mark Friedrich 9f8634e2e8 - updated composer.json with new exodus4d/pathfinder_esi version v1.2.4
- added "rel='preload'" for resource mappage.js
- renamed "categoryModel.php" to lowercase
2018-06-08 18:31:34 +02:00

456 lines
19 KiB
JavaScript

/**
* System info module
*/
define([
'jquery',
'app/init',
'app/util',
'app/render',
'app/map/util'
], function($, Init, Util, Render, MapUtil) {
'use strict';
let config = {
// module info
modulePosition: 2,
moduleName: 'systemInfo',
// system info module
moduleTypeClass: 'pf-system-info-module', // class for this module
// breadcrumb
constellationLinkClass: 'pf-system-info-constellation', // class for "constellation" name
regionLinkClass: 'pf-system-info-region', // class for "region" name
typeLinkClass: 'pf-system-info-type', // class for "type" name
// info table
systemInfoTableClass: 'pf-module-table', // class for system info table
systemInfoNameInfoClass: 'pf-system-info-name', // class for "name" information element
systemInfoEffectInfoClass: 'pf-system-info-effect', // class for "effect" information element
systemInfoStatusLabelClass: 'pf-system-info-status-label', // class for "status" information element
systemInfoStatusAttributeName: 'data-status', // attribute name for status label
systemInfoWormholeClass: 'pf-system-info-wormhole-', // class prefix for static wormhole element
// description field
descriptionArea: 'pf-system-info-description-area', // class for "description" area
addDescriptionButtonClass: 'pf-system-info-description-button', // class for "add description" button
moduleElementToolbarClass: 'pf-table-tools', // class for "module toolbar" element
tableToolsActionClass: 'pf-table-tools-action', // class for "edit" action
descriptionTextareaElementClass: 'pf-system-info-description', // class for "description" textarea element (xEditable)
descriptionTextareaCharCounter: 'pf-form-field-char-count', // class for "character counter" element for form field
// fonts
fontTriglivianClass: 'pf-triglivian' // class for "Triglivian" names (e.g. Abyssal systems)
};
// disable Module update temporary (until. some requests/animations) are finished
let disableModuleUpdate = true;
// animation speed values
let animationSpeedToolbarAction = 200;
// max character length for system description
let maxDescriptionLength = 512;
/**
* set module observer and look for relevant system data to update
*/
let setModuleObserver = (moduleElement) => {
$(document).off('pf:updateSystemInfoModule').on('pf:updateSystemInfoModule', function(e, data){
if(data){
moduleElement.updateSystemInfoModule(data);
}
});
};
/**
* shows the tool action element by animation
* @param toolsActionElement
*/
let showToolsActionElement = (toolsActionElement) => {
toolsActionElement.velocity('stop').velocity({
opacity: 1,
height: '100%'
},{
duration: animationSpeedToolbarAction,
display: 'block',
visibility: 'visible'
});
};
/**
* hides the tool action element by animation
* @param toolsActionElement
*/
let hideToolsActionElement = (toolsActionElement) => {
toolsActionElement.velocity('stop').velocity('reverse', {
display: 'none',
visibility: 'hidden'
});
};
/**
* update trigger function for this module
* compare data and update module
* @param systemData
*/
$.fn.updateSystemInfoModule = function(systemData){
// module update is disabled
if(disableModuleUpdate === true){
return;
}
let moduleElement = $(this);
let systemId = moduleElement.data('id');
if(systemId === systemData.id){
// update module
// system status =====================================================================================
let systemStatusLabelElement = moduleElement.find('.' + config.systemInfoStatusLabelClass);
let systemStatusId = parseInt( systemStatusLabelElement.attr( config.systemInfoStatusAttributeName ) );
if(systemStatusId !== systemData.status.id){
// status changed
let currentStatusClass = Util.getStatusInfoForSystem(systemStatusId, 'class');
let newStatusClass = Util.getStatusInfoForSystem(systemData.status.id, 'class');
let newStatusLabel = Util.getStatusInfoForSystem(systemData.status.id, 'label');
systemStatusLabelElement.removeClass(currentStatusClass).addClass(newStatusClass).text(newStatusLabel);
// set new status attribute
systemStatusLabelElement.attr( config.systemInfoStatusAttributeName, systemData.status.id);
}
// description textarea element ======================================================================
let descriptionTextareaElement = moduleElement.find('.' + config.descriptionTextareaElementClass);
let description = descriptionTextareaElement.editable('getValue', true);
if(description !== systemData.description){
// description changed
// description button
let descriptionButton = moduleElement.find('.' + config.addDescriptionButtonClass);
// set new value
descriptionTextareaElement.editable('setValue', systemData.description);
let actionElement = descriptionButton.siblings('.' + config.tableToolsActionClass);
if(systemData.description.length === 0){
// show/activate description field
// show button if value is empty
descriptionButton.show();
hideToolsActionElement(actionElement);
}else{
// hide/disable description field
// hide tool button
descriptionButton.hide();
showToolsActionElement(actionElement);
}
}
// created/updated tooltip ===========================================================================
let nameRowElement = $(moduleElement).find('.' + config.systemInfoNameInfoClass);
let tooltipData = {
created: systemData.created,
updated: systemData.updated
};
nameRowElement.addCharacterInfoTooltip( tooltipData );
}
moduleElement.find('.' + config.descriptionArea).hideLoadingAnimation();
};
/**
* get module element
* @param parentElement
* @param mapId
* @param systemData
*/
let getModule = (parentElement, mapId, systemData) => {
// create new module container
let moduleElement = $('<div>');
// store systemId -> module can be updated with the correct data
moduleElement.data('id', systemData.id);
// shattered wormhole info data
let shatteredWormholeInfo = false;
// add security class for statics
if(
systemData.statics &&
systemData.statics.length > 0
){
for(let i = 0; i < systemData.statics.length; i++){
systemData.statics[i].class = Util.getSecurityClassForSystem( systemData.statics[i].security );
}
}else if(systemData.type.id === 1){
// system type "wormhole" but no statics => "shattered wormhole"
shatteredWormholeInfo = true;
}
let effectName = MapUtil.getEffectInfoForSystem(systemData.effect, 'name');
let effectClass = MapUtil.getEffectInfoForSystem(systemData.effect, 'class');
// systemInfo template config
let moduleConfig = {
name: 'modules/system_info',
position: moduleElement,
link: 'append',
functions: {
after: function(conf){
let tempModuleElement = conf.position;
// lock "description" field until first update
tempModuleElement.find('.' + config.descriptionArea).showLoadingAnimation();
// "add description" button
let descriptionButton = tempModuleElement.find('.' + config.addDescriptionButtonClass);
// description textarea element
let descriptionTextareaElement = tempModuleElement.find('.' + config.descriptionTextareaElementClass);
// init description textarea
descriptionTextareaElement.editable({
url: Init.path.saveSystem,
dataType: 'json',
pk: systemData.id,
type: 'textarea',
mode: 'inline',
emptytext: '',
onblur: 'cancel',
showbuttons: true,
value: '', // value is set by trigger function updateSystemInfoModule()
rows: 5,
name: 'description',
inputclass: config.descriptionTextareaElementClass,
tpl: '<textarea maxlength="' + maxDescriptionLength + '"></textarea>',
params: function(params){
params.mapData = {
id: mapId
};
params.systemData = {};
params.systemData.id = params.pk;
params.systemData[params.name] = params.value;
// clear unnecessary data
delete params.pk;
delete params.name;
delete params.value;
return params;
},
validate: function(value){
if(value.length > 0 && $.trim(value).length === 0) {
return {newValue: ''};
}
},
success: function(response, newValue){
Util.showNotify({title: 'System updated', text: 'Name: ' + response.name, type: 'success'});
},
error: function(jqXHR, newValue){
let reason = '';
let status = '';
if(jqXHR.name){
// save error new sig (mass save)
reason = jqXHR.name;
status = 'Error';
}else{
reason = jqXHR.responseJSON.text;
status = jqXHR.status;
}
Util.showNotify({title: status + ': save system information', text: reason, type: 'warning'});
$(document).setProgramStatus('problem');
return reason;
}
});
// on xEditable open -------------------------------------------------------------------------
descriptionTextareaElement.on('shown', function(e, editable){
let textarea = editable.input.$input;
// disable module update until description field is open
disableModuleUpdate = true;
// create character counter
let charCounter = $('<kbd>', {
class: [config.descriptionTextareaCharCounter, 'txt-color', 'text-right'].join(' ')
});
textarea.parent().next().append(charCounter);
// update character counter
Util.updateCounter(textarea, charCounter, maxDescriptionLength);
textarea.on('keyup', function(){
Util.updateCounter($(this), charCounter, maxDescriptionLength);
});
});
// on xEditable close ------------------------------------------------------------------------
descriptionTextareaElement.on('hidden', function(e){
let value = $(this).editable('getValue', true);
if(value.length === 0){
// show button if value is empty
hideToolsActionElement(descriptionButton.siblings('.' + config.tableToolsActionClass));
descriptionButton.show();
}
// enable module update
disableModuleUpdate = false;
});
// enable xEditable field on Button click ----------------------------------------------------
descriptionButton.on('click', function(e){
e.stopPropagation();
let descriptionButton = $(this);
// hide tool buttons
descriptionButton.hide();
// show field *before* showing the element
descriptionTextareaElement.editable('show');
showToolsActionElement(descriptionButton.siblings('.' + config.tableToolsActionClass));
});
// init tooltips -----------------------------------------------------------------------------
let tooltipElements = tempModuleElement.find('[data-toggle="tooltip"]');
tooltipElements.tooltip();
// init system effect popover ----------------------------------------------------------------
$(moduleElement).find('.' + config.systemInfoEffectInfoClass).addSystemEffectTooltip(systemData.security, systemData.effect);
// init static wormhole information ----------------------------------------------------------
if(systemData.statics){
for(let i = 0; i < systemData.statics.length; i++){
let staticData = systemData.statics[i];
let staticRowElement = tempModuleElement.find('.' + config.systemInfoWormholeClass + staticData.name);
staticRowElement.addWormholeInfoTooltip(staticData);
}
}
// constellation popover ---------------------------------------------------------------------
tempModuleElement.find('a.popup-ajax').popover({
html: true,
trigger: 'hover',
placement: 'top',
delay: 200,
container: 'body',
content: function(){
return details_in_popup(this);
}
});
function details_in_popup(popoverElement){
popoverElement = $(popoverElement);
let popover = popoverElement.data('bs.popover');
$.ajax({
url: popoverElement.data('url'),
success: function(data){
let systemEffectTable = Util.getSystemsInfoTable( data.systemData );
popover.options.content = systemEffectTable;
// reopen popover (new content size)
popover.show();
}
});
return 'Loading...';
}
}
}
};
let moduleData = {
system: systemData,
tableClass: config.systemInfoTableClass,
nameInfoClass: config.systemInfoNameInfoClass,
effectInfoClass: config.systemInfoEffectInfoClass,
wormholePrefixClass: config.systemInfoWormholeClass,
statusInfoClass: config.systemInfoStatusLabelClass,
systemTypeName: MapUtil.getSystemTypeInfo(systemData.type.id, 'name'),
systemIsWormhole: MapUtil.getSystemTypeInfo(systemData.type.id, 'name') === 'w-space',
systemStatusId: systemData.status.id,
systemStatusClass: Util.getStatusInfoForSystem(systemData.status.id, 'class'),
systemStatusLabel: Util.getStatusInfoForSystem(systemData.status.id, 'label'),
securityClass: Util.getSecurityClassForSystem( systemData.security ),
trueSec: systemData.trueSec.toFixed(1),
trueSecClass: Util.getTrueSecClassForSystem( systemData.trueSec ),
effectName: effectName,
effectClass: effectClass,
moduleToolbarClass: config.moduleElementToolbarClass,
descriptionButtonClass: config.addDescriptionButtonClass,
tableToolsActionClass: config.tableToolsActionClass,
descriptionTextareaClass: config.descriptionTextareaElementClass,
systemNameClass: () => {
return (val, render) => {
return render(val) === 'A' ? config.fontTriglivianClass : '';
};
},
shatteredWormholeInfo: shatteredWormholeInfo,
ajaxConstellationInfoUrl: Init.path.getConstellationData,
systemConstellationLinkClass: config.constellationLinkClass,
systemRegionLinkClass: config.regionLinkClass,
systemTypeLinkClass: config.typeLinkClass
};
Render.showModule(moduleConfig, moduleData);
return moduleElement;
};
/**
* init callback
* @param moduleElement
* @param mapId
* @param systemData
*/
let initModule = (moduleElement, mapId, systemData) => {
// set module observer
setModuleObserver(moduleElement);
// enable auto update
disableModuleUpdate = false;
};
/**
* efore module destroy callback
* @param moduleElement
*/
let beforeDestroy = (moduleElement) => {
// remove xEditable description textarea
let descriptionTextareaElement = moduleElement.find('.' + config.descriptionTextareaElementClass);
descriptionTextareaElement.editable('destroy');
};
return {
config: config,
getModule: getModule,
initModule: initModule,
beforeDestroy: beforeDestroy
};
});