@@ -231,13 +231,6 @@ class Map extends Controller\AccessController {
|
||||
}
|
||||
}
|
||||
|
||||
// Add data that should not be cached =========================================================================
|
||||
|
||||
// program mode (e.g. "maintenance") --------------------------------------------------------------------------
|
||||
$return->programMode = [
|
||||
'maintenance' => Config::getPathfinderData('login.mode_maintenance')
|
||||
];
|
||||
|
||||
// get SSO error messages that should be shown immediately ----------------------------------------------------
|
||||
// -> e.g. errors while character switch from previous HTTP requests
|
||||
if($f3->exists(Controller\Ccp\Sso::SESSION_KEY_SSO_ERROR, $message)){
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Controller\Api;
|
||||
|
||||
use Controller;
|
||||
use Model;
|
||||
use Exception;
|
||||
|
||||
class System extends Controller\AccessController {
|
||||
|
||||
@@ -79,24 +80,34 @@ class System extends Controller\AccessController {
|
||||
}
|
||||
|
||||
if( !is_null($systemModel) ){
|
||||
// set/update system custom data
|
||||
$systemModel->copyfrom($systemData, ['statusId', 'locked', 'rallyUpdated', 'position', 'description']);
|
||||
try{
|
||||
// set/update system custom data
|
||||
$systemModel->copyfrom($systemData, ['statusId', 'locked', 'rallyUpdated', 'position', 'description']);
|
||||
|
||||
if($systemModel->save($activeCharacter)){
|
||||
// get data from "fresh" model (e.g. some relational data has changed: "statusId")
|
||||
/**
|
||||
* @var $newSystemModel Model\SystemModel
|
||||
*/
|
||||
$newSystemModel = Model\BasicModel::getNew('SystemModel');
|
||||
$newSystemModel->getById( $systemModel->_id, 0);
|
||||
$newSystemModel->clearCacheData();
|
||||
$return->systemData = $newSystemModel->getData();
|
||||
if($systemModel->save($activeCharacter)){
|
||||
// get data from "fresh" model (e.g. some relational data has changed: "statusId")
|
||||
/**
|
||||
* @var $newSystemModel Model\SystemModel
|
||||
*/
|
||||
$newSystemModel = Model\BasicModel::getNew('SystemModel');
|
||||
$newSystemModel->getById( $systemModel->_id, 0);
|
||||
$newSystemModel->clearCacheData();
|
||||
$return->systemData = $newSystemModel->getData();
|
||||
|
||||
// broadcast map changes
|
||||
$this->broadcastMapData($newSystemModel->mapId);
|
||||
}else{
|
||||
$return->error = $systemModel->getErrors();
|
||||
// broadcast map changes
|
||||
$this->broadcastMapData($newSystemModel->mapId);
|
||||
}else{
|
||||
$return->error = $systemModel->getErrors();
|
||||
}
|
||||
}catch(Exception\ValidationException $e){
|
||||
$validationError = (object) [];
|
||||
$validationError->type = 'error';
|
||||
$validationError->field = $e->getField();
|
||||
$validationError->message = $e->getMessage();
|
||||
$return->error[] = $validationError;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,13 +284,14 @@ class System extends Controller\AccessController {
|
||||
$requestData = (array)$f3->get('POST');
|
||||
$mapId = (int)$requestData['mapId'];
|
||||
$systemId = (int)$requestData['systemId'];
|
||||
$isCcpId = (bool)$requestData['isCcpId'];
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
$return = (object) [];
|
||||
|
||||
if(
|
||||
!is_null($map = $activeCharacter->getMap($mapId)) &&
|
||||
!is_null($system = $map->getSystemById($systemId))
|
||||
!is_null($system = $isCcpId ? $map->getSystemByCCPId($systemId) : $map->getSystemById($systemId))
|
||||
){
|
||||
$return->system = $system->getData();
|
||||
$return->system->signatures = $system->getSignaturesData();
|
||||
|
||||
@@ -94,10 +94,11 @@ class SystemModel extends AbstractMapTrackingModel {
|
||||
'activity-log' => true
|
||||
],
|
||||
'description' => [
|
||||
'type' => Schema::DT_VARCHAR512,
|
||||
'type' => Schema::DT_TEXT,
|
||||
'nullable' => false,
|
||||
'default' => '',
|
||||
'activity-log' => true
|
||||
'activity-log' => true,
|
||||
'validate' => true
|
||||
],
|
||||
'posX' => [
|
||||
'type' => Schema::DT_INT,
|
||||
@@ -262,6 +263,21 @@ class SystemModel extends AbstractMapTrackingModel {
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string $val
|
||||
* @return bool
|
||||
* @throws \Exception\ValidationException
|
||||
*/
|
||||
protected function validate_description(string $key, string $val): bool {
|
||||
$valid = true;
|
||||
if(mb_strlen($val) > 9000){
|
||||
$valid = false;
|
||||
$this->throwValidationException($key);
|
||||
}
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* setter for system alias
|
||||
* @param string $alias
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[PATHFINDER]
|
||||
NAME = Pathfinder
|
||||
; installed version (used for CSS/JS cache busting)
|
||||
VERSION = v1.4.1
|
||||
VERSION = v1.4.2
|
||||
; contact information [optional]
|
||||
CONTACT = https://github.com/exodus4d
|
||||
; public contact email [optional]
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
"php-64bit": ">=7.0",
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-ctype": "*",
|
||||
"ext-zmq": ">=1.1.3",
|
||||
"react/zmq": "0.3.*",
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
"php-64bit": ">=7.0",
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-ctype": "*",
|
||||
"ext-zmq": ">=1.1.3",
|
||||
"react/zmq": "0.3.*",
|
||||
|
||||
94
js/app.js
94
js/app.js
@@ -25,37 +25,40 @@ requirejs.config({
|
||||
admin: './app/admin', // initial start "admin page" view
|
||||
notification: './app/notification', // "notification" view
|
||||
|
||||
jquery: 'lib/jquery-3.3.1.min', // v3.3.1 jQuery
|
||||
bootstrap: 'lib/bootstrap.min', // v3.3.0 Bootstrap js code - http://getbootstrap.com/javascript
|
||||
text: 'lib/requirejs/text', // v2.0.12 A RequireJS/AMD loader plugin for loading text resources.
|
||||
mustache: 'lib/mustache.min', // v1.0.0 Javascript template engine - http://mustache.github.io
|
||||
localForage: 'lib/localforage.min', // v1.4.2 localStorage library - https://mozilla.github.io/localForage
|
||||
velocity: 'lib/velocity.min', // v1.5.1 animation engine - http://julian.com/research/velocity
|
||||
velocityUI: 'lib/velocity.ui.min', // v5.2.0 plugin for velocity - http://julian.com/research/velocity/#uiPack
|
||||
slidebars: 'lib/slidebars', // v0.10 Slidebars - side menu plugin http://plugins.adchsm.me/slidebars
|
||||
jsPlumb: 'lib/dom.jsPlumb-1.7.6', // v1.7.6 jsPlumb (Vanilla)- main map draw plugin https://jsplumbtoolkit.com
|
||||
farahey: 'lib/farahey-0.5', // v0.5 jsPlumb "magnetizing" extension - https://github.com/jsplumb/farahey
|
||||
customScrollbar: 'lib/jquery.mCustomScrollbar.min', // v3.1.5 Custom scroll bars - http://manos.malihu.gr
|
||||
mousewheel: 'lib/jquery.mousewheel.min', // v3.1.13 Mousewheel - https://github.com/jquery/jquery-mousewheel
|
||||
xEditable: 'lib/bootstrap-editable.min', // v1.5.1 X-editable - in placed editing
|
||||
morris: 'lib/morris.min', // v0.5.1 Morris.js - graphs and charts
|
||||
raphael: 'lib/raphael-min', // v2.1.2 Raphaël - required for morris (dependency)
|
||||
bootbox: 'lib/bootbox.min', // v4.4.0 Bootbox.js - custom dialogs - http://bootboxjs.com
|
||||
easyPieChart: 'lib/jquery.easypiechart.min', // v2.1.6 Easy Pie Chart - HTML 5 pie charts - http://rendro.github.io/easy-pie-chart
|
||||
peityInlineChart: 'lib/jquery.peity.min', // v3.2.1 Inline Chart - http://benpickles.github.io/peity/
|
||||
dragToSelect: 'lib/jquery.dragToSelect', // v1.1 Drag to Select - http://andreaslagerkvist.com/jquery/drag-to-select
|
||||
hoverIntent: 'lib/jquery.hoverIntent.min', // v1.9.0 Hover intention - http://cherne.net/brian/resources/jquery.hoverIntent.html
|
||||
fullScreen: 'lib/jquery.fullscreen.min', // v0.6.0 Full screen mode - https://github.com/private-face/jquery.fullscreen
|
||||
select2: 'lib/select2.min', // v4.0.3 Drop Down customization - https://select2.github.io
|
||||
validator: 'lib/validator.min', // v0.10.1 Validator for Bootstrap 3 - https://github.com/1000hz/bootstrap-validator
|
||||
lazylinepainter: 'lib/jquery.lazylinepainter-1.5.1.min', // v1.5.1 SVG line animation plugin - http://lazylinepainter.info
|
||||
blueImpGallery: 'lib/blueimp-gallery', // v2.21.3 Image Gallery - https://github.com/blueimp/Gallery
|
||||
blueImpGalleryHelper: 'lib/blueimp-helper', // helper function for Blue Imp Gallery
|
||||
blueImpGalleryBootstrap: 'lib/bootstrap-image-gallery', // v3.4.2 Bootstrap extension for Blue Imp Gallery - https://blueimp.github.io/Bootstrap-Image-Gallery
|
||||
bootstrapConfirmation: 'lib/bootstrap-confirmation', // v1.0.5 Bootstrap extension for inline confirm dialog - https://github.com/tavicu/bs-confirmation
|
||||
bootstrapToggle: 'lib/bootstrap-toggle.min', // v2.2.0 Bootstrap Toggle (Checkbox) - http://www.bootstraptoggle.com
|
||||
lazyload: 'lib/jquery.lazyload.min', // v1.9.5 LazyLoader images - http://www.appelsiini.net/projects/lazyload
|
||||
sortable: 'lib/sortable.min', // v1.6.0 Sortable - drag&drop reorder - https://github.com/rubaxa/Sortable
|
||||
jquery: 'lib/jquery-3.3.1.min', // v3.3.1 jQuery
|
||||
bootstrap: 'lib/bootstrap.min', // v3.3.0 Bootstrap js code - http://getbootstrap.com/javascript
|
||||
text: 'lib/requirejs/text', // v2.0.12 A RequireJS/AMD loader plugin for loading text resources.
|
||||
mustache: 'lib/mustache.min', // v1.0.0 Javascript template engine - http://mustache.github.io
|
||||
localForage: 'lib/localforage.min', // v1.4.2 localStorage library - https://mozilla.github.io/localForage
|
||||
velocity: 'lib/velocity.min', // v1.5.1 animation engine - http://julian.com/research/velocity
|
||||
velocityUI: 'lib/velocity.ui.min', // v5.2.0 plugin for velocity - http://julian.com/research/velocity/#uiPack
|
||||
slidebars: 'lib/slidebars', // v0.10 Slidebars - side menu plugin http://plugins.adchsm.me/slidebars
|
||||
jsPlumb: 'lib/dom.jsPlumb-1.7.6', // v1.7.6 jsPlumb (Vanilla)- main map draw plugin https://jsplumbtoolkit.com
|
||||
farahey: 'lib/farahey-0.5', // v0.5 jsPlumb "magnetizing" extension - https://github.com/jsplumb/farahey
|
||||
customScrollbar: 'lib/jquery.mCustomScrollbar.min', // v3.1.5 Custom scroll bars - http://manos.malihu.gr
|
||||
mousewheel: 'lib/jquery.mousewheel.min', // v3.1.13 Mousewheel - https://github.com/jquery/jquery-mousewheel
|
||||
xEditable: 'lib/bootstrap-editable.min', // v1.5.1 X-editable - in placed editing
|
||||
morris: 'lib/morris.min', // v0.5.1 Morris.js - graphs and charts
|
||||
raphael: 'lib/raphael-min', // v2.1.2 Raphaël - required for morris (dependency)
|
||||
bootbox: 'lib/bootbox.min', // v4.4.0 Bootbox.js - custom dialogs - http://bootboxjs.com
|
||||
easyPieChart: 'lib/jquery.easypiechart.min', // v2.1.6 Easy Pie Chart - HTML 5 pie charts - http://rendro.github.io/easy-pie-chart
|
||||
peityInlineChart: 'lib/jquery.peity.min', // v3.2.1 Inline Chart - http://benpickles.github.io/peity/
|
||||
dragToSelect: 'lib/jquery.dragToSelect', // v1.1 Drag to Select - http://andreaslagerkvist.com/jquery/drag-to-select
|
||||
hoverIntent: 'lib/jquery.hoverIntent.min', // v1.9.0 Hover intention - http://cherne.net/brian/resources/jquery.hoverIntent.html
|
||||
fullScreen: 'lib/jquery.fullscreen.min', // v0.6.0 Full screen mode - https://github.com/private-face/jquery.fullscreen
|
||||
select2: 'lib/select2.min', // v4.0.3 Drop Down customization - https://select2.github.io
|
||||
validator: 'lib/validator.min', // v0.10.1 Validator for Bootstrap 3 - https://github.com/1000hz/bootstrap-validator
|
||||
lazylinepainter: 'lib/jquery.lazylinepainter-1.5.1.min', // v1.5.1 SVG line animation plugin - http://lazylinepainter.info
|
||||
blueImpGallery: 'lib/blueimp-gallery', // v2.21.3 Image Gallery - https://github.com/blueimp/Gallery
|
||||
blueImpGalleryHelper: 'lib/blueimp-helper', // helper function for Blue Imp Gallery
|
||||
blueImpGalleryBootstrap: 'lib/bootstrap-image-gallery', // v3.4.2 Bootstrap extension for Blue Imp Gallery - https://blueimp.github.io/Bootstrap-Image-Gallery
|
||||
bootstrapConfirmation: 'lib/bootstrap-confirmation', // v1.0.5 Bootstrap extension for inline confirm dialog - https://github.com/tavicu/bs-confirmation
|
||||
bootstrapToggle: 'lib/bootstrap-toggle.min', // v2.2.0 Bootstrap Toggle (Checkbox) - http://www.bootstraptoggle.com
|
||||
lazyload: 'lib/jquery.lazyload.min', // v1.9.5 LazyLoader images - http://www.appelsiini.net/projects/lazyload
|
||||
sortable: 'lib/sortable.min', // v1.6.0 Sortable - drag&drop reorder - https://github.com/rubaxa/Sortable
|
||||
|
||||
'summernote.loader': './app/summernote.loader', // v0.8.10 Summernote WYSIWYG editor -https://summernote.org
|
||||
'summernote': 'lib/summernote/summernote.min',
|
||||
|
||||
// header animation
|
||||
easePack: 'lib/EasePack.min',
|
||||
@@ -135,44 +138,47 @@ requirejs.config({
|
||||
}
|
||||
},
|
||||
pnotify: {
|
||||
deps : ['jquery']
|
||||
deps: ['jquery']
|
||||
},
|
||||
easyPieChart: {
|
||||
deps : ['jquery']
|
||||
deps: ['jquery']
|
||||
},
|
||||
peityInlineChart: {
|
||||
deps : ['jquery']
|
||||
deps: ['jquery']
|
||||
},
|
||||
dragToSelect: {
|
||||
deps : ['jquery']
|
||||
deps: ['jquery']
|
||||
},
|
||||
hoverIntent: {
|
||||
deps : ['jquery']
|
||||
deps: ['jquery']
|
||||
},
|
||||
fullScreen: {
|
||||
deps : ['jquery']
|
||||
deps: ['jquery']
|
||||
},
|
||||
select2: {
|
||||
deps : ['jquery', 'mousewheel'],
|
||||
deps: ['jquery', 'mousewheel'],
|
||||
exports: 'Select2'
|
||||
},
|
||||
validator: {
|
||||
deps : ['jquery', 'bootstrap']
|
||||
deps: ['jquery', 'bootstrap']
|
||||
},
|
||||
lazylinepainter: {
|
||||
deps : ['jquery', 'bootstrap']
|
||||
deps: ['jquery', 'bootstrap']
|
||||
},
|
||||
blueImpGallery: {
|
||||
deps : ['jquery']
|
||||
deps: ['jquery']
|
||||
},
|
||||
bootstrapConfirmation: {
|
||||
deps : ['bootstrap']
|
||||
deps: ['bootstrap']
|
||||
},
|
||||
bootstrapToggle: {
|
||||
deps : ['jquery']
|
||||
deps: ['jquery']
|
||||
},
|
||||
lazyload: {
|
||||
deps : ['jquery']
|
||||
deps: ['jquery']
|
||||
},
|
||||
summernote: {
|
||||
deps: ['jquery']
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -275,7 +275,8 @@ define([
|
||||
// exclude some HTML Tags from watcher
|
||||
if(
|
||||
e.target.tagName !== 'INPUT' &&
|
||||
e.target.tagName !== 'TEXTAREA'
|
||||
e.target.tagName !== 'TEXTAREA' &&
|
||||
!e.target.classList.contains('note-editable') // Summerstyle editor
|
||||
){
|
||||
let key = e.key.toUpperCase();
|
||||
map[key] = true;
|
||||
|
||||
@@ -54,11 +54,6 @@ define([
|
||||
connectionContextMenuId: 'pf-map-connection-contextmenu',
|
||||
systemContextMenuId: 'pf-map-system-contextmenu',
|
||||
|
||||
// dialogs
|
||||
systemDialogId: 'pf-system-dialog', // id for system dialog
|
||||
systemDialogSelectClass: 'pf-system-dialog-select', // class for system select Element
|
||||
systemDialogStatusSelectId: 'pf-system-dialog-status-select', // id for "status" select
|
||||
|
||||
// system security classes
|
||||
systemSec: 'pf-system-sec'
|
||||
};
|
||||
@@ -1325,228 +1320,6 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* save a new system and add it to the map
|
||||
* @param requestData
|
||||
* @param context
|
||||
*/
|
||||
let saveSystem = (requestData, context) => {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Init.path.saveSystem,
|
||||
data: requestData,
|
||||
dataType: 'json',
|
||||
context: context
|
||||
}).done(function(responseData){
|
||||
let newSystemData = responseData.systemData;
|
||||
|
||||
if( !$.isEmptyObject(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(this.onSuccess){
|
||||
this.onSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
// show errors
|
||||
if(
|
||||
responseData.error &&
|
||||
responseData.error.length > 0
|
||||
){
|
||||
for(let i = 0; i < responseData.error.length; i++){
|
||||
let error = responseData.error[i];
|
||||
Util.showNotify({title: error.field + ' error', text: 'System: ' + error.message, type: error.type});
|
||||
}
|
||||
}
|
||||
}).fail(function(jqXHR, status, error){
|
||||
let reason = status + ' ' + error;
|
||||
Util.showNotify({title: jqXHR.status + ': saveSystem', text: reason, type: 'warning'});
|
||||
$(document).setProgramStatus('problem');
|
||||
}).always(function(){
|
||||
if(this.onAlways){
|
||||
this.onAlways(this);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 = (map, options) => {
|
||||
let mapContainer = $(map.getContainer());
|
||||
|
||||
// format system status for form select -----------------------------------------------------------------------
|
||||
// "default" selection (id = 0) prevents status from being overwritten
|
||||
// -> e.g. keep status information if system was just inactive (active = 0)
|
||||
let statusData = [{id: 0, text: 'auto'}];
|
||||
|
||||
// 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,
|
||||
select2Class: Util.config.select2Class,
|
||||
selectClass: config.systemDialogSelectClass,
|
||||
statusSelectId: config.systemDialogStatusSelectId,
|
||||
statusData: statusData
|
||||
};
|
||||
|
||||
// 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,
|
||||
show: false,
|
||||
buttons: {
|
||||
close: {
|
||||
label: 'cancel',
|
||||
className: 'btn-default'
|
||||
},
|
||||
success: {
|
||||
label: '<i class="fas fa-fw fa-check"></i> save',
|
||||
className: 'btn-success',
|
||||
callback: function(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')
|
||||
}
|
||||
};
|
||||
|
||||
this.find('.modal-content').showLoadingAnimation();
|
||||
|
||||
saveSystem(requestData, {
|
||||
map: map,
|
||||
sourceSystem: sourceSystem,
|
||||
systemDialog: this,
|
||||
onSuccess: () => {
|
||||
bootbox.hideAll();
|
||||
},
|
||||
onAlways: (context) => {
|
||||
context.systemDialog.find('.modal-content').hideLoadingAnimation();
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
systemDialog.on('show.bs.modal', function(e){
|
||||
let modalContent = $('#' + config.systemDialogId);
|
||||
|
||||
// init "status" select2
|
||||
for(let [statusName, data] of Object.entries(Init.systemStatus)){
|
||||
statusData.push({id: data.id, text: data.label, class: data.class});
|
||||
}
|
||||
|
||||
modalContent.find('#' + config.systemDialogStatusSelectId).initStatusSelect({
|
||||
data: statusData,
|
||||
iconClass: 'fa-tag'
|
||||
});
|
||||
});
|
||||
|
||||
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: 'id',
|
||||
disabledOptions: mapSystemIds
|
||||
});
|
||||
});
|
||||
|
||||
// show dialog
|
||||
systemDialog.modal('show');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* make a system name/alias editable by x-editable
|
||||
* @param system
|
||||
@@ -2057,7 +1830,7 @@ define([
|
||||
switch(action){
|
||||
case 'add_system':
|
||||
// add a new system
|
||||
showNewSystemDialog(map, {sourceSystem: currentSystem} );
|
||||
System.showNewSystemDialog(map, {sourceSystem: currentSystem}, saveSystemCallback);
|
||||
|
||||
break;
|
||||
case 'lock_system':
|
||||
@@ -2166,6 +1939,20 @@ define([
|
||||
Util.singleDoubleClick(system, single, double);
|
||||
};
|
||||
|
||||
/**
|
||||
* callback after system save
|
||||
* @param map
|
||||
* @param newSystemData
|
||||
* @param sourceSystem
|
||||
*/
|
||||
let saveSystemCallback = (map, newSystemData, sourceSystem) => {
|
||||
// draw new system to map
|
||||
drawSystem(map, newSystemData, sourceSystem);
|
||||
|
||||
// re/arrange systems (prevent overlapping)
|
||||
MagnetizerWrapper.setElements(map);
|
||||
};
|
||||
|
||||
/**
|
||||
* mark a dom element (map, system, connection) as changed
|
||||
*/
|
||||
@@ -2480,7 +2267,7 @@ define([
|
||||
position.y = dimensions[0].top;
|
||||
}
|
||||
|
||||
showNewSystemDialog(currentMap, {position: position});
|
||||
System.showNewSystemDialog(currentMap, {position: position}, saveSystemCallback);
|
||||
break;
|
||||
case 'select_all':
|
||||
currentMapElement.selectAllSystems();
|
||||
@@ -3022,7 +2809,7 @@ define([
|
||||
let interval = mapElement.getMapOverlayInterval();
|
||||
|
||||
if(
|
||||
! interval ||
|
||||
!interval ||
|
||||
options.forceData === true
|
||||
){
|
||||
|
||||
@@ -3280,7 +3067,7 @@ define([
|
||||
return {
|
||||
getMapInstance: getMapInstance,
|
||||
loadMap: loadMap,
|
||||
showNewSystemDialog: showNewSystemDialog
|
||||
saveSystemCallback: saveSystemCallback
|
||||
};
|
||||
|
||||
});
|
||||
@@ -5,7 +5,7 @@ define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util'
|
||||
], function($, Init, Util){
|
||||
], ($, Init, Util) => {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,8 +29,21 @@ define([
|
||||
systemTooltipInnerIdPrefix: 'pf-system-tooltip-inner-', // id prefix for system tooltip content
|
||||
systemTooltipInnerClass: 'pf-system-tooltip-inner', // class for system tooltip content
|
||||
|
||||
dialogRallyId: 'pf-rally-dialog', // id for "Rally point" dialog
|
||||
// dialogs
|
||||
dialogSystemId: 'pf-system-dialog', // id for system dialog
|
||||
dialogSystemSelectClass: 'pf-system-dialog-select', // class for system select element
|
||||
dialogSystemStatusSelectId: 'pf-system-dialog-status-select', // id for "status" select
|
||||
dialogSystemLockId: 'pf-system-dialog-lock', // id for "locked" checkbox
|
||||
dialogSystemRallyId: 'pf-system-dialog-rally', // id for "rally" checkbox
|
||||
|
||||
dialogSystemSectionInfoId: 'pf-system-dialog-section-info', // id for "info" section element
|
||||
dialogSystemSectionInfoStatusId: 'pf-system-dialog-section-info-status', // id for "status" message in "info" element
|
||||
dialogSystemAliasId: 'pf-system-dialog-alias', // id for "alias" static element
|
||||
dialogSystemDescriptionId: 'pf-system-dialog-description', // id for "description" static element
|
||||
dialogSystemCreatedId: 'pf-system-dialog-created', // id for "created" static element
|
||||
dialogSystemUpdatedId: 'pf-system-dialog-updated', // id for "updated" static element
|
||||
|
||||
dialogRallyId: 'pf-rally-dialog', // id for "Rally point" dialog
|
||||
dialogRallyPokeDesktopId: 'pf-rally-dialog-poke-desktop', // id for "desktop" poke checkbox
|
||||
dialogRallyPokeSlackId: 'pf-rally-dialog-poke-slack', // id for "Slack" poke checkbox
|
||||
dialogRallyPokeDiscordId: 'pf-rally-dialog-poke-discord', // id for "Discord" poke checkbox
|
||||
@@ -43,6 +56,316 @@ define([
|
||||
'- DPS and Logistic ships needed'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* save a new system and add it to the map
|
||||
* @param requestData
|
||||
* @param context
|
||||
* @param callback
|
||||
*/
|
||||
let saveSystem = (requestData, context, callback) => {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Init.path.saveSystem,
|
||||
data: requestData,
|
||||
dataType: 'json',
|
||||
context: context
|
||||
}).done(function(responseData){
|
||||
let newSystemData = responseData.systemData;
|
||||
|
||||
if( !$.isEmptyObject(newSystemData) ){
|
||||
Util.showNotify({title: 'New system', text: newSystemData.name, type: 'success'});
|
||||
|
||||
callback(newSystemData);
|
||||
}
|
||||
|
||||
if(
|
||||
responseData.error &&
|
||||
responseData.error.length > 0
|
||||
){
|
||||
for(let i = 0; i < responseData.error.length; i++){
|
||||
let error = responseData.error[i];
|
||||
Util.showNotify({title: error.field + ' error', text: 'System: ' + error.message, type: error.type});
|
||||
}
|
||||
}
|
||||
}).fail(function(jqXHR, status, error){
|
||||
let reason = status + ' ' + error;
|
||||
Util.showNotify({title: jqXHR.status + ': saveSystem', text: reason, type: 'warning'});
|
||||
$(document).setProgramStatus('problem');
|
||||
}).always(function(){
|
||||
this.systemDialog.find('.modal-content').hideLoadingAnimation();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param callback
|
||||
*/
|
||||
let showNewSystemDialog = (map, options, callback) => {
|
||||
let mapContainer = $(map.getContainer());
|
||||
let mapId = mapContainer.data('id');
|
||||
|
||||
/**
|
||||
* update new system dialog with some "additional" data
|
||||
* -> if system was mapped before
|
||||
* @param dialogElement
|
||||
* @param systemData
|
||||
*/
|
||||
let updateDialog = (dialogElement, systemData = null) => {
|
||||
let labelEmpty = '<span class="editable-empty">empty</span>';
|
||||
let labelUnknown = '<span class="editable-empty">unknown</span>';
|
||||
let labelExist = '<span class="txt-color txt-color-success">loaded</span>';
|
||||
|
||||
let showInfoHeadline = 'fadeOut';
|
||||
let showInfoSection = 'hide';
|
||||
let info = labelEmpty;
|
||||
|
||||
let statusId = false; // -> no value change
|
||||
let alias = labelEmpty;
|
||||
let description = labelEmpty;
|
||||
let createdTime = labelUnknown;
|
||||
let updatedTime = labelUnknown;
|
||||
|
||||
if(systemData){
|
||||
// system data found for selected system
|
||||
showInfoHeadline = 'fadeIn';
|
||||
showInfoSection = 'show';
|
||||
info = labelExist;
|
||||
statusId = parseInt(Util.getObjVal(systemData, 'status.id')) || statusId;
|
||||
alias = systemData.alias.length ? Util.htmlEncode(systemData.alias) : alias;
|
||||
description = systemData.description.length ? systemData.description : description;
|
||||
|
||||
let dateCreated = new Date(systemData.created.created * 1000);
|
||||
let dateUpdated = new Date(systemData.updated.updated * 1000);
|
||||
let dateCreatedUTC = Util.convertDateToUTC(dateCreated);
|
||||
let dateUpdatedUTC = Util.convertDateToUTC(dateUpdated);
|
||||
|
||||
createdTime = Util.convertDateToString(dateCreatedUTC);
|
||||
updatedTime = Util.convertDateToString(dateUpdatedUTC);
|
||||
|
||||
}else if(systemData === null){
|
||||
// no system found for selected system
|
||||
showInfoHeadline = 'fadeIn';
|
||||
}
|
||||
|
||||
// update new system dialog with new default data
|
||||
dialogElement.find('#' + config.dialogSystemSectionInfoStatusId).html(info);
|
||||
if(statusId !== false){
|
||||
dialogElement.find('#' + config.dialogSystemStatusSelectId).val(statusId).trigger('change');
|
||||
}
|
||||
dialogElement.find('#' + config.dialogSystemAliasId).html(alias);
|
||||
dialogElement.find('#' + config.dialogSystemDescriptionId).html(description);
|
||||
dialogElement.find('#' + config.dialogSystemCreatedId).html('<i class="fas fa-fw fa-plus"></i> ' + createdTime);
|
||||
dialogElement.find('#' + config.dialogSystemUpdatedId).html('<i class="fas fa-fw fa-pen"></i> ' + updatedTime);
|
||||
dialogElement.find('[data-target="#' + config.dialogSystemSectionInfoId + '"]').velocity('stop').velocity(showInfoHeadline, {duration: 120});
|
||||
dialogElement.find('[data-type="spinner"]').removeClass('in');
|
||||
dialogElement.find('#' + config.dialogSystemSectionInfoId).collapse(showInfoSection);
|
||||
};
|
||||
|
||||
/**
|
||||
* request system data from server for persistent data -> update dialog
|
||||
* @param dialogElement
|
||||
* @param mapId
|
||||
* @param systemId
|
||||
*/
|
||||
let requestSystemData = (dialogElement, mapId, systemId) => {
|
||||
// show loading animation
|
||||
dialogElement.find('[data-type="spinner"]').addClass('in');
|
||||
|
||||
MapUtil.requestSystemData({
|
||||
mapId: mapId,
|
||||
systemId: systemId,
|
||||
isCcpId: 1
|
||||
}, {
|
||||
dialogElement: dialogElement
|
||||
}).then(payload => updateDialog(payload.context.dialogElement, payload.data))
|
||||
.catch(payload => updateDialog(payload.context.dialogElement));
|
||||
};
|
||||
|
||||
// format system status for form select -----------------------------------------------------------------------
|
||||
// "default" selection (id = 0) prevents status from being overwritten
|
||||
// -> e.g. keep status information if system was just inactive (active = 0)
|
||||
let statusData = [{id: 0, text: 'auto'}];
|
||||
|
||||
// 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 = mapSystems.map(systemData => systemData.systemId);
|
||||
|
||||
// dialog data ------------------------------------------------------------------------------------------------
|
||||
let data = {
|
||||
id: config.dialogSystemId,
|
||||
select2Class: Util.config.select2Class,
|
||||
systemSelectClass: config.dialogSystemSelectClass,
|
||||
statusSelectId: config.dialogSystemStatusSelectId,
|
||||
lockId: config.dialogSystemLockId,
|
||||
rallyId: config.dialogSystemRallyId,
|
||||
|
||||
sectionInfoId: config.dialogSystemSectionInfoId,
|
||||
sectionInfoStatusId: config.dialogSystemSectionInfoStatusId,
|
||||
aliasId: config.dialogSystemAliasId,
|
||||
descriptionId: config.dialogSystemDescriptionId,
|
||||
createdId: config.dialogSystemCreatedId,
|
||||
updatedId: config.dialogSystemUpdatedId,
|
||||
statusData: statusData
|
||||
};
|
||||
|
||||
// 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'], (template, Mustache) => {
|
||||
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
let systemDialog = bootbox.dialog({
|
||||
title: 'Add new system',
|
||||
message: content,
|
||||
show: false,
|
||||
buttons: {
|
||||
close: {
|
||||
label: 'cancel',
|
||||
className: 'btn-default'
|
||||
},
|
||||
success: {
|
||||
label: '<i class="fas fa-fw fa-check"></i> save',
|
||||
className: 'btn-success',
|
||||
callback: function(e){
|
||||
// get form Values
|
||||
let form = this.find('form');
|
||||
|
||||
let systemDialogData = $(form).getFormValues();
|
||||
|
||||
// validate form
|
||||
form.validator('validate');
|
||||
|
||||
// check whether the form is valid
|
||||
let formValid = form.isValidForm();
|
||||
|
||||
// don't close dialog on invalid data
|
||||
if(formValid === false) return false;
|
||||
|
||||
// calculate new system position ----------------------------------------------------------
|
||||
let newPosition = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
|
||||
// add new position
|
||||
let sourceSystem = null;
|
||||
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: mapId
|
||||
}
|
||||
};
|
||||
|
||||
this.find('.modal-content').showLoadingAnimation();
|
||||
|
||||
saveSystem(requestData, {
|
||||
systemDialog: this
|
||||
}, (newSystemData) => {
|
||||
// success callback
|
||||
callback(map, newSystemData, sourceSystem);
|
||||
|
||||
bootbox.hideAll();
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
systemDialog.on('show.bs.modal', function(e){
|
||||
let dialogElement = $(this);
|
||||
|
||||
// init "status" select2 ------------------------------------------------------------------------------
|
||||
for(let [statusName, data] of Object.entries(Init.systemStatus)){
|
||||
statusData.push({id: data.id, text: data.label, class: data.class});
|
||||
}
|
||||
|
||||
dialogElement.find('#' + config.dialogSystemStatusSelectId).initStatusSelect({
|
||||
data: statusData,
|
||||
iconClass: 'fa-tag'
|
||||
});
|
||||
|
||||
// initial dialog update with persistent system data --------------------------------------------------
|
||||
// -> only if system is preselected (e.g. current active system)
|
||||
let systemId = parseInt(dialogElement.find('.' + config.dialogSystemSelectClass).val()) || 0;
|
||||
if(systemId){
|
||||
requestSystemData(dialogElement, mapId, systemId);
|
||||
}
|
||||
});
|
||||
|
||||
systemDialog.on('shown.bs.modal', function(e){
|
||||
let dialogElement = $(this);
|
||||
|
||||
// no system selected
|
||||
updateDialog(dialogElement, false);
|
||||
|
||||
dialogElement.initTooltips();
|
||||
|
||||
// init system select live search - some delay until modal transition has finished
|
||||
let selectElement = dialogElement.find('.' + config.dialogSystemSelectClass);
|
||||
selectElement.delay(240).initSystemSelect({
|
||||
key: 'id',
|
||||
disabledOptions: mapSystemIds,
|
||||
onChange: systemId => {
|
||||
// on system select -> update dialog with persistent system data
|
||||
if(systemId){
|
||||
requestSystemData(dialogElement, mapId, systemId);
|
||||
}else{
|
||||
// no system selected
|
||||
updateDialog(dialogElement, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// show dialog
|
||||
systemDialog.modal('show');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* show "set rally point" dialog for system
|
||||
* @param system
|
||||
@@ -535,9 +858,9 @@ define([
|
||||
};
|
||||
|
||||
return {
|
||||
showNewSystemDialog: showNewSystemDialog,
|
||||
deleteSystems: deleteSystems,
|
||||
removeSystems: removeSystems,
|
||||
calculateNewSystemPosition: calculateNewSystemPosition,
|
||||
getHeadInfoElement: getHeadInfoElement
|
||||
};
|
||||
});
|
||||
@@ -1314,10 +1314,11 @@ define([
|
||||
|
||||
// dynamic require Map module -> otherwise there is a require(), loop
|
||||
let Map = require('app/map/map');
|
||||
let System = require('app/map/system');
|
||||
let map = Map.getMapInstance( mapElement.data('id'));
|
||||
|
||||
mapWrapper.watchKey('mapSystemAdd', (mapWrapper) => {
|
||||
Map.showNewSystemDialog(map, {position: {x: 0, y: 0}});
|
||||
System.showNewSystemDialog(map, {position: {x: 0, y: 0}}, Map.saveSystemCallback);
|
||||
},{focus: true});
|
||||
|
||||
mapWrapper.watchKey('mapSystemsSelect', (mapWrapper) => {
|
||||
@@ -1617,6 +1618,10 @@ define([
|
||||
let requestSystemData = (requestData, context) => {
|
||||
|
||||
let requestSystemDataExecutor = (resolve, reject) => {
|
||||
let payload = {
|
||||
action: 'systemData'
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url: Init.path.getSystemData,
|
||||
type: 'POST',
|
||||
@@ -1624,17 +1629,20 @@ define([
|
||||
data: requestData,
|
||||
context: context
|
||||
}).done(function(data){
|
||||
payload.context = this;
|
||||
|
||||
if(data.system){
|
||||
resolve({
|
||||
action: 'systemData',
|
||||
context: this,
|
||||
data: data.system
|
||||
});
|
||||
// system data found
|
||||
payload.data = data.system;
|
||||
resolve(payload);
|
||||
}else{
|
||||
console.warn('Missing systemData in response!', requestData);
|
||||
// no system data returned/found
|
||||
reject(payload);
|
||||
}
|
||||
}).fail(function(jqXHR, status, error){
|
||||
console.warn('Fail request systemData!', requestData);
|
||||
payload.context = this;
|
||||
reject(payload);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -136,7 +136,6 @@ define([
|
||||
Init.structureStatus = response.structureStatus;
|
||||
Init.universeCategories = response.universeCategories;
|
||||
Init.routeSearch = response.routeSearch;
|
||||
Init.programMode = response.programMode;
|
||||
|
||||
resolve({
|
||||
action: 'initData',
|
||||
|
||||
187
js/app/summernote.loader.js
Normal file
187
js/app/summernote.loader.js
Normal file
@@ -0,0 +1,187 @@
|
||||
define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'summernote'
|
||||
], ($, Init) => {
|
||||
'use strict';
|
||||
|
||||
// all Summernote stuff is available...
|
||||
let initDefaultSummernoteConfig = () => {
|
||||
// "length" hint plugin ---------------------------------------------------------------------------------------
|
||||
$.extend($.summernote.plugins, {
|
||||
/**
|
||||
* @param {Object} context - context object has status of editor.
|
||||
*/
|
||||
lengthField: function (context){
|
||||
let self = this;
|
||||
let ui = $.summernote.ui;
|
||||
|
||||
// add counter
|
||||
context.memo('button.lengthField', () => {
|
||||
return $('<kbd>', {
|
||||
class: ['text-right', 'txt-color'].join(' ')
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* update counter element with left chars
|
||||
* @param contents
|
||||
*/
|
||||
let updateCounter = (contents) => {
|
||||
let maxTextLength = context.options.maxTextLength;
|
||||
let textLength = contents.length;
|
||||
let counter = context.layoutInfo.toolbar.find('kbd');
|
||||
let counterLeft = maxTextLength - textLength;
|
||||
|
||||
counter.text(counterLeft).data('charCount', counterLeft);
|
||||
counter.toggleClass('txt-color-red', maxTextLength <= textLength);
|
||||
|
||||
// disable "save" button
|
||||
let saveBtn = context.layoutInfo.toolbar.find('.btn-save');
|
||||
saveBtn.prop('disabled', maxTextLength < textLength);
|
||||
};
|
||||
|
||||
// events
|
||||
this.events = {
|
||||
'summernote.init': function (we, e) {
|
||||
updateCounter(context.$note.summernote('code'));
|
||||
},
|
||||
'summernote.change': function(we, contents){
|
||||
updateCounter(contents);
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// "discard" button plugin ------------------------------------------------------------------------------------
|
||||
$.extend($.summernote.plugins, {
|
||||
/**
|
||||
* @param {Object} context - context object has status of editor.
|
||||
*/
|
||||
discardBtn: function (context){
|
||||
let self = this;
|
||||
let ui = $.summernote.ui;
|
||||
|
||||
// add button
|
||||
context.memo('button.discardBtn', () => {
|
||||
let button = ui.button({
|
||||
contents: '<i class="fas fa-fw fa-ban"/>',
|
||||
container: 'body',
|
||||
click: function(){
|
||||
// show confirmation dialog
|
||||
$(this).confirmation('show');
|
||||
}
|
||||
});
|
||||
let $button = button.render();
|
||||
|
||||
// show "discard" changes confirmation
|
||||
let confirmationSettings = {
|
||||
container: 'body',
|
||||
placement: 'top',
|
||||
btnCancelClass: 'btn btn-sm btn-default',
|
||||
btnCancelLabel: 'cancel',
|
||||
title: 'discard changes',
|
||||
btnOkClass: 'btn btn-sm btn-warning',
|
||||
btnOkLabel: 'discard',
|
||||
btnOkIcon: 'fas fa-fw fa-ban',
|
||||
onConfirm: (e, target) => {
|
||||
// discard all changes
|
||||
context.$note.summernote('reset');
|
||||
context.$note.summernote('destroy');
|
||||
}
|
||||
};
|
||||
$button.confirmation(confirmationSettings);
|
||||
|
||||
return $button;
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* init new Summernote editor
|
||||
* @param element
|
||||
* @param options
|
||||
*/
|
||||
let initSummernote = (element, options) => {
|
||||
|
||||
let defaultOptions = {
|
||||
dialogsInBody: true,
|
||||
dialogsFade: true,
|
||||
//textareaAutoSync: false,
|
||||
//hintDirection: 'right',
|
||||
//tooltip: 'right',
|
||||
//container: 'body',
|
||||
styleTags: ['p', 'h2', 'h3', 'blockquote'],
|
||||
linkTargetBlank: true,
|
||||
tableClassName: 'table table-condensed table-bordered',
|
||||
insertTableMaxSize: {
|
||||
col: 5,
|
||||
row: 5
|
||||
},
|
||||
icons: {
|
||||
//'align': 'note-icon-align',
|
||||
'alignCenter': 'fas fa-align-center',
|
||||
'alignJustify': 'fas fa-align-justify',
|
||||
'alignLeft': 'fas fa-align-left',
|
||||
'alignRight': 'fas fa-align-right',
|
||||
//'rowBelow': 'note-icon-row-below',
|
||||
//'colBefore': 'note-icon-col-before',
|
||||
//'colAfter': 'note-icon-col-after',
|
||||
//'rowAbove': 'note-icon-row-above',
|
||||
//'rowRemove': 'note-icon-row-remove',
|
||||
//'colRemove': 'note-icon-col-remove',
|
||||
'indent': 'fas fa-indent',
|
||||
'outdent': 'fas fa-outdent',
|
||||
'arrowsAlt': 'fas fa-expand-arrows-alt',
|
||||
'bold': 'fas fa-bold',
|
||||
'caret': 'fas fa-caret-down',
|
||||
'circle': 'fas fa-circle',
|
||||
'close': 'fas fa-time',
|
||||
'code': 'fas fa-code',
|
||||
'eraser': 'fas fa-eraser',
|
||||
'font': 'fas fa-font',
|
||||
//'frame': 'note-icon-frame',
|
||||
'italic': 'fas fa-italic',
|
||||
'link': 'fas fa-link',
|
||||
'unlink': 'fas fa-unlink',
|
||||
'magic': 'fas fa-magic',
|
||||
'menuCheck': 'fas fa-check',
|
||||
'minus': 'fas fa-minus',
|
||||
'orderedlist': 'fas fa-list-ol',
|
||||
'pencil': 'fa-pen',
|
||||
'picture': 'fas fa-image',
|
||||
'question': 'fas fa-question',
|
||||
'redo': 'fas fa-redo',
|
||||
'square': 'fas fa-square',
|
||||
'strikethrough': 'fas fa-strikethrough',
|
||||
'subscript': 'fas fa-subscript',
|
||||
'superscript': 'fas fa-superscript',
|
||||
'table': 'fas fa-table',
|
||||
'textHeight': 'fas fa-text-height',
|
||||
'trash': 'fas fa-trash',
|
||||
'underline': 'fas fa-underline',
|
||||
'undo': 'fas fa-undo',
|
||||
'unorderedlist': 'fas fa-list-ul',
|
||||
'video': 'fab fa-youtube'
|
||||
},
|
||||
colors: [
|
||||
['#5cb85c', '#e28a0d', '#d9534f', '#e06fdf', '#9fa8da', '#e2ce48', '#428bca']
|
||||
],
|
||||
colorsName: [
|
||||
['Green', 'Orange', 'Red', 'Pink', 'Indigo', 'Yellow', 'Blue']
|
||||
],
|
||||
};
|
||||
|
||||
options = $.extend({}, defaultOptions, options);
|
||||
|
||||
element.summernote(options);
|
||||
};
|
||||
|
||||
initDefaultSummernoteConfig();
|
||||
|
||||
return {
|
||||
initSummernote: initSummernote
|
||||
};
|
||||
});
|
||||
@@ -1254,7 +1254,7 @@ define([
|
||||
*/
|
||||
$.fn.showMapInfoDialog = function(options){
|
||||
let activeMap = Util.getMapModule().getActiveMap();
|
||||
let mapData = activeMap.getMapDataFromClient({forceData: true});
|
||||
let mapData = activeMap ? activeMap.getMapDataFromClient({forceData: true}) : false;
|
||||
|
||||
if(mapData !== false){
|
||||
// "log" tab -> get "Origin", not all config options are set in mapData
|
||||
@@ -1351,6 +1351,13 @@ define([
|
||||
});
|
||||
|
||||
});
|
||||
}else{
|
||||
// no active map found (e.g. not loaded yet, or no map exists)
|
||||
Util.showNotify({
|
||||
title: 'Map data not found',
|
||||
text: 'No map initialized at this point',
|
||||
type: 'warning'}
|
||||
);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -333,11 +333,14 @@ define([
|
||||
dropdownParent: selectElement.parents('.modal-body'),
|
||||
minimumInputLength: 3,
|
||||
templateResult: formatResultData,
|
||||
placeholder: 'System name',
|
||||
placeholder: 'Name or ID',
|
||||
allowClear: true,
|
||||
maximumSelectionLength: options.maxSelectionLength
|
||||
}).on('change', function(e){
|
||||
// select changed
|
||||
if(options.onChange){
|
||||
options.onChange(parseInt($(this).val()) || 0);
|
||||
}
|
||||
}).on('select2:open', function(){
|
||||
// clear selected system (e.g. default system)
|
||||
// => improves usability (not necessary). There is a small "x" if field can be cleared manually
|
||||
|
||||
@@ -30,6 +30,9 @@ define([
|
||||
connectionInfoPanelClass: 'pf-connection-info-panel', // class for connection info panels
|
||||
connectionInfoPanelId: 'pf-connection-info-panel-', // id prefix for connection info panels
|
||||
|
||||
dynamicAreaClass: 'pf-dynamic-area', // class for "dynamic" areas
|
||||
controlAreaClass: 'pf-module-control-area', // class for "control" areas
|
||||
|
||||
// info table
|
||||
moduleTableClass: 'pf-module-table', // class for module tables
|
||||
connectionInfoTableLabelSourceClass: 'pf-connection-info-label-source', // class for source label
|
||||
@@ -107,7 +110,7 @@ define([
|
||||
*/
|
||||
let getInfoPanelControl = (mapId) => {
|
||||
let connectionElement = getConnectionElement(mapId, 0).append($('<div>', {
|
||||
class: 'pf-dynamic-area',
|
||||
class: [config.dynamicAreaClass, config.controlAreaClass].join(' '),
|
||||
html: '<i class="fas fa-fw fa-plus"></i> add connection <kbd>ctrl</kbd> + <kbd>click</kbd>'
|
||||
}));
|
||||
|
||||
@@ -125,7 +128,7 @@ define([
|
||||
let scopeLabel = MapUtil.getScopeInfoForConnection(connectionData.scope, 'label');
|
||||
|
||||
let element = $('<div>', {
|
||||
class: 'pf-dynamic-area'
|
||||
class: [config.dynamicAreaClass, config.controlAreaClass].join(' ')
|
||||
}).append(
|
||||
$('<table>', {
|
||||
class: ['table', 'table-condensed', 'pf-table-fixed', config.moduleTableClass].join(' ')
|
||||
|
||||
@@ -6,9 +6,8 @@ define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
'app/util',
|
||||
'app/render',
|
||||
'app/map/util'
|
||||
], ($, Init, Util, Render, MapUtil) => {
|
||||
], ($, Init, Util, MapUtil) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
@@ -38,50 +37,55 @@ define([
|
||||
systemInfoWormholeClass: 'pf-system-info-wormhole-', // class prefix for static wormhole element
|
||||
|
||||
// description field
|
||||
descriptionArea: 'pf-system-info-description-area', // class for "description" area
|
||||
descriptionAreaClass: '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)
|
||||
fontTriglivianClass: 'pf-triglivian', // class for "Triglivian" names (e.g. Abyssal systems)
|
||||
|
||||
// Summernote
|
||||
defaultBgColor: '#e2ce48'
|
||||
};
|
||||
|
||||
// disable Module update temporary (in case e.g. textarea is currently active)
|
||||
let disableModuleUpdate = false;
|
||||
|
||||
// animation speed values
|
||||
let animationSpeedToolbarAction = 200;
|
||||
|
||||
// max character length for system description
|
||||
let maxDescriptionLength = 512;
|
||||
let maxDescriptionLength = 9000;
|
||||
|
||||
/**
|
||||
* shows the tool action element by animation
|
||||
* @param toolsActionElement
|
||||
* save system (description)
|
||||
* @param requestData
|
||||
* @param context
|
||||
* @param callback
|
||||
*/
|
||||
let showToolsActionElement = (toolsActionElement) => {
|
||||
toolsActionElement.velocity('stop').velocity({
|
||||
opacity: 1,
|
||||
height: '100%'
|
||||
},{
|
||||
duration: animationSpeedToolbarAction,
|
||||
display: 'block',
|
||||
visibility: 'visible'
|
||||
});
|
||||
};
|
||||
let saveSystem = (requestData, context, callback) => {
|
||||
context.descriptionArea.showLoadingAnimation();
|
||||
|
||||
/**
|
||||
* hides the tool action element by animation
|
||||
* @param toolsActionElement
|
||||
*/
|
||||
let hideToolsActionElement = (toolsActionElement) => {
|
||||
toolsActionElement.velocity('stop').velocity('reverse', {
|
||||
display: 'none',
|
||||
visibility: 'hidden'
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Init.path.saveSystem,
|
||||
data: requestData,
|
||||
dataType: 'json',
|
||||
context: context
|
||||
}).done(function(responseData){
|
||||
let newSystemData = responseData.systemData;
|
||||
|
||||
if( !$.isEmptyObject(newSystemData) ){
|
||||
callback(newSystemData);
|
||||
}
|
||||
|
||||
if(
|
||||
responseData.error &&
|
||||
responseData.error.length > 0
|
||||
){
|
||||
for(let error of responseData.error){
|
||||
Util.showNotify({title: error.field + ' error', text: 'System: ' + error.message, type: error.type});
|
||||
}
|
||||
}
|
||||
}).fail(function(jqXHR, status, error){
|
||||
let reason = status + ' ' + error;
|
||||
Util.showNotify({title: jqXHR.status + ': saveSystem', text: reason, type: 'warning'});
|
||||
}).always(function(){
|
||||
this.descriptionArea.hideLoadingAnimation();
|
||||
});
|
||||
};
|
||||
|
||||
@@ -93,8 +97,24 @@ define([
|
||||
*/
|
||||
let updateModule = (moduleElement, systemData) => {
|
||||
let systemId = moduleElement.data('id');
|
||||
let updated = moduleElement.data('updated');
|
||||
|
||||
if(
|
||||
systemId === systemData.id &&
|
||||
updated !== systemData.updated.updated
|
||||
){
|
||||
let setUpdated = true;
|
||||
|
||||
// created/updated tooltip --------------------------------------------------------------------------------
|
||||
let nameRowElement = moduleElement.find('.' + config.systemInfoNameClass);
|
||||
|
||||
let tooltipData = {
|
||||
created: systemData.created,
|
||||
updated: systemData.updated
|
||||
};
|
||||
|
||||
nameRowElement.addCharacterInfoTooltip( tooltipData );
|
||||
|
||||
if(systemId === systemData.id){
|
||||
// update system status -----------------------------------------------------------------------------------
|
||||
let systemStatusLabelElement = moduleElement.find('.' + config.systemInfoStatusLabelClass);
|
||||
let systemStatusId = parseInt( systemStatusLabelElement.attr( config.systemInfoStatusAttributeName ) );
|
||||
@@ -112,45 +132,33 @@ define([
|
||||
|
||||
// update description textarea ----------------------------------------------------------------------------
|
||||
let descriptionTextareaElement = moduleElement.find('.' + config.descriptionTextareaElementClass);
|
||||
let description = descriptionTextareaElement.editable('getValue', true);
|
||||
if(descriptionTextareaElement.length){
|
||||
let description = descriptionTextareaElement.html();
|
||||
if(description !== systemData.description){
|
||||
// description has changed
|
||||
if(typeof descriptionTextareaElement.data().summernote === 'object'){
|
||||
// "Summernote" editor is currently open
|
||||
setUpdated = false;
|
||||
}else{
|
||||
// not open
|
||||
let newDescription = systemData.description;
|
||||
if( !Util.isValidHtml(newDescription) ){
|
||||
// try to convert raw text into valid html
|
||||
newDescription = newDescription.replace(/(\r\n|\n|\r)/g, '<br>');
|
||||
newDescription = '<p>' + newDescription + '</p>';
|
||||
}
|
||||
|
||||
if(
|
||||
!disableModuleUpdate && // don´t update if field is active
|
||||
description !== systemData.description
|
||||
){
|
||||
// description changed
|
||||
let descriptionButton = moduleElement.find('.' + config.addDescriptionButtonClass);
|
||||
|
||||
// set new value
|
||||
descriptionTextareaElement.editable('setValue', systemData.description);
|
||||
|
||||
let actionElement = descriptionButton.siblings('.' + config.tableToolsActionClass);
|
||||
|
||||
if(systemData.description.length === 0){
|
||||
// show/activate description field
|
||||
// show button if value is empty
|
||||
descriptionButton.show();
|
||||
hideToolsActionElement(actionElement);
|
||||
}else{
|
||||
// hide/disable description field
|
||||
// hide tool button
|
||||
descriptionButton.hide();
|
||||
showToolsActionElement(actionElement);
|
||||
descriptionTextareaElement.html(newDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// created/updated tooltip --------------------------------------------------------------------------------
|
||||
let nameRowElement = moduleElement.find('.' + config.systemInfoNameClass);
|
||||
|
||||
let tooltipData = {
|
||||
created: systemData.created,
|
||||
updated: systemData.updated
|
||||
};
|
||||
|
||||
nameRowElement.addCharacterInfoTooltip( tooltipData );
|
||||
if(setUpdated){
|
||||
moduleElement.data('updated', systemData.updated.updated);
|
||||
}
|
||||
}
|
||||
|
||||
moduleElement.find('.' + config.descriptionArea).hideLoadingAnimation();
|
||||
moduleElement.find('.' + config.descriptionAreaClass).hideLoadingAnimation();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -181,188 +189,7 @@ define([
|
||||
let effectName = MapUtil.getEffectInfoForSystem(systemData.effect, 'name');
|
||||
let effectClass = MapUtil.getEffectInfoForSystem(systemData.effect, 'class');
|
||||
|
||||
// systemInfo template config
|
||||
let moduleConfig = {
|
||||
name: 'modules/system_info',
|
||||
position: moduleElement,
|
||||
link: 'append',
|
||||
functions: {
|
||||
after: function(conf){
|
||||
let tempModuleElement = conf.position;
|
||||
// lock "description" field until first update
|
||||
tempModuleElement.find('.' + config.descriptionArea).showLoadingAnimation();
|
||||
// "add description" button
|
||||
let descriptionButton = tempModuleElement.find('.' + config.addDescriptionButtonClass);
|
||||
// description textarea element
|
||||
let descriptionTextareaElement = tempModuleElement.find('.' + config.descriptionTextareaElementClass);
|
||||
|
||||
// init description textarea
|
||||
descriptionTextareaElement.editable({
|
||||
url: Init.path.saveSystem,
|
||||
dataType: 'json',
|
||||
pk: systemData.id,
|
||||
type: 'textarea',
|
||||
mode: 'inline',
|
||||
emptytext: '',
|
||||
onblur: 'cancel',
|
||||
showbuttons: true,
|
||||
value: '', // value is set by trigger function updateModule()
|
||||
rows: 5,
|
||||
name: 'description',
|
||||
inputclass: config.descriptionTextareaElementClass,
|
||||
tpl: '<textarea maxlength="' + maxDescriptionLength + '"></textarea>',
|
||||
params: function(params){
|
||||
params.mapData = {
|
||||
id: mapId
|
||||
};
|
||||
|
||||
params.systemData = {};
|
||||
params.systemData.id = params.pk;
|
||||
params.systemData[params.name] = params.value;
|
||||
|
||||
// clear unnecessary data
|
||||
delete params.pk;
|
||||
delete params.name;
|
||||
delete params.value;
|
||||
|
||||
return params;
|
||||
},
|
||||
validate: function(value){
|
||||
if(value.length > 0 && $.trim(value).length === 0){
|
||||
return {newValue: ''};
|
||||
}
|
||||
},
|
||||
success: function(response, newValue){
|
||||
Util.showNotify({title: 'System updated', text: 'Name: ' + response.name, type: 'success'});
|
||||
},
|
||||
error: function(jqXHR, newValue){
|
||||
let reason = '';
|
||||
let status = '';
|
||||
if(jqXHR.name){
|
||||
// save error new sig (mass save)
|
||||
reason = jqXHR.name;
|
||||
status = 'Error';
|
||||
}else{
|
||||
reason = jqXHR.responseJSON.text;
|
||||
status = jqXHR.status;
|
||||
}
|
||||
|
||||
Util.showNotify({title: status + ': save system information', text: reason, type: 'warning'});
|
||||
$(document).setProgramStatus('problem');
|
||||
return reason;
|
||||
}
|
||||
});
|
||||
|
||||
// on xEditable open ------------------------------------------------------------------------------
|
||||
descriptionTextareaElement.on('shown', function(e, editable){
|
||||
let textarea = editable.input.$input;
|
||||
|
||||
// disable module update until description field is open
|
||||
disableModuleUpdate = true;
|
||||
|
||||
// create character counter
|
||||
let charCounter = $('<kbd>', {
|
||||
class: [config.descriptionTextareaCharCounter, 'txt-color', 'text-right'].join(' ')
|
||||
});
|
||||
textarea.parent().next().append(charCounter);
|
||||
|
||||
// update character counter
|
||||
Util.updateCounter(textarea, charCounter, maxDescriptionLength);
|
||||
|
||||
textarea.on('keyup', function(){
|
||||
Util.updateCounter($(this), charCounter, maxDescriptionLength);
|
||||
});
|
||||
});
|
||||
|
||||
// on xEditable close -----------------------------------------------------------------------------
|
||||
descriptionTextareaElement.on('hidden', function(e){
|
||||
let value = $(this).editable('getValue', true);
|
||||
if(value.length === 0){
|
||||
// show button if value is empty
|
||||
hideToolsActionElement(descriptionButton.siblings('.' + config.tableToolsActionClass));
|
||||
descriptionButton.show();
|
||||
}
|
||||
|
||||
// enable module update
|
||||
disableModuleUpdate = false;
|
||||
});
|
||||
|
||||
// enable xEditable field on Button click ---------------------------------------------------------
|
||||
descriptionButton.on('click', function(e){
|
||||
e.stopPropagation();
|
||||
let descriptionButton = $(this);
|
||||
|
||||
// hide tool buttons
|
||||
descriptionButton.hide();
|
||||
|
||||
// show field *before* showing the element
|
||||
descriptionTextareaElement.editable('show');
|
||||
|
||||
showToolsActionElement(descriptionButton.siblings('.' + config.tableToolsActionClass));
|
||||
});
|
||||
|
||||
// init tooltips ----------------------------------------------------------------------------------
|
||||
let tooltipElements = tempModuleElement.find('[data-toggle="tooltip"]');
|
||||
tooltipElements.tooltip({
|
||||
container: 'body',
|
||||
placement: 'top'
|
||||
});
|
||||
|
||||
// init system effect popover ---------------------------------------------------------------------
|
||||
tempModuleElement.find('.' + config.systemInfoEffectClass).addSystemEffectTooltip(systemData.security, systemData.effect);
|
||||
|
||||
// init planets popover ---------------------------------------------------------------------------
|
||||
tempModuleElement.find('.' + config.systemInfoPlanetsClass).addSystemPlanetsTooltip(systemData.planets);
|
||||
|
||||
// init static wormhole information ---------------------------------------------------------------
|
||||
for(let staticData of staticsData){
|
||||
let staticRowElement = tempModuleElement.find('.' + config.systemInfoWormholeClass + staticData.name);
|
||||
staticRowElement.addWormholeInfoTooltip(staticData);
|
||||
}
|
||||
|
||||
// copy system deeplink URL -----------------------------------------------------------------------
|
||||
tempModuleElement.find('.' + config.urlLinkClass).on('click', function(){
|
||||
let mapUrl = $(this).attr('data-url');
|
||||
Util.copyToClipboard(mapUrl).then(payload => {
|
||||
if(payload.data){
|
||||
Util.showNotify({title: 'Copied to clipbaord', text: mapUrl, type: 'success'});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// constellation popover --------------------------------------------------------------------------
|
||||
tempModuleElement.find('a.popup-ajax').popover({
|
||||
html: true,
|
||||
trigger: 'hover',
|
||||
placement: 'top',
|
||||
delay: 200,
|
||||
container: 'body',
|
||||
content: function(){
|
||||
return details_in_popup(this);
|
||||
}
|
||||
});
|
||||
|
||||
function details_in_popup(popoverElement){
|
||||
popoverElement = $(popoverElement);
|
||||
let popover = popoverElement.data('bs.popover');
|
||||
|
||||
$.ajax({
|
||||
url: popoverElement.data('url'),
|
||||
success: function(data){
|
||||
let systemEffectTable = Util.getSystemsInfoTable( data.systemsData );
|
||||
popover.options.content = systemEffectTable;
|
||||
// reopen popover (new content size)
|
||||
popover.show();
|
||||
}
|
||||
});
|
||||
return 'Loading...';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let moduleData = {
|
||||
let data = {
|
||||
system: systemData,
|
||||
static: staticsData,
|
||||
moduleHeadlineIconClass: config.moduleHeadlineIconClass,
|
||||
@@ -385,9 +212,8 @@ define([
|
||||
trueSecClass: Util.getTrueSecClassForSystem( systemData.trueSec ),
|
||||
effectName: effectName,
|
||||
effectClass: effectClass,
|
||||
moduleToolbarClass: config.moduleElementToolbarClass,
|
||||
descriptionAreaClass: config.descriptionAreaClass,
|
||||
descriptionButtonClass: config.addDescriptionButtonClass,
|
||||
tableToolsActionClass: config.tableToolsActionClass,
|
||||
descriptionTextareaClass: config.descriptionTextareaElementClass,
|
||||
systemNameClass: () => {
|
||||
return (val, render) => {
|
||||
@@ -409,7 +235,189 @@ define([
|
||||
systemUrlLinkClass: config.urlLinkClass
|
||||
};
|
||||
|
||||
Render.showModule(moduleConfig, moduleData);
|
||||
requirejs(['text!templates/modules/system_info.html', 'mustache', 'summernote.loader'], (template, Mustache, Summernote) => {
|
||||
let content = Mustache.render(template, data);
|
||||
moduleElement.append(content);
|
||||
|
||||
let descriptionArea = moduleElement.find('.' + config.descriptionAreaClass);
|
||||
let descriptionButton = moduleElement.find('.' + config.addDescriptionButtonClass);
|
||||
let descriptionTextareaElement = moduleElement.find('.' + config.descriptionTextareaElementClass);
|
||||
|
||||
// lock "description" field until first update
|
||||
descriptionArea.showLoadingAnimation();
|
||||
|
||||
// WYSIWYG init on button click ---------------------------------------------------------------------------
|
||||
descriptionButton.on('click', function(e){
|
||||
e.stopPropagation();
|
||||
let descriptionButton = $(this);
|
||||
// hide edit button
|
||||
descriptionButton.hide();
|
||||
|
||||
// content has changed
|
||||
let descriptionChanged = false;
|
||||
|
||||
Summernote.initSummernote(descriptionTextareaElement, {
|
||||
height: 75, // set editor height
|
||||
minHeight: 75, // set minimum height of editor
|
||||
maxHeight: 500, // set maximum height of editor
|
||||
focus: true,
|
||||
placeholder: false,
|
||||
maxTextLength: maxDescriptionLength,
|
||||
disableDragAndDrop: true,
|
||||
shortcuts: false,
|
||||
toolbar: [
|
||||
['style', ['style']],
|
||||
['font', ['underline', 'strikethrough', 'clear']],
|
||||
['color', ['color']],
|
||||
['para', ['ul', 'ol', 'paragraph']],
|
||||
['table', ['table']],
|
||||
['insert', ['link', 'hr']],
|
||||
//['view', ['codeview', 'help']],
|
||||
['misc', ['undo', 'redo']],
|
||||
['lengthField'],
|
||||
['customBtn', ['discardBtn', 'saveBtn']]
|
||||
],
|
||||
buttons: {
|
||||
saveBtn: context => {
|
||||
let ui = $.summernote.ui;
|
||||
let button = ui.button({
|
||||
contents: '<i class="fas fa-fw fa-check"/>',
|
||||
container: 'body',
|
||||
className: ['btn-success', 'btn-save'],
|
||||
click: e => {
|
||||
context.layoutInfo.editable.removeClass('has-error');
|
||||
|
||||
// save changes
|
||||
if(descriptionChanged){
|
||||
let validDescription = true;
|
||||
let description = '';
|
||||
|
||||
if( context.$note.summernote('isEmpty') ){
|
||||
// ... isEmpty -> clear empty default tags as well
|
||||
context.$note.summernote('code', '');
|
||||
}else{
|
||||
description = context.$note.summernote('code');
|
||||
if( !Util.isValidHtml(description) ){
|
||||
// ... not valid HTML
|
||||
validDescription = false;
|
||||
context.layoutInfo.editable.addClass('has-error');
|
||||
Util.showNotify({title: 'Validation failed', text: 'HTML not valid', type: 'error'});
|
||||
}
|
||||
}
|
||||
|
||||
if(validDescription){
|
||||
// ... valid -> save()
|
||||
saveSystem({
|
||||
mapData: {
|
||||
id: mapId
|
||||
},
|
||||
systemData: {
|
||||
id: systemData.id,
|
||||
description: description
|
||||
}
|
||||
}, {
|
||||
descriptionArea: descriptionArea
|
||||
}, (systemData) => {
|
||||
// .. save callback
|
||||
context.$note.summernote('destroy');
|
||||
updateModule(moduleElement, systemData);
|
||||
});
|
||||
}
|
||||
}else{
|
||||
// ... no changes -> no save()
|
||||
context.$note.summernote('destroy');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return button.render();
|
||||
}
|
||||
},
|
||||
callbacks: {
|
||||
onInit: function(context){
|
||||
// make editable field a big larger
|
||||
context.editable.css('height', '150px');
|
||||
|
||||
// set default background color
|
||||
// -> could not figure out how to set by API as default color
|
||||
context.toolbar.find('.note-current-color-button').attr('data-backcolor', config.defaultBgColor)
|
||||
.find('.note-recent-color').css('background-color', config.defaultBgColor);
|
||||
},
|
||||
onChange: function(contents){
|
||||
descriptionChanged = true;
|
||||
},
|
||||
onPaste: function (e) {
|
||||
let bufferText = ((e.originalEvent || e).clipboardData || window.clipboardData).getData('Text');
|
||||
e.preventDefault();
|
||||
|
||||
// Firefox fix
|
||||
setTimeout(() => {
|
||||
document.execCommand('insertText', false, bufferText);
|
||||
}, 10);
|
||||
},
|
||||
onDestroy: function(context){
|
||||
descriptionButton.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// init system effect popover -----------------------------------------------------------------------------
|
||||
moduleElement.find('.' + config.systemInfoEffectClass).addSystemEffectTooltip(systemData.security, systemData.effect);
|
||||
|
||||
// init planets popover -----------------------------------------------------------------------------------
|
||||
moduleElement.find('.' + config.systemInfoPlanetsClass).addSystemPlanetsTooltip(systemData.planets);
|
||||
|
||||
// init static wormhole information -----------------------------------------------------------------------
|
||||
for(let staticData of staticsData){
|
||||
let staticRowElement = moduleElement.find('.' + config.systemInfoWormholeClass + staticData.name);
|
||||
staticRowElement.addWormholeInfoTooltip(staticData);
|
||||
}
|
||||
|
||||
// copy system deeplink URL -------------------------------------------------------------------------------
|
||||
moduleElement.find('.' + config.urlLinkClass).on('click', function(){
|
||||
let mapUrl = $(this).attr('data-url');
|
||||
Util.copyToClipboard(mapUrl).then(payload => {
|
||||
if(payload.data){
|
||||
Util.showNotify({title: 'Copied to clipbaord', text: mapUrl, type: 'success'});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// constellation popover ----------------------------------------------------------------------------------
|
||||
moduleElement.find('a.popup-ajax').popover({
|
||||
html: true,
|
||||
trigger: 'hover',
|
||||
placement: 'top',
|
||||
delay: 200,
|
||||
container: 'body',
|
||||
content: function(){
|
||||
return details_in_popup(this);
|
||||
}
|
||||
});
|
||||
|
||||
let details_in_popup = popoverElement => {
|
||||
popoverElement = $(popoverElement);
|
||||
let popover = popoverElement.data('bs.popover');
|
||||
|
||||
$.ajax({
|
||||
url: popoverElement.data('url'),
|
||||
success: function(data){
|
||||
popover.options.content = Util.getSystemsInfoTable(data.systemsData);
|
||||
// reopen popover (new content size)
|
||||
popover.show();
|
||||
}
|
||||
});
|
||||
return 'Loading...';
|
||||
};
|
||||
|
||||
// init tooltips ------------------------------------------------------------------------------------------
|
||||
let tooltipElements = moduleElement.find('[data-toggle="tooltip"]');
|
||||
tooltipElements.tooltip({
|
||||
container: 'body',
|
||||
placement: 'top'
|
||||
});
|
||||
});
|
||||
|
||||
return moduleElement;
|
||||
};
|
||||
@@ -418,10 +426,8 @@ define([
|
||||
* efore module destroy callback
|
||||
* @param moduleElement
|
||||
*/
|
||||
let beforeDestroy = (moduleElement) => {
|
||||
// remove xEditable description textarea
|
||||
let descriptionTextareaElement = moduleElement.find('.' + config.descriptionTextareaElementClass);
|
||||
descriptionTextareaElement.editable('destroy');
|
||||
let beforeDestroy = moduleElement => {
|
||||
moduleElement.find('.' + config.descriptionTextareaElementClass).summernote('destroy');
|
||||
|
||||
moduleElement.destroyPopover(true);
|
||||
};
|
||||
@@ -433,6 +439,3 @@ define([
|
||||
beforeDestroy: beforeDestroy
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ define([
|
||||
|
||||
// system killboard module
|
||||
moduleTypeClass: 'pf-system-killboard-module', // class for this module
|
||||
systemKillboardGraphKillsClass: 'pf-system-killboard-graph-kills', // class for system kill graph
|
||||
|
||||
// system killboard list
|
||||
systemKillboardListClass: 'pf-system-killboard-list', // class for a list with kill entries
|
||||
@@ -30,12 +29,18 @@ define([
|
||||
systemKillboardListImgShip: 'pf-system-killboard-img-ship', // class for all ship images
|
||||
systemKillboardListImgChar: 'pf-system-killboard-img-char', // class for all character logos
|
||||
systemKillboardListImgAlly: 'pf-system-killboard-img-ally', // class for all alliance logos
|
||||
systemKillboardListImgCorp: 'pf-system-killboard-img-corp' // class for all corp logos
|
||||
systemKillboardListImgCorp: 'pf-system-killboard-img-corp', // class for all corp logos
|
||||
|
||||
labelRecentKillsClass: 'pf-system-killboard-label-recent', // class for "recent kills" label
|
||||
dynamicAreaClass: 'pf-dynamic-area', // class for "dynamic" areas
|
||||
controlAreaClass: 'pf-module-control-area', // class for "control" areas
|
||||
|
||||
minCountKills: 5,
|
||||
chunkCountKills: 5,
|
||||
maxCountKills: 43
|
||||
};
|
||||
|
||||
let cache = {
|
||||
systemKillsGraphData: {} // data for system kills info graph
|
||||
};
|
||||
let cache = {};
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -43,81 +48,143 @@ define([
|
||||
* @param options
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
let getLabel = (text, options) => {
|
||||
let label = $('<span>', {
|
||||
class: ['label', options.type, options.align].join(' ')
|
||||
}).text( text );
|
||||
let getLabel = (text, options) => $('<span>', {
|
||||
class: ['label', options.type, options.align, options.class].join(' ')
|
||||
}).text(text);
|
||||
|
||||
/**
|
||||
* get killmail data from ESI
|
||||
* @param requestData
|
||||
* @param context
|
||||
* @param callback
|
||||
*/
|
||||
let loadKillmailData = (requestData, context, callback) => {
|
||||
let cacheKey = 'killmail_' + requestData.killId;
|
||||
if(cache[cacheKey]){
|
||||
// ... already cached -> return from cache
|
||||
callback(context, cache[cacheKey])
|
||||
.then(payload => showKills(payload.data.killboardElement, payload.data.systemId, payload.data.chunkSize));
|
||||
}else{
|
||||
// ...not cached -> request data
|
||||
let url = 'https://esi.evetech.net/latest/killmails/' + requestData.killId + '/' + requestData.hash + '/';
|
||||
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: url,
|
||||
dataType: 'json',
|
||||
context: context
|
||||
}).done(function(responseData){
|
||||
cache[cacheKey] = responseData;
|
||||
|
||||
callback(this, responseData)
|
||||
.then(payload => showKills(payload.data.killboardElement, payload.data.systemId, payload.data.chunkSize));
|
||||
}).fail(function(jqXHR, status, error){
|
||||
// request failed -> skip this and load next
|
||||
showKills(this.killboardElement, this.systemId, this.chunkSize);
|
||||
});
|
||||
}
|
||||
|
||||
return label;
|
||||
};
|
||||
|
||||
/**
|
||||
* show killMails
|
||||
* @param moduleElement
|
||||
* @param killboardData
|
||||
* load a chunk of killmails and render them
|
||||
* @param killboardElement
|
||||
* @param systemId
|
||||
* @param chunkSize
|
||||
*/
|
||||
let showKillmails = (moduleElement, killboardData) => {
|
||||
let showKills = (killboardElement, systemId, chunkSize) => {
|
||||
if(chunkSize){
|
||||
if(
|
||||
killboardElement.children().length < config.maxCountKills &&
|
||||
cache['zkb_' + systemId].length
|
||||
){
|
||||
// next killmail to load
|
||||
let nextZkb = cache['zkb_' + systemId].shift();
|
||||
|
||||
// show number of killMails
|
||||
let killMailCounterMax = 20;
|
||||
let killMailCounter = 0;
|
||||
|
||||
// change order (show right to left)
|
||||
killboardData.tableData.reverse();
|
||||
|
||||
let data = {
|
||||
tableData: killboardData.tableData,
|
||||
systemKillboardListClass: config.systemKillboardListClass,
|
||||
systemKillboardListEntryClass: config.systemKillboardListEntryClass,
|
||||
systemKillboardListImgShip: config.systemKillboardListImgShip,
|
||||
systemKillboardListImgChar: config.systemKillboardListImgChar,
|
||||
systemKillboardListImgAlly: config.systemKillboardListImgAlly,
|
||||
systemKillboardListImgCorp: config.systemKillboardListImgCorp,
|
||||
zKillboardUrl: 'https://zkillboard.com',
|
||||
ccpImageServerUrl: Init.url.ccpImageServer,
|
||||
|
||||
dateFormat: () => {
|
||||
return (val, render) => {
|
||||
let killDate = Util.convertDateToUTC(new Date(render(val)));
|
||||
return Util.convertDateToString(killDate);
|
||||
};
|
||||
},
|
||||
iskFormat: () => {
|
||||
return (val, render) => {
|
||||
return Util.formatPrice(render(val));
|
||||
};
|
||||
},
|
||||
checkRender : () => {
|
||||
return (val, render) => {
|
||||
if(killMailCounter < killMailCounterMax){
|
||||
return render(val);
|
||||
}
|
||||
};
|
||||
},
|
||||
increaseCount : () => {
|
||||
return (val, render) => {
|
||||
killMailCounter++;
|
||||
};
|
||||
loadKillmailData({
|
||||
killId: parseInt(nextZkb.killmail_id) || 0,
|
||||
hash: nextZkb.zkb.hash
|
||||
}, {
|
||||
chunkSize: --chunkSize,
|
||||
zkb: nextZkb.zkb,
|
||||
systemId: systemId,
|
||||
killboardElement: killboardElement
|
||||
}, renderKillmail);
|
||||
}else{
|
||||
// no more kills available OR max kills reached
|
||||
killboardElement.closest('.' + config.moduleTypeClass).find('.' + config.controlAreaClass).hide();
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* render a single killmail
|
||||
* @param context
|
||||
* @param killmailData
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
let renderKillmail = (context, killmailData) => {
|
||||
|
||||
let renderKillmailExecutor = (resolve, reject) => {
|
||||
// calculate time diff in hours
|
||||
let serverDate= Util.getServerTime();
|
||||
let killDate = Util.convertDateToUTC(new Date(killmailData.killmail_time));
|
||||
|
||||
// get time diff
|
||||
let timeDiffMin = Math.round((serverDate - killDate) / 1000 / 60);
|
||||
let timeDiffHour = Math.floor(timeDiffMin / 60);
|
||||
|
||||
let data = {
|
||||
zkb: context.zkb,
|
||||
killmail: killmailData,
|
||||
systemKillboardListEntryClass: config.systemKillboardListEntryClass,
|
||||
systemKillboardListImgShip: config.systemKillboardListImgShip,
|
||||
systemKillboardListImgChar: config.systemKillboardListImgChar,
|
||||
systemKillboardListImgCorp: config.systemKillboardListImgCorp,
|
||||
systemKillboardListImgAlly: config.systemKillboardListImgAlly,
|
||||
zKillboardUrl: 'https://zkillboard.com',
|
||||
ccpImageServerUrl: Init.url.ccpImageServer,
|
||||
dateFormat: () => {
|
||||
return (val, render) => {
|
||||
let killDate = Util.convertDateToUTC(new Date(render(val)));
|
||||
return Util.convertDateToString(killDate);
|
||||
};
|
||||
},
|
||||
iskFormat: () => {
|
||||
return (val, render) => {
|
||||
return Util.formatPrice(render(val));
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
requirejs(['text!templates/modules/killmail.html', 'mustache'], (template, Mustache) => {
|
||||
// show hint for recent kills -------------------------------------------------------------------------
|
||||
if(timeDiffHour === 0){
|
||||
context.killboardElement.siblings('.' + config.labelRecentKillsClass).css('display', 'block');
|
||||
}
|
||||
|
||||
// render killmail entry ------------------------------------------------------------------------------
|
||||
let content = Mustache.render(template, data);
|
||||
context.killboardElement.append(content);
|
||||
|
||||
// animate kill li-element ----------------------------------------------------------------------------
|
||||
context.killboardElement.children().last().velocity('transition.expandIn', {
|
||||
complete: function(){
|
||||
$(this).find('[title]').tooltip({
|
||||
container: 'body'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
resolve({
|
||||
action: 'renderKillmail',
|
||||
data: context
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
requirejs(['text!templates/modules/killboard.html', 'mustache'], function(template, Mustache){
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
moduleElement.append(content);
|
||||
|
||||
// animate kill li-elements
|
||||
$('.' + config.systemKillboardListEntryClass).velocity('transition.expandIn', {
|
||||
stagger: 50,
|
||||
complete: function(){
|
||||
// init tooltips
|
||||
moduleElement.find('[title]').tooltip({
|
||||
container: 'body'
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
return new Promise(renderKillmailExecutor);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -127,214 +194,69 @@ define([
|
||||
$.fn.updateSystemInfoGraphs = function(systemData){
|
||||
let moduleElement = $(this);
|
||||
|
||||
let killboardGraphElement = $('<div>', {
|
||||
class: config.systemKillboardGraphKillsClass
|
||||
});
|
||||
|
||||
moduleElement.append(killboardGraphElement);
|
||||
|
||||
let showHours = 24;
|
||||
let maxKillmailCount = 200; // limited by API
|
||||
|
||||
let labelOptions = {
|
||||
align: 'center-block'
|
||||
};
|
||||
let label = '';
|
||||
|
||||
// private function draws a "system kills" graph
|
||||
let drawGraph = function(data){
|
||||
let tableData = data.tableData;
|
||||
// get kills within the last 24h
|
||||
let timeFrameInSeconds = 60 * 60 * 24;
|
||||
|
||||
// change order (show right to left)
|
||||
tableData.reverse();
|
||||
|
||||
if(data.count === 0){
|
||||
labelOptions.type = 'label-success';
|
||||
label = getLabel('No kills found within the last 24h', labelOptions );
|
||||
killboardGraphElement.append( label );
|
||||
|
||||
minifyKillboardGraphElement(killboardGraphElement);
|
||||
return;
|
||||
}
|
||||
|
||||
let labelYFormat = function(y){
|
||||
return Math.round(y);
|
||||
};
|
||||
|
||||
// draw chart
|
||||
Morris.Bar({
|
||||
element: killboardGraphElement,
|
||||
resize: true,
|
||||
redraw: true,
|
||||
grid: true,
|
||||
gridStrokeWidth: 0.3,
|
||||
gridTextSize: 9,
|
||||
gridTextColor: '#63676a',
|
||||
gridTextFamily: 'Oxygen Bold',
|
||||
hideHover: true,
|
||||
data: tableData,
|
||||
xkey: 'label',
|
||||
ykeys: ['kills'],
|
||||
labels: ['Kills'],
|
||||
yLabelFormat: labelYFormat,
|
||||
xLabelMargin: 10,
|
||||
padding: 10,
|
||||
parseTime: false,
|
||||
barOpacity: 0.8,
|
||||
barRadius: [2, 2, 0, 0],
|
||||
barSizeRatio: 0.5,
|
||||
barGap: 3,
|
||||
barColors: function(row, series, type){
|
||||
if(type === 'bar'){
|
||||
// highlight last row -> recent kills found
|
||||
if(this.xmax === row.x){
|
||||
return '#c2760c';
|
||||
}
|
||||
}
|
||||
|
||||
return '#375959';
|
||||
}
|
||||
});
|
||||
|
||||
// show hint for recent kills
|
||||
if(tableData[tableData.length - 1].kills > 0){
|
||||
labelOptions.type = 'label-warning';
|
||||
label = getLabel( tableData[tableData.length - 1].kills + ' kills within the last hour', labelOptions );
|
||||
killboardGraphElement.prepend( label );
|
||||
}
|
||||
};
|
||||
|
||||
// get recent KB stats (last 24h))
|
||||
let localDate = new Date();
|
||||
|
||||
// cache result for 5min
|
||||
let cacheKey = systemData.systemId + '_' + localDate.getHours() + '_' + ( Math.ceil( localDate.getMinutes() / 5 ) * 5);
|
||||
|
||||
if(cache.systemKillsGraphData.hasOwnProperty(cacheKey) ){
|
||||
// cached results
|
||||
|
||||
drawGraph( cache.systemKillsGraphData[cacheKey] );
|
||||
|
||||
// show killmail information
|
||||
showKillmails(moduleElement, cache.systemKillsGraphData[cacheKey]);
|
||||
}else{
|
||||
|
||||
// chart data
|
||||
let chartData = [];
|
||||
|
||||
for(let i = 0; i < showHours; i++){
|
||||
let tempData = {
|
||||
label: i + 'h',
|
||||
kills: 0
|
||||
};
|
||||
|
||||
chartData.push(tempData);
|
||||
}
|
||||
|
||||
// get kills within the last 24h
|
||||
let timeFrameInSeconds = 60 * 60 * 24;
|
||||
|
||||
// get current server time
|
||||
let serverDate= Util.getServerTime();
|
||||
|
||||
// if system is w-space system -> add link modifier
|
||||
let wSpaceLinkModifier = '';
|
||||
if(systemData.type.id === 1){
|
||||
wSpaceLinkModifier = 'w-space/';
|
||||
}
|
||||
|
||||
let url = Init.url.zKillboard + '/';
|
||||
url += 'no-items/' + wSpaceLinkModifier + 'no-attackers/solarSystemID/' + systemData.systemId + '/pastSeconds/' + timeFrameInSeconds + '/';
|
||||
|
||||
killboardGraphElement.showLoadingAnimation();
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'GET',
|
||||
dataType: 'json'
|
||||
}).done(function(kbData){
|
||||
|
||||
// the API wont return more than 200KMs ! - remember last bar block with complete KM information
|
||||
let lastCompleteDiffHourData = 0;
|
||||
|
||||
// loop kills and count kills by hour
|
||||
for(let i = 0; i < kbData.length; i++){
|
||||
let killmailData = kbData[i];
|
||||
let killDate = Util.convertDateToUTC(new Date(killmailData.killmail_time));
|
||||
|
||||
// get time diff
|
||||
let timeDiffMin = Math.round(( serverDate - killDate ) / 1000 / 60);
|
||||
let timeDiffHour = Math.floor(timeDiffMin / 60);
|
||||
|
||||
// update chart data
|
||||
if(chartData[timeDiffHour]){
|
||||
chartData[timeDiffHour].kills++;
|
||||
|
||||
// add kill mail data
|
||||
if(chartData[timeDiffHour].killmails === undefined){
|
||||
chartData[timeDiffHour].killmails = [];
|
||||
}
|
||||
chartData[timeDiffHour].killmails.push(killmailData);
|
||||
|
||||
if(timeDiffHour > lastCompleteDiffHourData){
|
||||
lastCompleteDiffHourData = timeDiffHour;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// remove empty chart Data
|
||||
if(kbData.length >= maxKillmailCount){
|
||||
chartData = chartData.splice(0, lastCompleteDiffHourData + 1);
|
||||
}
|
||||
|
||||
// fill cache
|
||||
cache.systemKillsGraphData[cacheKey] = {};
|
||||
cache.systemKillsGraphData[cacheKey].tableData = chartData;
|
||||
cache.systemKillsGraphData[cacheKey].count = kbData.length;
|
||||
|
||||
// draw table
|
||||
drawGraph(cache.systemKillsGraphData[cacheKey]);
|
||||
|
||||
// show killmail information
|
||||
showKillmails(moduleElement, cache.systemKillsGraphData[cacheKey]);
|
||||
|
||||
killboardGraphElement.hideLoadingAnimation();
|
||||
}).fail(function(e){
|
||||
|
||||
labelOptions.type = 'label-danger';
|
||||
label = getLabel( 'zKillboard is not responding', labelOptions );
|
||||
killboardGraphElement.prepend( label );
|
||||
|
||||
killboardGraphElement.hideLoadingAnimation();
|
||||
|
||||
minifyKillboardGraphElement(killboardGraphElement);
|
||||
|
||||
Util.showNotify({title: e.status + ': Get system kills', text: 'Loading failed', type: 'error'});
|
||||
});
|
||||
// if system is w-space system -> add link modifier
|
||||
let wSpaceLinkModifier = '';
|
||||
if(systemData.type.id === 1){
|
||||
wSpaceLinkModifier = 'w-space/';
|
||||
}
|
||||
|
||||
let url = Init.url.zKillboard + '/';
|
||||
url += 'no-items/' + wSpaceLinkModifier + 'no-attackers/npc/0/solarSystemID/' + systemData.systemId + '/pastSeconds/' + timeFrameInSeconds + '/';
|
||||
|
||||
moduleElement.showLoadingAnimation();
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'GET',
|
||||
dataType: 'json'
|
||||
}).done(function(result){
|
||||
// zkb result needs to be cached and becomes reduced on "load more"
|
||||
let cacheKey = 'zkb_' + systemData.systemId;
|
||||
cache[cacheKey] = result;
|
||||
|
||||
if(result.length){
|
||||
// kills found -> insert hidden warning for recent kills
|
||||
labelOptions.type = 'label-warning';
|
||||
labelOptions.class = config.labelRecentKillsClass;
|
||||
let label = getLabel('recent kills within the last hour', labelOptions);
|
||||
moduleElement.append(label);
|
||||
|
||||
let killboardElement = $('<ul>', {
|
||||
class: config.systemKillboardListClass
|
||||
});
|
||||
moduleElement.append(killboardElement);
|
||||
moduleElement.append(getControlElement());
|
||||
|
||||
showKills(killboardElement, systemData.systemId, config.chunkCountKills);
|
||||
}else{
|
||||
// no kills found
|
||||
labelOptions.type = 'label-success';
|
||||
label = getLabel('No kills found within the last 24h', labelOptions);
|
||||
moduleElement.append(label);
|
||||
}
|
||||
}).fail(function(e){
|
||||
labelOptions.type = 'label-danger';
|
||||
label = getLabel('zKillboard is not responding', labelOptions);
|
||||
moduleElement.find('.' + config.moduleHeadClass).after(label);
|
||||
|
||||
Util.showNotify({title: e.status + ': Get system kills', text: 'Loading failed', type: 'error'});
|
||||
}).always(function(){
|
||||
moduleElement.hideLoadingAnimation();
|
||||
});
|
||||
|
||||
// init tooltips
|
||||
let tooltipElements = moduleElement.find('[data-toggle="tooltip"]');
|
||||
tooltipElements.tooltip({
|
||||
container: 'body'
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* minify the killboard graph element e.g. if no kills where found, or on error
|
||||
* @param killboardGraphElement
|
||||
*/
|
||||
let minifyKillboardGraphElement = (killboardGraphElement) => {
|
||||
killboardGraphElement.velocity({
|
||||
height: '20px',
|
||||
marginBottom: '0px'
|
||||
},{
|
||||
duration: Init.animationSpeed.mapModule
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -364,6 +286,29 @@ define([
|
||||
return headlineToolbar;
|
||||
};
|
||||
|
||||
/**
|
||||
* get info control element
|
||||
* @returns {void|jQuery|*}
|
||||
*/
|
||||
let getControlElement = () => {
|
||||
let controlElement = $('<div>', {
|
||||
class: [config.dynamicAreaClass, config.controlAreaClass, config.moduleHeadlineIconClass].join(' '),
|
||||
html: '<i class="fas fa-sync"></i> load more'
|
||||
});
|
||||
return controlElement;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param moduleElement
|
||||
* @param systemData
|
||||
*/
|
||||
let setModuleObserver = (moduleElement, systemData) => {
|
||||
moduleElement.on('click', '.' + config.controlAreaClass, function(){
|
||||
let killboardElement = moduleElement.find('.' + config.systemKillboardListClass);
|
||||
showKills(killboardElement, systemData.systemId, config.chunkCountKills);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* before module "show" callback
|
||||
* @param moduleElement
|
||||
@@ -396,6 +341,8 @@ define([
|
||||
)
|
||||
);
|
||||
|
||||
setModuleObserver(moduleElement, systemData);
|
||||
|
||||
return moduleElement;
|
||||
};
|
||||
|
||||
|
||||
@@ -606,7 +606,12 @@ define([
|
||||
let signatureOptions = {
|
||||
deleteOld: (formData.deleteOld) ? 1 : 0
|
||||
};
|
||||
updateSignatureTableByClipboard(moduleElement, systemData, formData.clipboard, signatureOptions);
|
||||
|
||||
let mapId = moduleElement.data('mapId');
|
||||
let systemId = moduleElement.data('systemId');
|
||||
let tableApi = getDataTableInstance(mapId, systemId, 'primary');
|
||||
|
||||
updateSignatureTableByClipboard(tableApi, systemData, formData.clipboard, signatureOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -975,7 +980,6 @@ define([
|
||||
let activateNextCell = (tableApi, cell, columnSelectors) => {
|
||||
let nextCell = searchNextCell(tableApi, cell, columnSelectors);
|
||||
activateCell(nextCell);
|
||||
let test;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1149,6 +1153,22 @@ define([
|
||||
// xEditable sets 'tabindex = -1'
|
||||
};
|
||||
|
||||
/**
|
||||
* en/disables xEditable element (select)
|
||||
* -> disables if there are no source options found
|
||||
* @param element
|
||||
*/
|
||||
let editableSelectCheck = element => {
|
||||
if(element.data('editable')){
|
||||
let options = element.data('editable').options.source();
|
||||
if(options.length > 0){
|
||||
editableEnable(element);
|
||||
}else{
|
||||
editableDisable(element);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* get dataTables default options for signature tables
|
||||
* @param mapId
|
||||
@@ -1328,31 +1348,16 @@ define([
|
||||
}
|
||||
tableApi.draw();
|
||||
|
||||
// find related "type" select (same row) and change options
|
||||
// find related "type" select (same row) and change options ---------------------------
|
||||
let signatureTypeCell = getNeighboringCell(tableApi, cell, 'type:name');
|
||||
let signatureTypeField = signatureTypeCell.nodes().to$();
|
||||
editableSelectCheck(signatureTypeField);
|
||||
|
||||
let typeOptions = getAllSignatureNames(
|
||||
systemData,
|
||||
systemData.type.id,
|
||||
Util.getAreaIdBySecurity(systemData.security),
|
||||
newValue
|
||||
);
|
||||
signatureTypeField.editable('option', 'source', typeOptions);
|
||||
|
||||
if(
|
||||
newValue > 0 &&
|
||||
typeOptions.length > 0
|
||||
){
|
||||
editableEnable(signatureTypeField);
|
||||
}else{
|
||||
editableDisable(signatureTypeField);
|
||||
}
|
||||
signatureTypeCell.data(0);
|
||||
signatureTypeField.editable('setValue', 0);
|
||||
|
||||
|
||||
// find "connection" select (same row) and change "enabled" flag
|
||||
// find "connection" select (same row) and change "enabled" flag ----------------------
|
||||
let signatureConnectionCell = getNeighboringCell(tableApi, cell, 'connection:name');
|
||||
let signatureConnectionField = signatureConnectionCell.nodes().to$();
|
||||
|
||||
@@ -2255,6 +2260,26 @@ define([
|
||||
// xEditable is active -> should always be active!
|
||||
// set new value even if no change -> e.g. render selected Ids as text labels
|
||||
let oldValue = node.editable('getValue', true);
|
||||
|
||||
// ... some editable cells depend on each other (e.g. group->type, group->connection)
|
||||
switch(node.data('editable').options.name){
|
||||
case 'typeId':
|
||||
// ... disable if no type options found
|
||||
editableSelectCheck(node);
|
||||
break;
|
||||
case 'connectionId':
|
||||
// disables if no wormhole group set
|
||||
let groupId = cell.cell(rowIndex, 'group:name').data();
|
||||
if(groupId === 5){
|
||||
// wormhole
|
||||
editableEnable(node);
|
||||
}else{
|
||||
editableDisable(node);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// values should be set AFTER en/disabling of a field
|
||||
node.editable('setValue', cell.data());
|
||||
|
||||
if(oldValue !== cell.data()){
|
||||
@@ -2340,6 +2365,9 @@ define([
|
||||
// table data changed -> draw() table changes
|
||||
tableApi.draw();
|
||||
|
||||
// check for "leads to" conflicts -> important if there are just "update" (no add/delete) changes
|
||||
checkConnectionConflicts();
|
||||
|
||||
if(!updateEmptyTable){
|
||||
// no notifications if table was empty just progressbar notification is needed
|
||||
// sum payloads by "action"
|
||||
|
||||
118
js/app/util.js
118
js/app/util.js
@@ -25,6 +25,9 @@ define([
|
||||
ajaxOverlayClass: 'pf-loading-overlay',
|
||||
ajaxOverlayWrapperClass: 'pf-loading-overlay-wrapper',
|
||||
|
||||
// page
|
||||
noScrollClass: 'no-scroll',
|
||||
|
||||
// form
|
||||
formEditableFieldClass: 'pf-editable', // class for all xEditable fields
|
||||
formErrorContainerClass: 'pf-dialog-error-container', // class for "error" containers in dialogs
|
||||
@@ -497,6 +500,8 @@ define([
|
||||
let data = {};
|
||||
|
||||
if(
|
||||
tooltipData.created &&
|
||||
tooltipData.updated &&
|
||||
tooltipData.created.character &&
|
||||
tooltipData.updated.character
|
||||
){
|
||||
@@ -522,39 +527,41 @@ define([
|
||||
createdStatusClass: statusCreatedClass,
|
||||
updatedStatusClass: statusUpdatedClass
|
||||
};
|
||||
}
|
||||
|
||||
let defaultOptions = {
|
||||
placement: 'top',
|
||||
html: true,
|
||||
trigger: 'hover',
|
||||
container: 'body',
|
||||
title: 'Created / Updated',
|
||||
delay: {
|
||||
show: 150,
|
||||
hide: 0
|
||||
}
|
||||
};
|
||||
|
||||
options = $.extend({}, defaultOptions, options);
|
||||
|
||||
return this.each(function(){
|
||||
let element = $(this);
|
||||
|
||||
requirejs(['text!templates/tooltip/character_info.html', 'mustache'], (template, Mustache) => {
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
element.popover(options);
|
||||
|
||||
// set new popover content
|
||||
let popover = element.data('bs.popover');
|
||||
popover.options.content = content;
|
||||
|
||||
if(options.show){
|
||||
element.popover('show');
|
||||
let defaultOptions = {
|
||||
placement: 'top',
|
||||
html: true,
|
||||
trigger: 'hover',
|
||||
container: 'body',
|
||||
title: 'Created / Updated',
|
||||
delay: {
|
||||
show: 150,
|
||||
hide: 0
|
||||
}
|
||||
};
|
||||
|
||||
options = $.extend({}, defaultOptions, options);
|
||||
|
||||
return this.each(function(){
|
||||
let element = $(this);
|
||||
|
||||
requirejs(['text!templates/tooltip/character_info.html', 'mustache'], (template, Mustache) => {
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
element.popover(options);
|
||||
|
||||
// set new popover content
|
||||
let popover = element.data('bs.popover');
|
||||
popover.options.content = content;
|
||||
|
||||
if(options.show){
|
||||
element.popover('show');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}else{
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -778,9 +785,7 @@ define([
|
||||
default: console.error('insertElement: %s is not specified!', defaultOptions.insertElement);
|
||||
}
|
||||
|
||||
//containerElement.children().first().velocity('stop').velocity('fadeIn');
|
||||
$('#' + defaultOptions.messageId).velocity('stop').velocity('fadeIn');
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1074,7 +1079,12 @@ define([
|
||||
callbacks: {
|
||||
alwaysTriggerOffsets: false, // only trigger callback.onTotalScroll() once
|
||||
onTotalScrollOffset: 300, // trigger callback.onTotalScroll() 100px before end
|
||||
onTotalScroll: function(a){
|
||||
onInit: function(){
|
||||
// disable page scroll -> otherwise page AND customScrollbars will scroll
|
||||
// -> this is because the initPassiveEvents() delegates the mouseWheel events
|
||||
togglePageScroll(false);
|
||||
},
|
||||
onTotalScroll: function(){
|
||||
// we want to "trigger" Select2´s 'scroll' event
|
||||
// in order to make its "infinite scrolling" function working
|
||||
this.mcs.content.find(':first-child').trigger('scroll');
|
||||
@@ -1117,6 +1127,10 @@ define([
|
||||
// the only way to prevent this is to remove the element
|
||||
// https://stackoverflow.com/questions/17995057/prevent-select2-from-autmatically-focussing-its-search-input-when-dropdown-is-op
|
||||
$(this).parents('.editableform').find(this).next().find('.select2-selection').remove();
|
||||
|
||||
// re-enable page scroll -> might be disabled before by mCustomScrollbar onInit() event
|
||||
// -> in case there is a custom <select> with scrollable options
|
||||
togglePageScroll(true);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1138,6 +1152,14 @@ define([
|
||||
'<div class="editableform-loading"><i class="fas fa-lg fa-sync fa-spin"></i></div>';
|
||||
};
|
||||
|
||||
/**
|
||||
* prevent page from scrolling
|
||||
* @param enable
|
||||
*/
|
||||
let togglePageScroll = (enable = true) => {
|
||||
$('html').toggleClass(config.noScrollClass, !enable);
|
||||
};
|
||||
|
||||
/**
|
||||
* request a captcha image
|
||||
* @param reason
|
||||
@@ -1759,7 +1781,7 @@ define([
|
||||
/**
|
||||
* get a HTML table with system effect information
|
||||
* e.g. for popover
|
||||
* @param data
|
||||
* @param effects
|
||||
* @returns {string}
|
||||
*/
|
||||
let getSystemEffectTable = effects => {
|
||||
@@ -2785,6 +2807,31 @@ define([
|
||||
return instance;
|
||||
};
|
||||
|
||||
/**
|
||||
* HTML encode string
|
||||
* @param value
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
let htmlEncode = value => $('<div>').text(value).html();
|
||||
|
||||
/**
|
||||
* HTML decode string
|
||||
* @param value
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
let htmlDecode = value => $('<div>').html(value).text();
|
||||
|
||||
/**
|
||||
* checks if html is valid
|
||||
* -> see https://stackoverflow.com/a/15458968/4329969
|
||||
* @param html
|
||||
* @returns {boolean}
|
||||
*/
|
||||
let isValidHtml = html => {
|
||||
let doc = new DOMParser().parseFromString(html, 'text/html');
|
||||
return Array.from(doc.body.childNodes).some(node => node.nodeType === 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* get deep json object value if exists
|
||||
* -> e.g. key = 'first.last.third' string
|
||||
@@ -2983,6 +3030,9 @@ define([
|
||||
singleDoubleClick: singleDoubleClick,
|
||||
getTableId: getTableId,
|
||||
getDataTableInstance: getDataTableInstance,
|
||||
htmlEncode: htmlEncode,
|
||||
htmlDecode: htmlDecode,
|
||||
isValidHtml: isValidHtml,
|
||||
getObjVal: getObjVal,
|
||||
redirect: redirect,
|
||||
logout: logout,
|
||||
|
||||
3
js/lib/summernote/summernote.min.js
vendored
Normal file
3
js/lib/summernote/summernote.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
public/css/v1.4.2/pathfinder.css.br
Normal file
BIN
public/css/v1.4.2/pathfinder.css.br
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
public/fonts/summernote.eot
Normal file
BIN
public/fonts/summernote.eot
Normal file
Binary file not shown.
BIN
public/fonts/summernote.ttf
Normal file
BIN
public/fonts/summernote.ttf
Normal file
Binary file not shown.
BIN
public/fonts/summernote.woff
Normal file
BIN
public/fonts/summernote.woff
Normal file
Binary file not shown.
@@ -1,2 +0,0 @@
|
||||
"use strict";var mainScriptPath=document.body.getAttribute("data-script"),jsBaseUrl=document.body.getAttribute("data-js-path");requirejs.config({baseUrl:"js",paths:{layout:"layout",conf:"app/conf",dialog:"app/ui/dialog",templates:"../../templates",img:"../../img",login:"./app/login",mappage:"./app/mappage",setup:"./app/setup",admin:"./app/admin",notification:"./app/notification",jquery:"lib/jquery-3.3.1.min",bootstrap:"lib/bootstrap.min",text:"lib/requirejs/text",mustache:"lib/mustache.min",localForage:"lib/localforage.min",velocity:"lib/velocity.min",velocityUI:"lib/velocity.ui.min",slidebars:"lib/slidebars",jsPlumb:"lib/dom.jsPlumb-1.7.6",farahey:"lib/farahey-0.5",customScrollbar:"lib/jquery.mCustomScrollbar.min",mousewheel:"lib/jquery.mousewheel.min",xEditable:"lib/bootstrap-editable.min",morris:"lib/morris.min",raphael:"lib/raphael-min",bootbox:"lib/bootbox.min",easyPieChart:"lib/jquery.easypiechart.min",peityInlineChart:"lib/jquery.peity.min",dragToSelect:"lib/jquery.dragToSelect",hoverIntent:"lib/jquery.hoverIntent.min",fullScreen:"lib/jquery.fullscreen.min",select2:"lib/select2.min",validator:"lib/validator.min",lazylinepainter:"lib/jquery.lazylinepainter-1.5.1.min",blueImpGallery:"lib/blueimp-gallery",blueImpGalleryHelper:"lib/blueimp-helper",blueImpGalleryBootstrap:"lib/bootstrap-image-gallery",bootstrapConfirmation:"lib/bootstrap-confirmation",bootstrapToggle:"lib/bootstrap-toggle.min",lazyload:"lib/jquery.lazyload.min",sortable:"lib/sortable.min",easePack:"lib/EasePack.min",tweenLite:"lib/TweenLite.min","datatables.loader":"./app/datatables.loader","datatables.net":"lib/datatables/DataTables-1.10.12/js/jquery.dataTables.min","datatables.net-buttons":"lib/datatables/Buttons-1.2.1/js/dataTables.buttons.min","datatables.net-buttons-html":"lib/datatables/Buttons-1.2.1/js/buttons.html5.min","datatables.net-responsive":"lib/datatables/Responsive-2.1.0/js/dataTables.responsive.min","datatables.net-select":"lib/datatables/Select-1.2.0/js/dataTables.select.min","datatables.plugins.render.ellipsis":"lib/datatables/plugins/render/ellipsis",pnotify:"lib/pnotify/pnotify","pnotify.buttons":"lib/pnotify/pnotify.buttons","pnotify.confirm":"lib/pnotify/pnotify.confirm","pnotify.nonblock":"lib/pnotify/pnotify.nonblock","pnotify.desktop":"lib/pnotify/pnotify.desktop","pnotify.history":"lib/pnotify/pnotify.history","pnotify.callbacks":"lib/pnotify/pnotify.callbacks","pnotify.reference":"lib/pnotify/pnotify.reference"},shim:{bootstrap:{deps:["jquery"]},farahey:{deps:["jsPlumb"]},velocity:{deps:["jquery"]},velocityUI:{deps:["velocity"]},slidebars:{deps:["jquery"]},customScrollbar:{deps:["jquery","mousewheel"]},"datatables.loader":{deps:["jquery"]},"datatables.net":{deps:["jquery"]},"datatables.net-buttons":{deps:["datatables.net"]},"datatables.net-buttons-html":{deps:["datatables.net-buttons"]},"datatables.net-responsive":{deps:["datatables.net"]},"datatables.net-select":{deps:["datatables.net"]},"datatables.plugins.render.ellipsis":{deps:["datatables.net"]},xEditable:{deps:["bootstrap"]},bootbox:{deps:["jquery","bootstrap"],exports:"bootbox"},morris:{deps:["jquery","raphael"],exports:"Morris",init:function(e,t){window.Raphael=t}},pnotify:{deps:["jquery"]},easyPieChart:{deps:["jquery"]},peityInlineChart:{deps:["jquery"]},dragToSelect:{deps:["jquery"]},hoverIntent:{deps:["jquery"]},fullScreen:{deps:["jquery"]},select2:{deps:["jquery","mousewheel"],exports:"Select2"},validator:{deps:["jquery","bootstrap"]},lazylinepainter:{deps:["jquery","bootstrap"]},blueImpGallery:{deps:["jquery"]},bootstrapConfirmation:{deps:["bootstrap"]},bootstrapToggle:{deps:["jquery"]},lazyload:{deps:["jquery"]}}}),require.config({baseUrl:jsBaseUrl}),requirejs([mainScriptPath]);
|
||||
//# sourceMappingURL=app.js.map
|
||||
Binary file not shown.
@@ -1 +0,0 @@
|
||||
{"version":3,"sources":["app.js"],"names":["mainScriptPath","document","body","getAttribute","jsBaseUrl","requirejs","config","baseUrl","paths","layout","conf","dialog","templates","img","login","mappage","setup","admin","notification","jquery","bootstrap","text","mustache","localForage","velocity","velocityUI","slidebars","jsPlumb","farahey","customScrollbar","mousewheel","xEditable","morris","raphael","bootbox","easyPieChart","peityInlineChart","dragToSelect","hoverIntent","fullScreen","select2","validator","lazylinepainter","blueImpGallery","blueImpGalleryHelper","blueImpGalleryBootstrap","bootstrapConfirmation","bootstrapToggle","lazyload","sortable","easePack","tweenLite","datatables.loader","datatables.net","datatables.net-buttons","datatables.net-buttons-html","datatables.net-responsive","datatables.net-select","datatables.plugins.render.ellipsis","pnotify","pnotify.buttons","pnotify.confirm","pnotify.nonblock","pnotify.desktop","pnotify.history","pnotify.callbacks","pnotify.reference","shim","deps","exports","init","$","Raphael","window","require"],"mappings":"AAAA,aAGA,IAAIA,eAAiBC,SAASC,KAAKC,aAAa,eAI5CC,UAAYH,SAASC,KAAKC,aAAa,gBAG3CE,UAAUC,QACNC,QAAS,KAETC,OACIC,OAAQ,SACRC,KAAM,WACNC,OAAQ,gBACRC,UAAW,kBACXC,IAAK,YAGLC,MAAO,cACPC,QAAS,gBACTC,MAAO,cACPC,MAAO,cACPC,aAAc,qBAEdC,OAAQ,uBACRC,UAAW,oBACXC,KAAM,qBACNC,SAAU,mBACVC,YAAa,sBACbC,SAAU,mBACVC,WAAY,sBACZC,UAAW,gBACXC,QAAS,wBACTC,QAAS,kBACTC,gBAAiB,kCACjBC,WAAY,4BACZC,UAAW,6BACXC,OAAQ,iBACRC,QAAS,kBACTC,QAAS,kBACTC,aAAc,8BACdC,iBAAkB,uBAClBC,aAAc,0BACdC,YAAa,6BACbC,WAAY,4BACZC,QAAS,kBACTC,UAAW,oBACXC,gBAAiB,uCACjBC,eAAgB,sBAChBC,qBAAsB,qBACtBC,wBAAyB,8BACzBC,sBAAuB,6BACvBC,gBAAiB,2BACjBC,SAAU,0BACVC,SAAU,mBAGVC,SAAU,mBACVC,UAAW,oBAGXC,oBAAqB,0BACrBC,iBAAkB,6DAClBC,yBAA0B,yDAC1BC,8BAA+B,oDAC/BC,4BAA6B,+DAC7BC,wBAAyB,uDACzBC,qCAAsC,yCAGtCC,QAAS,sBACTC,kBAAmB,8BACnBC,kBAAmB,8BACnBC,mBAAoB,+BACpBC,kBAAmB,8BACnBC,kBAAmB,8BACnBC,oBAAqB,gCACrBC,oBAAqB,iCAEzBC,MACI/C,WACIgD,MAAO,WAEXxC,SACIwC,MAAO,YAEX5C,UACI4C,MAAO,WAEX3C,YACI2C,MAAO,aAEX1C,WACI0C,MAAO,WAEXvC,iBACIuC,MAAO,SAAU,eAErBhB,qBACIgB,MAAO,WAEXf,kBACIe,MAAO,WAEXd,0BACIc,MAAO,mBAEXb,+BACIa,MAAO,2BAEXZ,6BACIY,MAAO,mBAEXX,yBACIW,MAAO,mBAEXV,sCACIU,MAAO,mBAEXrC,WACIqC,MAAO,cAEXlC,SACIkC,MAAO,SAAU,aACjBC,QAAS,WAEbrC,QACIoC,MAAO,SAAU,WACjBC,QAAS,SACTC,KAAM,SAAUC,EAAGC,GACfC,OAAOD,QAAUA,IAGzBb,SACIS,MAAQ,WAEZjC,cACIiC,MAAQ,WAEZhC,kBACIgC,MAAQ,WAEZ/B,cACI+B,MAAQ,WAEZ9B,aACI8B,MAAQ,WAEZ7B,YACI6B,MAAQ,WAEZ5B,SACI4B,MAAQ,SAAU,cAClBC,QAAS,WAEb5B,WACI2B,MAAQ,SAAU,cAEtB1B,iBACI0B,MAAQ,SAAU,cAEtBzB,gBACIyB,MAAQ,WAEZtB,uBACIsB,MAAQ,cAEZrB,iBACIqB,MAAQ,WAEZpB,UACIoB,MAAQ,cAQpBM,QAAQpE,QACJC,QAASH,YAIbC,WAAYL","file":"app.js","sourceRoot":"/js"}
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
2
public/js/v1.4.2/app.js
Normal file
2
public/js/v1.4.2/app.js
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";var mainScriptPath=document.body.getAttribute("data-script"),jsBaseUrl=document.body.getAttribute("data-js-path");requirejs.config({baseUrl:"js",paths:{layout:"layout",conf:"app/conf",dialog:"app/ui/dialog",templates:"../../templates",img:"../../img",login:"./app/login",mappage:"./app/mappage",setup:"./app/setup",admin:"./app/admin",notification:"./app/notification",jquery:"lib/jquery-3.3.1.min",bootstrap:"lib/bootstrap.min",text:"lib/requirejs/text",mustache:"lib/mustache.min",localForage:"lib/localforage.min",velocity:"lib/velocity.min",velocityUI:"lib/velocity.ui.min",slidebars:"lib/slidebars",jsPlumb:"lib/dom.jsPlumb-1.7.6",farahey:"lib/farahey-0.5",customScrollbar:"lib/jquery.mCustomScrollbar.min",mousewheel:"lib/jquery.mousewheel.min",xEditable:"lib/bootstrap-editable.min",morris:"lib/morris.min",raphael:"lib/raphael-min",bootbox:"lib/bootbox.min",easyPieChart:"lib/jquery.easypiechart.min",peityInlineChart:"lib/jquery.peity.min",dragToSelect:"lib/jquery.dragToSelect",hoverIntent:"lib/jquery.hoverIntent.min",fullScreen:"lib/jquery.fullscreen.min",select2:"lib/select2.min",validator:"lib/validator.min",lazylinepainter:"lib/jquery.lazylinepainter-1.5.1.min",blueImpGallery:"lib/blueimp-gallery",blueImpGalleryHelper:"lib/blueimp-helper",blueImpGalleryBootstrap:"lib/bootstrap-image-gallery",bootstrapConfirmation:"lib/bootstrap-confirmation",bootstrapToggle:"lib/bootstrap-toggle.min",lazyload:"lib/jquery.lazyload.min",sortable:"lib/sortable.min","summernote.loader":"./app/summernote.loader",summernote:"lib/summernote/summernote.min",easePack:"lib/EasePack.min",tweenLite:"lib/TweenLite.min","datatables.loader":"./app/datatables.loader","datatables.net":"lib/datatables/DataTables-1.10.12/js/jquery.dataTables.min","datatables.net-buttons":"lib/datatables/Buttons-1.2.1/js/dataTables.buttons.min","datatables.net-buttons-html":"lib/datatables/Buttons-1.2.1/js/buttons.html5.min","datatables.net-responsive":"lib/datatables/Responsive-2.1.0/js/dataTables.responsive.min","datatables.net-select":"lib/datatables/Select-1.2.0/js/dataTables.select.min","datatables.plugins.render.ellipsis":"lib/datatables/plugins/render/ellipsis",pnotify:"lib/pnotify/pnotify","pnotify.buttons":"lib/pnotify/pnotify.buttons","pnotify.confirm":"lib/pnotify/pnotify.confirm","pnotify.nonblock":"lib/pnotify/pnotify.nonblock","pnotify.desktop":"lib/pnotify/pnotify.desktop","pnotify.history":"lib/pnotify/pnotify.history","pnotify.callbacks":"lib/pnotify/pnotify.callbacks","pnotify.reference":"lib/pnotify/pnotify.reference"},shim:{bootstrap:{deps:["jquery"]},farahey:{deps:["jsPlumb"]},velocity:{deps:["jquery"]},velocityUI:{deps:["velocity"]},slidebars:{deps:["jquery"]},customScrollbar:{deps:["jquery","mousewheel"]},"datatables.loader":{deps:["jquery"]},"datatables.net":{deps:["jquery"]},"datatables.net-buttons":{deps:["datatables.net"]},"datatables.net-buttons-html":{deps:["datatables.net-buttons"]},"datatables.net-responsive":{deps:["datatables.net"]},"datatables.net-select":{deps:["datatables.net"]},"datatables.plugins.render.ellipsis":{deps:["datatables.net"]},xEditable:{deps:["bootstrap"]},bootbox:{deps:["jquery","bootstrap"],exports:"bootbox"},morris:{deps:["jquery","raphael"],exports:"Morris",init:function(e,t){window.Raphael=t}},pnotify:{deps:["jquery"]},easyPieChart:{deps:["jquery"]},peityInlineChart:{deps:["jquery"]},dragToSelect:{deps:["jquery"]},hoverIntent:{deps:["jquery"]},fullScreen:{deps:["jquery"]},select2:{deps:["jquery","mousewheel"],exports:"Select2"},validator:{deps:["jquery","bootstrap"]},lazylinepainter:{deps:["jquery","bootstrap"]},blueImpGallery:{deps:["jquery"]},bootstrapConfirmation:{deps:["bootstrap"]},bootstrapToggle:{deps:["jquery"]},lazyload:{deps:["jquery"]},summernote:{deps:["jquery"]}}}),require.config({baseUrl:jsBaseUrl}),requirejs([mainScriptPath]);
|
||||
//# sourceMappingURL=app.js.map
|
||||
BIN
public/js/v1.4.2/app.js.br
Normal file
BIN
public/js/v1.4.2/app.js.br
Normal file
Binary file not shown.
1
public/js/v1.4.2/app.js.map
Normal file
1
public/js/v1.4.2/app.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["app.js"],"names":["mainScriptPath","document","body","getAttribute","jsBaseUrl","requirejs","config","baseUrl","paths","layout","conf","dialog","templates","img","login","mappage","setup","admin","notification","jquery","bootstrap","text","mustache","localForage","velocity","velocityUI","slidebars","jsPlumb","farahey","customScrollbar","mousewheel","xEditable","morris","raphael","bootbox","easyPieChart","peityInlineChart","dragToSelect","hoverIntent","fullScreen","select2","validator","lazylinepainter","blueImpGallery","blueImpGalleryHelper","blueImpGalleryBootstrap","bootstrapConfirmation","bootstrapToggle","lazyload","sortable","summernote.loader","summernote","easePack","tweenLite","datatables.loader","datatables.net","datatables.net-buttons","datatables.net-buttons-html","datatables.net-responsive","datatables.net-select","datatables.plugins.render.ellipsis","pnotify","pnotify.buttons","pnotify.confirm","pnotify.nonblock","pnotify.desktop","pnotify.history","pnotify.callbacks","pnotify.reference","shim","deps","exports","init","$","Raphael","window","require"],"mappings":"AAAA,aAGA,IAAIA,eAAiBC,SAASC,KAAKC,aAAa,eAI5CC,UAAYH,SAASC,KAAKC,aAAa,gBAG3CE,UAAUC,QACNC,QAAS,KAETC,OACIC,OAAQ,SACRC,KAAM,WACNC,OAAQ,gBACRC,UAAW,kBACXC,IAAK,YAGLC,MAAO,cACPC,QAAS,gBACTC,MAAO,cACPC,MAAO,cACPC,aAAc,qBAEdC,OAAQ,uBACRC,UAAW,oBACXC,KAAM,qBACNC,SAAU,mBACVC,YAAa,sBACbC,SAAU,mBACVC,WAAY,sBACZC,UAAW,gBACXC,QAAS,wBACTC,QAAS,kBACTC,gBAAiB,kCACjBC,WAAY,4BACZC,UAAW,6BACXC,OAAQ,iBACRC,QAAS,kBACTC,QAAS,kBACTC,aAAc,8BACdC,iBAAkB,uBAClBC,aAAc,0BACdC,YAAa,6BACbC,WAAY,4BACZC,QAAS,kBACTC,UAAW,oBACXC,gBAAiB,uCACjBC,eAAgB,sBAChBC,qBAAsB,qBACtBC,wBAAyB,8BACzBC,sBAAuB,6BACvBC,gBAAiB,2BACjBC,SAAU,0BACVC,SAAU,mBAEVC,oBAAqB,0BACrBC,WAAc,gCAGdC,SAAU,mBACVC,UAAW,oBAGXC,oBAAqB,0BACrBC,iBAAkB,6DAClBC,yBAA0B,yDAC1BC,8BAA+B,oDAC/BC,4BAA6B,+DAC7BC,wBAAyB,uDACzBC,qCAAsC,yCAGtCC,QAAS,sBACTC,kBAAmB,8BACnBC,kBAAmB,8BACnBC,mBAAoB,+BACpBC,kBAAmB,8BACnBC,kBAAmB,8BACnBC,oBAAqB,gCACrBC,oBAAqB,iCAEzBC,MACIjD,WACIkD,MAAO,WAEX1C,SACI0C,MAAO,YAEX9C,UACI8C,MAAO,WAEX7C,YACI6C,MAAO,aAEX5C,WACI4C,MAAO,WAEXzC,iBACIyC,MAAO,SAAU,eAErBhB,qBACIgB,MAAO,WAEXf,kBACIe,MAAO,WAEXd,0BACIc,MAAO,mBAEXb,+BACIa,MAAO,2BAEXZ,6BACIY,MAAO,mBAEXX,yBACIW,MAAO,mBAEXV,sCACIU,MAAO,mBAEXvC,WACIuC,MAAO,cAEXpC,SACIoC,MAAO,SAAU,aACjBC,QAAS,WAEbvC,QACIsC,MAAO,SAAU,WACjBC,QAAS,SACTC,KAAM,SAAUC,EAAGC,GACfC,OAAOD,QAAUA,IAGzBb,SACIS,MAAO,WAEXnC,cACImC,MAAO,WAEXlC,kBACIkC,MAAO,WAEXjC,cACIiC,MAAO,WAEXhC,aACIgC,MAAO,WAEX/B,YACI+B,MAAO,WAEX9B,SACI8B,MAAO,SAAU,cACjBC,QAAS,WAEb9B,WACI6B,MAAO,SAAU,cAErB5B,iBACI4B,MAAO,SAAU,cAErB3B,gBACI2B,MAAO,WAEXxB,uBACIwB,MAAO,cAEXvB,iBACIuB,MAAO,WAEXtB,UACIsB,MAAO,WAEXnB,YACImB,MAAO,cAQnBM,QAAQtE,QACJC,QAASH,YAIbC,WAAYL","file":"app.js","sourceRoot":"/js"}
|
||||
File diff suppressed because one or more lines are too long
BIN
public/js/v1.4.2/app/admin.js.br
Normal file
BIN
public/js/v1.4.2/app/admin.js.br
Normal file
Binary file not shown.
1
public/js/v1.4.2/app/admin.js.map
Normal file
1
public/js/v1.4.2/app/admin.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
public/js/v1.4.2/app/login.js.br
Normal file
BIN
public/js/v1.4.2/app/login.js.br
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
2
public/js/v1.4.2/app/mappage.js
Normal file
2
public/js/v1.4.2/app/mappage.js
Normal file
File diff suppressed because one or more lines are too long
BIN
public/js/v1.4.2/app/mappage.js.br
Normal file
BIN
public/js/v1.4.2/app/mappage.js.br
Normal file
Binary file not shown.
1
public/js/v1.4.2/app/mappage.js.map
Normal file
1
public/js/v1.4.2/app/mappage.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
public/js/v1.4.2/app/setup.js.br
Normal file
BIN
public/js/v1.4.2/app/setup.js.br
Normal file
Binary file not shown.
1
public/js/v1.4.2/app/setup.js.map
Normal file
1
public/js/v1.4.2/app/setup.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/js/v1.4.2/app/summernote.loader.js
Normal file
2
public/js/v1.4.2/app/summernote.loader.js
Normal file
@@ -0,0 +1,2 @@
|
||||
define(["jquery","app/init","summernote"],(e,a)=>{"use strict";return e.extend(e.summernote.plugins,{lengthField:function(a){e.summernote.ui,a.memo("button.lengthField",()=>e("<kbd>",{class:["text-right","txt-color"].join(" ")}));let t=e=>{let t=a.options.maxTextLength,n=e.length,s=a.layoutInfo.toolbar.find("kbd"),f=t-n;s.text(f).data("charCount",f),s.toggleClass("txt-color-red",t<=n),a.layoutInfo.toolbar.find(".btn-save").prop("disabled",t<n)};this.events={"summernote.init":function(e,n){t(a.$note.summernote("code"))},"summernote.change":function(e,a){t(a)}}}}),e.extend(e.summernote.plugins,{discardBtn:function(a){let t=e.summernote.ui;a.memo("button.discardBtn",()=>{let n=t.button({contents:'<i class="fas fa-fw fa-ban"/>',container:"body",click:function(){e(this).confirmation("show")}}).render(),s={container:"body",placement:"top",btnCancelClass:"btn btn-sm btn-default",btnCancelLabel:"cancel",title:"discard changes",btnOkClass:"btn btn-sm btn-warning",btnOkLabel:"discard",btnOkIcon:"fas fa-fw fa-ban",onConfirm:(e,t)=>{a.$note.summernote("reset"),a.$note.summernote("destroy")}};return n.confirmation(s),n})}}),{initSummernote:(a,t)=>{t=e.extend({},{dialogsInBody:!0,dialogsFade:!0,styleTags:["p","h2","h3","blockquote"],linkTargetBlank:!0,tableClassName:"table table-condensed table-bordered",insertTableMaxSize:{col:5,row:5},icons:{alignCenter:"fas fa-align-center",alignJustify:"fas fa-align-justify",alignLeft:"fas fa-align-left",alignRight:"fas fa-align-right",indent:"fas fa-indent",outdent:"fas fa-outdent",arrowsAlt:"fas fa-expand-arrows-alt",bold:"fas fa-bold",caret:"fas fa-caret-down",circle:"fas fa-circle",close:"fas fa-time",code:"fas fa-code",eraser:"fas fa-eraser",font:"fas fa-font",italic:"fas fa-italic",link:"fas fa-link",unlink:"fas fa-unlink",magic:"fas fa-magic",menuCheck:"fas fa-check",minus:"fas fa-minus",orderedlist:"fas fa-list-ol",pencil:"fa-pen",picture:"fas fa-image",question:"fas fa-question",redo:"fas fa-redo",square:"fas fa-square",strikethrough:"fas fa-strikethrough",subscript:"fas fa-subscript",superscript:"fas fa-superscript",table:"fas fa-table",textHeight:"fas fa-text-height",trash:"fas fa-trash",underline:"fas fa-underline",undo:"fas fa-undo",unorderedlist:"fas fa-list-ul",video:"fab fa-youtube"},colors:[["#5cb85c","#e28a0d","#d9534f","#e06fdf","#9fa8da","#e2ce48","#428bca"]],colorsName:[["Green","Orange","Red","Pink","Indigo","Yellow","Blue"]]},t),a.summernote(t)}}});
|
||||
//# sourceMappingURL=summernote.loader.js.map
|
||||
BIN
public/js/v1.4.2/app/summernote.loader.js.br
Normal file
BIN
public/js/v1.4.2/app/summernote.loader.js.br
Normal file
Binary file not shown.
1
public/js/v1.4.2/app/summernote.loader.js.map
Normal file
1
public/js/v1.4.2/app/summernote.loader.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["app/summernote.loader.js"],"names":["define","$","Init","extend","summernote","plugins","lengthField","context","ui","memo","class","join","updateCounter","contents","maxTextLength","options","textLength","length","counter","layoutInfo","toolbar","find","counterLeft","text","data","toggleClass","prop","this","events","summernote.init","we","e","$note","summernote.change","discardBtn","$button","button","container","click","confirmation","render","confirmationSettings","placement","btnCancelClass","btnCancelLabel","title","btnOkClass","btnOkLabel","btnOkIcon","onConfirm","target","initSummernote","element","dialogsInBody","dialogsFade","styleTags","linkTargetBlank","tableClassName","insertTableMaxSize","col","row","icons","alignCenter","alignJustify","alignLeft","alignRight","indent","outdent","arrowsAlt","bold","caret","circle","close","code","eraser","font","italic","link","unlink","magic","menuCheck","minus","orderedlist","pencil","picture","question","redo","square","strikethrough","subscript","superscript","table","textHeight","trash","underline","undo","unorderedlist","video","colors","colorsName"],"mappings":"AAAAA,QACI,SACA,WACA,cACD,CAACC,EAAGC,KACH,aAkLA,OA7KID,EAAEE,OAAOF,EAAEG,WAAWC,SAIlBC,YAAa,SAAUC,GAEVN,EAAEG,WAAWI,GAGtBD,EAAQE,KAAK,qBAAsB,IACxBR,EAAE,SACLS,OAAQ,aAAc,aAAaC,KAAK,QAQhD,IAAIC,EAAiBC,IACjB,IAAIC,EAAgBP,EAAQQ,QAAQD,cAChCE,EAAaH,EAASI,OACtBC,EAAUX,EAAQY,WAAWC,QAAQC,KAAK,OAC1CC,EAAcR,EAAgBE,EAElCE,EAAQK,KAAKD,GAAaE,KAAK,YAAaF,GAC5CJ,EAAQO,YAAY,gBAAiBX,GAAiBE,GAGxCT,EAAQY,WAAWC,QAAQC,KAAK,aACtCK,KAAK,WAAYZ,EAAgBE,IAI7CW,KAAKC,QACDC,kBAAmB,SAAUC,EAAIC,GAC7BnB,EAAcL,EAAQyB,MAAM5B,WAAW,UAE3C6B,oBAAqB,SAASH,EAAIjB,GAC9BD,EAAcC,QAQ9BZ,EAAEE,OAAOF,EAAEG,WAAWC,SAIlB6B,WAAY,SAAU3B,GAClB,IACIC,EAAKP,EAAEG,WAAWI,GAGtBD,EAAQE,KAAK,oBAAqB,KAC9B,IAQI0B,EARS3B,EAAG4B,QACZvB,SAAU,gCACVwB,UAAW,OACXC,MAAO,WAEHrC,EAAE0B,MAAMY,aAAa,WAGRC,SAGjBC,GACAJ,UAAW,OACXK,UAAW,MACXC,eAAgB,yBAChBC,eAAgB,SAChBC,MAAO,kBACPC,WAAY,yBACZC,WAAY,UACZC,UAAW,mBACXC,UAAW,CAAClB,EAAGmB,KAEX3C,EAAQyB,MAAM5B,WAAW,SACzBG,EAAQyB,MAAM5B,WAAW,aAKjC,OAFA+B,EAAQI,aAAaE,GAEdN,QAyFnBgB,eA9EiB,CAACC,EAASrC,KAsE3BA,EAAUd,EAAEE,WAnERkD,eAAe,EACfC,aAAa,EAKbC,WAAY,IAAK,KAAM,KAAM,cAC7BC,iBAAiB,EACjBC,eAAgB,uCAChBC,oBACIC,IAAK,EACLC,IAAK,GAETC,OAEIC,YAAe,sBACfC,aAAgB,uBAChBC,UAAa,oBACbC,WAAc,qBAOdC,OAAU,gBACVC,QAAW,iBACXC,UAAa,2BACbC,KAAQ,cACRC,MAAS,oBACTC,OAAU,gBACVC,MAAS,cACTC,KAAQ,cACRC,OAAU,gBACVC,KAAQ,cAERC,OAAU,gBACVC,KAAQ,cACRC,OAAU,gBACVC,MAAS,eACTC,UAAa,eACbC,MAAS,eACTC,YAAe,iBACfC,OAAU,SACVC,QAAW,eACXC,SAAY,kBACZC,KAAQ,cACRC,OAAU,gBACVC,cAAiB,uBACjBC,UAAa,mBACbC,YAAe,qBACfC,MAAS,eACTC,WAAc,qBACdC,MAAS,eACTC,UAAa,mBACbC,KAAQ,cACRC,cAAiB,iBACjBC,MAAS,kBAEbC,SACK,UAAW,UAAW,UAAW,UAAW,UAAW,UAAW,YAEvEC,aACK,QAAS,SAAU,MAAO,OAAQ,SAAU,SAAU,UAIxBpF,GAEvCqC,EAAQhD,WAAWW","file":"summernote.loader.js","sourceRoot":"/js"}
|
||||
2
public/js/v1.4.2/lib/summernote/summernote.min.js
vendored
Normal file
2
public/js/v1.4.2/lib/summernote/summernote.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
public/js/v1.4.2/lib/summernote/summernote.min.js.br
Normal file
BIN
public/js/v1.4.2/lib/summernote/summernote.min.js.br
Normal file
Binary file not shown.
1
public/js/v1.4.2/lib/summernote/summernote.min.js.map
Normal file
1
public/js/v1.4.2/lib/summernote/summernote.min.js.map
Normal file
File diff suppressed because one or more lines are too long
@@ -49,7 +49,7 @@
|
||||
|
||||
<div class="col-sm-12 col-md-6">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12 col-xs-6 checkbox">
|
||||
<div class="col-xs-12 col-sm-12 col-xs-6 checkbox">
|
||||
<input id="{{deleteExpiredConnectionsId}}" name="deleteExpiredConnections" value="1" type="checkbox" {{#deleteExpiredConnections}}checked{{/deleteExpiredConnections}}>
|
||||
<label for="{{deleteExpiredConnectionsId}}">Auto delete outdated wormholes
|
||||
<i class="fas fa-fw fa-question-circle pf-help-light" title="outdated WHs (~2 days)"></i>
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
<div class="col-sm-12 col-md-6">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12 col-xs-6 checkbox" >
|
||||
<div class="col-xs-12 col-sm-12 col-xs-6 checkbox" >
|
||||
<input id="{{deleteEolConnectionsId}}" name="deleteEolConnections" value="1" type="checkbox" {{#deleteEolConnections}}checked{{/deleteEolConnections}}>
|
||||
<label for="{{deleteEolConnectionsId}}">Auto delete expired wormholes
|
||||
<i class="fas fa-fw fa-question-circle pf-help-light" title="expired EOL WHs (~4h 15min)"></i>
|
||||
@@ -69,7 +69,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-6">
|
||||
<div class="col-xs-12 col-sm-12 col-md-6">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12 col-xs-6 checkbox">
|
||||
<input id="{{persistentAliasesId}}" name="persistentAliases" value="1" type="checkbox" {{#persistentAliases}}checked{{/persistentAliases}}>
|
||||
@@ -88,7 +88,7 @@
|
||||
|
||||
<div class="col-sm-12 col-md-6">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12 col-xs-6 checkbox">
|
||||
<div class="col-xs-12 col-sm-12 col-xs-6 checkbox">
|
||||
<input id="{{logHistoryId}}" name="logHistory" value="1" type="checkbox" {{#logHistory}}checked{{/logHistory}}>
|
||||
<label for="{{logHistoryId}}">Save map changes to logfile
|
||||
<i class="fas fa-fw fa-question-circle pf-help-light" title="Map changes will be stored in a log file"></i>
|
||||
@@ -99,7 +99,7 @@
|
||||
|
||||
<div class="col-sm-12 col-md-6">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12 col-xs-6 checkbox">
|
||||
<div class="col-xs-12 col-sm-12 col-xs-6 checkbox">
|
||||
<input id="{{logActivityId}}" name="logActivity" value="1" type="checkbox" {{#logActivity}}checked{{/logActivity}}>
|
||||
<label for="{{logActivityId}}">Store user statistics
|
||||
<i class="fas fa-fw fa-question-circle pf-help-light" title="Map changes will be tracked in order to generate user statistics"></i>
|
||||
|
||||
@@ -2,37 +2,40 @@
|
||||
<form role="form" class="form-horizontal">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-8">
|
||||
<div class="col-xs-9">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="form_system">System</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="input-group">
|
||||
<label for="form_system"></label>
|
||||
<select id="form_system" name="systemId" class="pf-select2 {{selectClass}}" data-error="Choose a valid system" required>
|
||||
<select id="form_system" name="systemId" class="pf-select2 {{systemSelectClass}}" data-error="Choose a valid system" required>
|
||||
{{#currentSystem}}
|
||||
<option value="{{id}}">{{name}}</option>
|
||||
{{/currentSystem}}
|
||||
</select>
|
||||
<span class="form-control-static fade" data-type="spinner">
|
||||
<i class="fas fa-fw fa-lg fa-spin fa-sync txt-color txt-color-grayLight"></i>
|
||||
</span>
|
||||
<span class="help-block with-errors">Search system name</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-4">
|
||||
<div class="col-xs-3">
|
||||
<div class="form-group" style="margin-bottom: 0;">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<div class="checkbox checkbox-primary">
|
||||
<input id="form_lock" name="locked" value="1" type="checkbox">
|
||||
<label for="form_lock">
|
||||
<input id="{{lockId}}" name="locked" value="1" type="checkbox">
|
||||
<label for="{{lockId}}">
|
||||
Lock system
|
||||
</label>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
|
||||
<div class="checkbox checkbox-primary">
|
||||
<input id="form_rally" name="rallyUpdated" value="1" type="checkbox">
|
||||
<label for="form_rally">
|
||||
<input id="{{rallyId}}" name="rallyUpdated" value="1" type="checkbox">
|
||||
<label for="{{rallyId}}">
|
||||
Rally point
|
||||
</label>
|
||||
<div class="help-block with-errors"></div>
|
||||
@@ -42,13 +45,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-8">
|
||||
<div class="col-xs-9">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="{{statusSelectId}}">Status</label>
|
||||
<div class="col-sm-6">
|
||||
<select name="statusId" id="{{statusSelectId}}" class="form-control {{select2Class}}">
|
||||
<select id="{{statusSelectId}}" name="statusId" class="form-control {{select2Class}}">
|
||||
{{#statusData}}
|
||||
<option value="{{id}}">{{text}}</option>
|
||||
{{/statusData}}
|
||||
@@ -58,5 +60,49 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{! system info -------------------------------------------------------- }}
|
||||
|
||||
<h4 class="pf-dynamic-area collapsed" data-toggle="collapse" data-target="#{{sectionInfoId}}" style="display: none;">
|
||||
System intel : <span id="{{sectionInfoStatusId}}"></span>
|
||||
<i class="fas fa-fw fa-question-circle pf-help-light" title="show persistent system data"></i>
|
||||
</h4>
|
||||
|
||||
<div id="{{sectionInfoId}}" class="collapse">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-9">
|
||||
<div class="form-group">
|
||||
<label class="col-xs-4 col-sm-2 control-label">Alias</label>
|
||||
<div class="col-xs-8 col-sm-10">
|
||||
<div class="controls">
|
||||
<div id="{{aliasId}}" class="form-control-static"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-3">
|
||||
<div id="{{createdId}}" class="well well-sm text-center" title="first create"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-9">
|
||||
<div class="form-group">
|
||||
<label class="col-xs-12 col-sm-2 control-label">Description</label>
|
||||
<div class="col-xs-12 col-sm-10">
|
||||
<div class="controls">
|
||||
<div id="{{descriptionId}}" class="form-control-static"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-3">
|
||||
<div id="{{updatedId}}" class="well well-sm text-center" title="last update/delete"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
@@ -1,49 +0,0 @@
|
||||
{{#tableData}}
|
||||
{{#killmails.length}}
|
||||
{{#checkRender}}
|
||||
<h5>{{label}} ago</h5>
|
||||
|
||||
<ul class="media-list {{systemKillboardListClass}}">
|
||||
{{#killmails}}
|
||||
{{#checkRender}}
|
||||
<li class="media {{systemKillboardListEntryClass}}">
|
||||
<a href="{{{zKillboardUrl}}}/kill/{{killmail_id}}/" target="_blank" rel="noopener">
|
||||
<img src="{{{ccpImageServerUrl}}}/Type/{{victim.ship_type_id}}_64.png" class="media-object pull-left {{systemKillboardListImgShip}}" title="killmail">
|
||||
</a>
|
||||
|
||||
<a href="{{{zKillboardUrl}}}/character/{{victim.character_id}}/" target="_blank" rel="noopener">
|
||||
<img src="{{{ccpImageServerUrl}}}/Character/{{victim.character_id}}_32.jpg" class="media-object pull-left {{systemKillboardListImgChar}}" title="pilot KB">
|
||||
</a>
|
||||
|
||||
<div class="media-body pull-right text-right">
|
||||
<h5 class="media-heading">
|
||||
<small>{{#dateFormat}}{{killmail_time}}{{/dateFormat}}</small>
|
||||
</h5>
|
||||
<h3 class="media-heading">
|
||||
<small class="txt-color txt-color-green">{{#iskFormat}}{{zkb.totalValue}}{{/iskFormat}}</small>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div class="media-body">
|
||||
<h5 class="media-heading">
|
||||
<a href="{{{zKillboardUrl}}}/corporation/{{victim.corporation_id}}/" title="corporation KB" target="_blank" rel="noopener">
|
||||
<img src="{{{ccpImageServerUrl}}}/Corporation/{{victim.corporation_id}}_32.png" class="{{systemKillboardListImgCorp}}">
|
||||
</a>
|
||||
</h5>
|
||||
{{#victim.alliance_id}}
|
||||
<h5 class="media-heading">
|
||||
<a href="{{{zKillboardUrl}}}/alliance/{{victim.alliance_id}}/" title="alliance KB" target="_blank" rel="noopener">
|
||||
<img src="{{{ccpImageServerUrl}}}/Alliance/{{victim.alliance_id}}_32.png" class="{{systemKillboardListImgAlly}}">
|
||||
</a>
|
||||
</h5>
|
||||
{{/victim.alliance_id}}
|
||||
</div>
|
||||
</li>
|
||||
{{#increaseCount}}{{/increaseCount}}
|
||||
{{/checkRender}}
|
||||
{{/killmails}}
|
||||
</ul>
|
||||
{{/checkRender}}
|
||||
{{/killmails.length}}
|
||||
{{/tableData}}
|
||||
|
||||
40
public/templates/modules/killmail.html
Normal file
40
public/templates/modules/killmail.html
Normal file
@@ -0,0 +1,40 @@
|
||||
<li class="media {{systemKillboardListEntryClass}}">
|
||||
<a href="{{{zKillboardUrl}}}/kill/{{killmail.killmail_id}}/" target="_blank" rel="noopener">
|
||||
<img src="{{{ccpImageServerUrl}}}/Type/{{killmail.victim.ship_type_id}}_64.png" class="media-object pull-left {{systemKillboardListImgShip}}" title="killmail">
|
||||
</a>
|
||||
|
||||
{{#killmail.victim.character_id}}
|
||||
<a href="{{{zKillboardUrl}}}/character/{{killmail.victim.character_id}}/" target="_blank" rel="noopener">
|
||||
<img src="{{{ccpImageServerUrl}}}/Character/{{killmail.victim.character_id}}_32.jpg" class="media-object pull-left {{systemKillboardListImgChar}}" title="pilot KB">
|
||||
</a>
|
||||
{{/killmail.victim.character_id}}
|
||||
{{^killmail.victim.character_id}}
|
||||
<a href="{{{zKillboardUrl}}}/corporation/{{killmail.victim.corporation_id}}/" target="_blank" rel="noopener">
|
||||
<img src="{{{ccpImageServerUrl}}}/Corporation/{{killmail.victim.corporation_id}}_32.jpg" class="media-object pull-left {{systemKillboardListImgChar}}" title="corporation KB">
|
||||
</a>
|
||||
{{/killmail.victim.character_id}}
|
||||
|
||||
<div class="media-body pull-right text-right">
|
||||
<h5 class="media-heading">
|
||||
<small>{{#dateFormat}}{{killmail.killmail_time}}{{/dateFormat}}</small>
|
||||
</h5>
|
||||
<h3 class="media-heading">
|
||||
<small class="txt-color txt-color-green">{{#iskFormat}}{{zkb.totalValue}}{{/iskFormat}}</small>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div class="media-body">
|
||||
<h5 class="media-heading">
|
||||
<a href="{{{zKillboardUrl}}}/corporation/{{killmail.victim.corporation_id}}/" title="corporation KB" target="_blank" rel="noopener">
|
||||
<img src="{{{ccpImageServerUrl}}}/Corporation/{{killmail.victim.corporation_id}}_32.png" class="{{systemKillboardListImgCorp}}">
|
||||
</a>
|
||||
</h5>
|
||||
{{#killmail.victim.alliance_id}}
|
||||
<h5 class="media-heading">
|
||||
<a href="{{{zKillboardUrl}}}/alliance/{{killmail.victim.alliance_id}}/" title="alliance KB" target="_blank" rel="noopener">
|
||||
<img src="{{{ccpImageServerUrl}}}/Alliance/{{killmail.victim.alliance_id}}_32.png" class="{{systemKillboardListImgAlly}}">
|
||||
</a>
|
||||
</h5>
|
||||
{{/killmail.victim.alliance_id}}
|
||||
</div>
|
||||
</li>
|
||||
@@ -36,18 +36,15 @@
|
||||
<div class="row">
|
||||
|
||||
{{! info text ================================================================================================ }}
|
||||
<div class="col-xs-12 col-sm-7">
|
||||
<div class="pf-dynamic-area pf-system-info-description-area">
|
||||
<div class="col-xs-12 col-sm-9">
|
||||
<div class="pf-dynamic-area {{descriptionAreaClass}}">
|
||||
<div class="{{descriptionTextareaClass}}"></div>
|
||||
<i class="fas fa-fw fa-lg fa-pen pull-right {{moduleHeadlineIconClass}} {{descriptionButtonClass}}" data-toggle="tooltip" title="edit description"></i>
|
||||
|
||||
<div class="{{tableToolsActionClass}}">
|
||||
<a href="#" class="{{descriptionTextareaClass}}"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{! info table ================================================================================================ }}
|
||||
<div class="col-xs-12 col-sm-5">
|
||||
<div class="col-xs-12 col-sm-3">
|
||||
|
||||
<span data-toggle="tooltip" title="status" data-status="{{systemStatusId}}" class="label center-block {{statusInfoClass}} {{systemStatusClass}}">
|
||||
{{systemStatusLabel}}
|
||||
@@ -59,7 +56,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th class="text-right">
|
||||
<th class="text-right pf-system-info-name-cell">
|
||||
{{#system.shattered}}
|
||||
<i class="fas fa-fw fa-skull {{shatteredClass}}" data-toggle="tooltip" title="shattered"></i>
|
||||
{{/system.shattered}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div id="{{id}}" class="alert alert-warning">
|
||||
<div class="ui-pnotify-icon"><span class="fas fa-exclamation fa-fw fa-lg"></span></div>
|
||||
<h4 class="ui-pnotify-title">Scheduled maintenance: Update v1.4.0 <i class="fas fa-long-arrow-alt-right"></i> v1.4.1; Shutdown: ~15:30 (UTC). ETA ~15:45 (UTC)</h4>
|
||||
<h4 class="ui-pnotify-title">Scheduled maintenance: Update v1.4.1 <i class="fas fa-long-arrow-alt-right"></i> v1.4.2; Shutdown: ~17:45 (UTC). ETA ~18:00 (UTC)</h4>
|
||||
</div>
|
||||
|
||||
@@ -7,21 +7,13 @@
|
||||
<div class="panel-body no-padding text-align-center">
|
||||
<div class="price-features" style="min-height: inherit;">
|
||||
<ul class="list-unstyled text-left">
|
||||
<li>
|
||||
<i class="fas fa-fw fa-angle-right"></i>Signature module: New filter <a target="_blank" href="//github.com/exodus4d/pathfinder/issues/376" rel="noopener">#376</a>,
|
||||
keyboard navigation <a target="_blank" href="//github.com/exodus4d/pathfinder/issues/266" rel="noopener">#266</a>,
|
||||
UI changes <a target="_blank" href="//github.com/exodus4d/pathfinder/issues/679" rel="noopener">#679</a>,
|
||||
tooltips <a target="_blank" href="//github.com/exodus4d/pathfinder/issues/390" rel="noopener">#390</a>,
|
||||
layout <a target="_blank" href="//github.com/exodus4d/pathfinder/issues/629" rel="noopener">#629</a>
|
||||
<li><i class="fas fa-fw fa-angle-right"></i>New HTML editor for system description <a target="_blank" href="//github.com/exodus4d/pathfinder/issues/698" rel="noopener">#698</a></li>
|
||||
<li><i class="fas fa-fw fa-angle-right"></i>New preview data section added to "new system" dialog <a target="_blank" href="//github.com/exodus4d/pathfinder/issues/662" rel="noopener">#662</a></li>
|
||||
<li><i class="fas fa-fw fa-angle-right"></i>Fixed bugs with the signature table
|
||||
<a target="_blank" href="//github.com/exodus4d/pathfinder/issues/690" rel="noopener">#690</a>,
|
||||
<a target="_blank" href="//github.com/exodus4d/pathfinder/issues/691" rel="noopener">#691</a>
|
||||
</li>
|
||||
<li><i class="fas fa-fw fa-angle-right"></i>"Rally point and "route search" improvements <a target="_blank" href="//github.com/exodus4d/pathfinder/issues/664" rel="noopener">#664</a></li>
|
||||
<li><i class="fas fa-fw fa-angle-right"></i>Unique system URLs (e.g. in <em>Discord/Slack</em> messages) <a target="_blank" href="//github.com/exodus4d/pathfinder/issues/682" rel="noopener">#682</a></li>
|
||||
<li><i class="fas fa-fw fa-angle-right"></i>Improved "planet" information <a target="_blank" href="//github.com/exodus4d/pathfinder/issues/684" rel="noopener">#684</a></li>
|
||||
<li>
|
||||
<i class="fas fa-fw fa-angle-right"></i>Performance improvements <a target="_blank" href="//github.com/exodus4d/pathfinder/issues/685" rel="noopener">#685</a>,
|
||||
<a target="_blank" href="//github.com/exodus4d/pathfinder/issues/686" rel="noopener">#686</a>
|
||||
</li>
|
||||
<li><i class="fas fa-fw fa-angle-double-right"></i>Many more improvements/fixes and performance optimizations. Complete <a href="javascript:void(0)" class="pf-navbar-version-info">changelog</a></li>
|
||||
<li><i class="fas fa-fw fa-angle-double-right"></i>Many more improvements/fixes. Complete <a href="javascript:void(0)" class="pf-navbar-version-info">changelog</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -38,7 +38,7 @@ $red-darker: #a52521;
|
||||
$red-darkest: #58100d;
|
||||
|
||||
// indigo
|
||||
$indigo-light: #9fa8da;
|
||||
$indigo-light: #9fa8da;
|
||||
$indigo: #7986cb;
|
||||
$indigo-dark: #5c6bc0;
|
||||
$indigo-darkest: #313966;
|
||||
|
||||
@@ -969,17 +969,17 @@ input[type="email"]{
|
||||
|
||||
.dropdown-submenu>a {
|
||||
&:after{
|
||||
display: block;
|
||||
content: " ";
|
||||
float: right;
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 7px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-color: transparent;
|
||||
border-style: solid;
|
||||
border-width: 5px 0 5px 5px;
|
||||
border-left-color: $gray-darker;
|
||||
margin-top: 4px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
&:hover{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user