- added "lazy update" (ctrl + v) for "intel module", closed #246
- fixed JS bug where signature sync (client side update) failed
This commit is contained in:
@@ -20,30 +20,61 @@ class Structure extends Controller\AccessController {
|
||||
* @throws Exception
|
||||
*/
|
||||
public function save(\Base $f3){
|
||||
$structureData = (array)$f3->get('POST');
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
$requestData = (array)$f3->get('POST');
|
||||
$structuresData = (array)$requestData['structures'];
|
||||
$return = (object) [];
|
||||
$return->error = [];
|
||||
|
||||
/**
|
||||
* @var $structure Model\StructureModel
|
||||
*/
|
||||
$structure = Model\BasicModel::getNew('StructureModel');
|
||||
$structure->getById((int)$structureData['id']);
|
||||
if($structuresData){
|
||||
$activeCharacter = $this->getCharacter();
|
||||
|
||||
if($structure->dry() || $structure->hasAccess($activeCharacter)){
|
||||
$newStructure = $structure->dry();
|
||||
try{
|
||||
$structure->copyfrom($structureData, ['structureId', 'corporationId', 'systemId', 'statusId', 'name', 'description']);
|
||||
$structure->save();
|
||||
if($activeCharacter->hasCorporation()){
|
||||
// structures always belong to a corporation
|
||||
/**
|
||||
* @var $structure Model\StructureModel
|
||||
*/
|
||||
$structure = Model\BasicModel::getNew('StructureModel');
|
||||
foreach ($structuresData as $structureData){
|
||||
// reset on loop start because of potential "continue"
|
||||
$structure->reset();
|
||||
|
||||
if($newStructure){
|
||||
$activeCharacter->getCorporation()->saveStructure($structure);
|
||||
if(!empty($structureData['id']) && $structureId = (int)$structureData['id']){
|
||||
// update specific structure
|
||||
$structure->getById($structureId);
|
||||
if( !$structure->hasAccess($activeCharacter) ){
|
||||
continue;
|
||||
}
|
||||
}elseif( !isset($structureData['id']) ){
|
||||
// from clipboard -> search by structure by name
|
||||
$structure->getByName($activeCharacter->getCorporation(), (string)$structureData['name']);
|
||||
}
|
||||
|
||||
$newStructure = $structure->dry();
|
||||
|
||||
try{
|
||||
$structure->copyfrom($structureData, ['structureId', 'corporationId', 'systemId', 'statusId', 'name', 'description']);
|
||||
$structure->save();
|
||||
|
||||
if($newStructure){
|
||||
$activeCharacter->getCorporation()->saveStructure($structure);
|
||||
}
|
||||
|
||||
// group all updated structures by corporation -> just for return
|
||||
$corporationsStructureData = $structure->getDataByCorporations();
|
||||
foreach($corporationsStructureData as $corporationId => $corporationStructureData){
|
||||
if(isset($return->structures[$corporationId])){
|
||||
$return->structures[$corporationId]['structures'] = array_merge(
|
||||
$return->structures[$corporationId]['structures'],
|
||||
$corporationStructureData['structures']
|
||||
);
|
||||
}else{
|
||||
$return->structures[$corporationId] = $corporationStructureData;
|
||||
}
|
||||
}
|
||||
}catch(Exception\ValidationException $e){
|
||||
$return->error[] = $e->getError();
|
||||
}
|
||||
}
|
||||
$return->structures = $structure->getDataByCorporations();
|
||||
}catch(Exception\ValidationException $e){
|
||||
$return->error[] = $e->getError();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ class StructureModel extends BasicModel {
|
||||
],
|
||||
'statusId' => [
|
||||
'type' => Schema::DT_INT,
|
||||
'default' => 1,
|
||||
'index' => true,
|
||||
'belongs-to-one' => 'Model\StructureStatusModel',
|
||||
'constraint' => [
|
||||
@@ -159,6 +160,33 @@ class StructureModel extends BasicModel {
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether this model is valid or not
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid(): bool {
|
||||
if($valid = parent::isValid()){
|
||||
// structure always belongs to a systemId
|
||||
if(!(int)$this->systemId){
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event "Hook" function
|
||||
* can be overwritten
|
||||
* return false will stop any further action
|
||||
* @param BasicModel $self
|
||||
* @param $pkeys
|
||||
* @return bool
|
||||
*/
|
||||
public function beforeInsertEvent($self, $pkeys){
|
||||
return $this->isValid() ? parent::beforeInsertEvent($self, $pkeys) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* check access by chraacter
|
||||
* @param CharacterModel $characterModel
|
||||
@@ -166,9 +194,7 @@ class StructureModel extends BasicModel {
|
||||
*/
|
||||
public function hasAccess(CharacterModel $characterModel) : bool {
|
||||
$access = false;
|
||||
if($this->dry()){
|
||||
$access = true;
|
||||
}elseif($characterModel->hasCorporation()){
|
||||
if($characterModel->hasCorporation()){
|
||||
$this->filter('structureCorporations', ['active = ?', 1]);
|
||||
$this->has('structureCorporations.corporationId', ['active = ?', 1]);
|
||||
$this->has('structureCorporations.corporationId', ['id = ?', $characterModel->get('corporationId', true)]);
|
||||
@@ -201,6 +227,16 @@ class StructureModel extends BasicModel {
|
||||
return $structuresData;
|
||||
}
|
||||
|
||||
public function getByName(CorporationModel $corporation, string $name) {
|
||||
if( !$corporation->dry() && $name){
|
||||
$this->has('structureCorporations', ['corporationId = :corporationId', ':corporationId' => $corporation->_id]);
|
||||
$this->load(['name = :name AND active = :active',
|
||||
':name' => $name,
|
||||
':active' => 1
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get universe type data for structureId
|
||||
* @param int $structureId
|
||||
|
||||
@@ -25,11 +25,11 @@ define([
|
||||
label: 'Reload tab',
|
||||
keyNames: ['CONTROL', 'R']
|
||||
},
|
||||
signaturePaste: {
|
||||
clipboardPaste: {
|
||||
group: 'global',
|
||||
label: 'Paste signatures from clipboard',
|
||||
label: 'Update signatures/D-Scan from clipboard',
|
||||
keyNames: ['CONTROL', 'V'],
|
||||
alias: 'paste'
|
||||
alias: 'paste'
|
||||
},
|
||||
|
||||
// map ----------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -69,7 +69,8 @@ define([
|
||||
dynamicElementWrapperId: 'pf-dialog-wrapper',
|
||||
|
||||
// system signature module
|
||||
systemSigModuleClass: 'pf-sig-table-module', // module wrapper (signatures)
|
||||
systemSignatureModuleClass: 'pf-signature-table-module', // module wrapper (signatures)
|
||||
systemIntelModuleClass: 'pf-system-intel-module', // module wrapper (intel)
|
||||
};
|
||||
|
||||
let programStatusCounter = 0; // current count down in s until next status change is possible
|
||||
@@ -137,13 +138,18 @@ define([
|
||||
location.reload();
|
||||
});
|
||||
|
||||
body.watchKey('signaturePaste', (e) => {
|
||||
body.watchKey('clipboardPaste', (e) => {
|
||||
// just send event to the current active map
|
||||
let activeMap = Util.getMapModule().getActiveMap();
|
||||
if(activeMap){
|
||||
// look for active signature module (active system)
|
||||
let signatureModuleElement = MapUtil.getTabContentElementByMapElement(activeMap).find('.' + config.systemSigModuleClass);
|
||||
if(signatureModuleElement.length){
|
||||
let mapContentElement = MapUtil.getTabContentElementByMapElement(activeMap);
|
||||
let signatureModuleElement = mapContentElement.find('.' + config.systemSignatureModuleClass);
|
||||
let intelModuleElement = mapContentElement.find('.' + config.systemIntelModuleClass);
|
||||
if(
|
||||
signatureModuleElement.length ||
|
||||
intelModuleElement.length
|
||||
){
|
||||
e = e.originalEvent;
|
||||
let targetElement = $(e.target);
|
||||
// do not read clipboard if pasting into form elements
|
||||
@@ -155,6 +161,7 @@ define([
|
||||
){
|
||||
let clipboard = (e.originalEvent || e).clipboardData.getData('text/plain');
|
||||
signatureModuleElement.trigger('pf:updateSystemSignatureModuleByClipboard', [clipboard]);
|
||||
intelModuleElement.trigger('pf:updateIntelModuleByClipboard', [clipboard]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ define([
|
||||
// headline toolbar
|
||||
moduleHeadlineIconClass: 'pf-module-icon-button', // class for toolbar icons in the head
|
||||
moduleHeadlineIconAddClass: 'pf-module-icon-button-add', // class for "add structure" icon
|
||||
moduleHeadlineIconReaderClass: 'pf-module-icon-button-reader', // class for "dScan reader" icon
|
||||
moduleHeadlineIconRefreshClass: 'pf-module-icon-button-refresh', // class for "refresh" icon
|
||||
|
||||
// system intel module
|
||||
@@ -28,6 +29,7 @@ define([
|
||||
|
||||
// structure dialog
|
||||
structureDialogId: 'pf-structure-dialog', // id for "structure" dialog
|
||||
statusSelectId: 'pf-structure-dialog-status-select', // id for "status" select
|
||||
typeSelectId: 'pf-structure-dialog-type-select', // id for "type" select
|
||||
corporationSelectId: 'pf-structure-dialog-corporation-select', // id for "corporation" select
|
||||
descriptionTextareaId: 'pf-structure-dialog-description-textarea', // id for "description" textarea
|
||||
@@ -79,6 +81,13 @@ define([
|
||||
*/
|
||||
let callbackUpdateStructureRows = (context, systemData) => {
|
||||
let touchedRows = [];
|
||||
let hadData = context.tableApi.rows().any();
|
||||
let notificationCounter = {
|
||||
added: 0,
|
||||
changed: 0,
|
||||
deleted: 0
|
||||
};
|
||||
|
||||
if(systemData){
|
||||
let corporations = Util.getObjVal(systemData, 'structures');
|
||||
if(corporations) {
|
||||
@@ -99,6 +108,7 @@ define([
|
||||
api.nodes().to$().data('animationStatus', 'changed').destroyTimestampCounter();
|
||||
|
||||
touchedRows.push(api.id());
|
||||
notificationCounter.changed++;
|
||||
}else{
|
||||
// insert new row
|
||||
//context.tableApi.row.add(structureData).nodes().to$().data('animationStatus', 'added');
|
||||
@@ -106,6 +116,7 @@ define([
|
||||
api.nodes().to$().data('animationStatus', 'added');
|
||||
|
||||
touchedRows.push(api.id());
|
||||
notificationCounter.added++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,10 +125,20 @@ define([
|
||||
}
|
||||
|
||||
if(context.removeMissing){
|
||||
context.tableApi.rows((idx, data, node) => !touchedRows.includes(node.id)).remove();
|
||||
notificationCounter.deleted += context.tableApi.rows((idx, data, node) => !touchedRows.includes(node.id)).remove().ids().count();
|
||||
}
|
||||
|
||||
context.tableApi.draw();
|
||||
|
||||
// show notification ------------------------------------------------------------------------------------------
|
||||
let notification = '';
|
||||
notification += notificationCounter.added > 0 ? notificationCounter.added + ' added<br>' : '';
|
||||
notification += notificationCounter.changed > 0 ? notificationCounter.changed + ' changed<br>' : '';
|
||||
notification += notificationCounter.deleted > 0 ? notificationCounter.deleted + ' deleted<br>' : '';
|
||||
|
||||
if(hadData && notification.length){
|
||||
Util.showNotify({title: 'Structures updated', text: notification, type: 'success'});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -127,14 +148,20 @@ define([
|
||||
*/
|
||||
let callbackDeleteStructures = (context, responseData) => {
|
||||
let structureIds = Util.getObjVal(responseData, 'deletedStructureIds');
|
||||
let deletedCounter = 0;
|
||||
if(structureIds && structureIds.length){
|
||||
for(let structureId of structureIds){
|
||||
let rowId = getRowId(context.tableApi, structureId);
|
||||
if(rowId){
|
||||
context.tableApi.row('#' + rowId).remove();
|
||||
deletedCounter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(deletedCounter){
|
||||
context.tableApi.draw();
|
||||
Util.showNotify({title: 'Structure deleted', text: deletedCounter + ' deleted', type: 'success'});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -215,6 +242,7 @@ define([
|
||||
data.selected = data.id === Util.getObjVal(structureData, 'status.id');
|
||||
return data;
|
||||
}),
|
||||
statusSelectId: config.statusSelectId,
|
||||
typeSelectId: config.typeSelectId,
|
||||
corporationSelectId: config.corporationSelectId,
|
||||
descriptionTextareaId: config.descriptionTextareaId,
|
||||
@@ -254,7 +282,9 @@ define([
|
||||
formData.corporationId = Util.getObjVal(formData, 'corporationId') | 0;
|
||||
formData.systemId = systemId | 0;
|
||||
|
||||
saveStructureData(formData,{
|
||||
saveStructureData({
|
||||
structures: [formData]
|
||||
}, {
|
||||
moduleElement: moduleElement,
|
||||
tableApi: tableApi
|
||||
}, callbackUpdateStructureRows);
|
||||
@@ -282,6 +312,10 @@ define([
|
||||
maxSelectionLength: 1
|
||||
});
|
||||
|
||||
$(this).find('#' + config.statusSelectId).select2({
|
||||
minimumResultsForSearch: -1
|
||||
});
|
||||
|
||||
// init character counter
|
||||
let textarea = $(this).find('#' + config.descriptionTextareaId);
|
||||
let charCounter = $(this).find('.' + config.descriptionTextareaCharCounter);
|
||||
@@ -298,9 +332,53 @@ define([
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* show D-Scan reader dialog
|
||||
* @param moduleElement
|
||||
* @param tableApi
|
||||
* @param systemData
|
||||
*/
|
||||
let showDscanReaderDialog = (moduleElement, tableApi, systemData) => {
|
||||
requirejs(['text!templates/dialog/dscan_reader.html', 'mustache'], (template, Mustache) => {
|
||||
let structureDialog = bootbox.dialog({
|
||||
title: 'D-Scan reader',
|
||||
message: Mustache.render(template, {}),
|
||||
show: true,
|
||||
buttons: {
|
||||
close: {
|
||||
label: 'cancel',
|
||||
className: 'btn-default'
|
||||
},
|
||||
success: {
|
||||
label: '<i class="fas fa-fw fa-paste fa-fw"></i> update intel',
|
||||
className: 'btn-success',
|
||||
callback: function (){
|
||||
let form = this.find('form');
|
||||
let formData = form.getFormValues();
|
||||
|
||||
updateStructureTableByClipboard(systemData, formData.clipboard, {
|
||||
moduleElement: moduleElement,
|
||||
tableApi: tableApi
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// dialog shown event
|
||||
structureDialog.on('shown.bs.modal', function(e) {
|
||||
// set focus on textarea
|
||||
structureDialog.find('textarea').focus();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* get module element
|
||||
* @returns {*}
|
||||
* @param parentElement
|
||||
* @param mapId
|
||||
* @param systemData
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
let getModule = (parentElement, mapId, systemData) => {
|
||||
let corporationId = Util.getCurrentUserInfo('corporationId');
|
||||
@@ -320,6 +398,10 @@ define([
|
||||
class: ['fas', 'fa-fw', 'fa-plus', config.moduleHeadlineIconClass, config.moduleHeadlineIconAddClass].join(' '),
|
||||
title: 'add'
|
||||
}).attr('data-html', 'true').attr('data-toggle', 'tooltip'),
|
||||
$('<i>', {
|
||||
class: ['fas', 'fa-fw', 'fa-paste', config.moduleHeadlineIconClass, config.moduleHeadlineIconReaderClass].join(' '),
|
||||
title: 'D-Scan reader'
|
||||
}).attr('data-html', 'true').attr('data-toggle', 'tooltip'),
|
||||
$('<i>', {
|
||||
class: ['fas', 'fa-fw', 'fa-sync', config.moduleHeadlineIconClass, config.moduleHeadlineIconRefreshClass].join(' '),
|
||||
title: 'refresh all'
|
||||
@@ -388,8 +470,8 @@ define([
|
||||
}
|
||||
},{
|
||||
targets: 2,
|
||||
title: 'structure',
|
||||
width: 50,
|
||||
title: 'type',
|
||||
width: 30,
|
||||
className: [config.tableCellEllipsisClass].join(' '),
|
||||
data: 'structure.name',
|
||||
defaultContent: '<i class="fas fa-question txt-color txt-color-orangeDark"></i>',
|
||||
@@ -588,6 +670,76 @@ define([
|
||||
return moduleElement;
|
||||
};
|
||||
|
||||
/**
|
||||
* get universe typeIds for given categoryIds
|
||||
* @param categoryIds
|
||||
* @returns {Array}
|
||||
*/
|
||||
let getUniverseTypeIdsByCategoryIds = (categoryIds) => {
|
||||
let typeIds = [];
|
||||
let mapIds = type => type.id;
|
||||
for(let categoryId of categoryIds){
|
||||
let categoryData = Util.getObjVal(Init, 'universeCategories.' + categoryId);
|
||||
if(categoryData && categoryData.groups){
|
||||
for(let groupData of categoryData.groups){
|
||||
if(groupData && groupData.types){
|
||||
typeIds = typeIds.concat(groupData.types.map(mapIds));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return typeIds;
|
||||
};
|
||||
|
||||
/**
|
||||
* parse a copy&paste string from ingame dScan windows
|
||||
* @param systemData
|
||||
* @param clipboard
|
||||
* @returns {Array}
|
||||
*/
|
||||
let parseDscanString = (systemData, clipboard) => {
|
||||
let dScanData = [];
|
||||
let structureTypeIds = getUniverseTypeIdsByCategoryIds([65]);
|
||||
|
||||
if(clipboard.length){
|
||||
let dScanRows = clipboard.split(/\r\n|\r|\n/g);
|
||||
|
||||
for(let rowData of dScanRows){
|
||||
rowData = rowData.split(/\t/g);
|
||||
|
||||
if(rowData.length === 4){
|
||||
rowData[0] = parseInt(rowData[0]);
|
||||
// valid dScan result
|
||||
if(structureTypeIds.indexOf( rowData[0] ) !== -1){
|
||||
dScanData.push({
|
||||
structureId: rowData[0],
|
||||
name: rowData[1],
|
||||
systemId: systemData.systemId
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dScanData;
|
||||
};
|
||||
|
||||
/**
|
||||
* parse clipboard data for structures and update table
|
||||
* @param systemData
|
||||
* @param clipboard
|
||||
* @param context
|
||||
*/
|
||||
let updateStructureTableByClipboard = (systemData, clipboard, context) => {
|
||||
let structureData = parseDscanString(systemData, clipboard);
|
||||
if(structureData.length){
|
||||
saveStructureData({
|
||||
structures: structureData
|
||||
}, context, callbackUpdateStructureRows);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* init intel module
|
||||
* @param moduleElement
|
||||
@@ -604,6 +756,11 @@ define([
|
||||
showStructureDialog(moduleElement, tableApi, systemData.systemId);
|
||||
});
|
||||
|
||||
// init structure dialog --------------------------------------------------------------------------------------
|
||||
moduleElement.find('.' + config.moduleHeadlineIconReaderClass).on('click', function(e){
|
||||
showDscanReaderDialog(moduleElement, tableApi, systemData);
|
||||
});
|
||||
|
||||
// init refresh button ----------------------------------------------------------------------------------------
|
||||
moduleElement.find('.' + config.moduleHeadlineIconRefreshClass).on('click', function(e){
|
||||
getStructureData({
|
||||
@@ -615,6 +772,14 @@ define([
|
||||
removeMissing: true
|
||||
}, callbackAddStructureRows);
|
||||
});
|
||||
|
||||
// init listener for global "past" dScan into this page -------------------------------------------------------
|
||||
moduleElement.on('pf:updateIntelModuleByClipboard', function(e, clipboard){
|
||||
updateStructureTableByClipboard(systemData, clipboard, {
|
||||
moduleElement: moduleElement,
|
||||
tableApi: tableApi
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@@ -3,7 +3,7 @@ define([
|
||||
'app/init',
|
||||
'app/util',
|
||||
'morris'
|
||||
], function($, Init, Util, Morris) {
|
||||
], ($, Init, Util, Morris) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
@@ -38,7 +38,7 @@ define([
|
||||
* @param options
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
let getLabel = function(text, options){
|
||||
let getLabel = (text, options) => {
|
||||
let label = $('<span>', {
|
||||
class: ['label', options.type, options.align].join(' ')
|
||||
}).text( text );
|
||||
@@ -51,7 +51,7 @@ define([
|
||||
* @param moduleElement
|
||||
* @param killboardData
|
||||
*/
|
||||
let showKillmails = function(moduleElement, killboardData){
|
||||
let showKillmails = (moduleElement, killboardData) => {
|
||||
|
||||
// show number of killMails
|
||||
let killMailCounterMax = 20;
|
||||
@@ -389,7 +389,7 @@ define([
|
||||
* minify the killboard graph element e.g. if no kills where found, or on error
|
||||
* @param killboardGraphElement
|
||||
*/
|
||||
let minifyKillboardGraphElement = function(killboardGraphElement){
|
||||
let minifyKillboardGraphElement = (killboardGraphElement) => {
|
||||
killboardGraphElement.velocity({
|
||||
height: '20px',
|
||||
marginBottom: '0px'
|
||||
@@ -438,8 +438,9 @@ define([
|
||||
/**
|
||||
* get module element
|
||||
* @param parentElement
|
||||
* @param mapId
|
||||
* @param systemData
|
||||
* @returns {*|jQuery|HTMLElement}
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
let getModule = (parentElement, mapId, systemData) => {
|
||||
// create new module container
|
||||
|
||||
@@ -23,15 +23,12 @@ define([
|
||||
moduleClass: 'pf-module', // class for each module
|
||||
|
||||
// system signature module
|
||||
moduleTypeClass: 'pf-sig-table-module', // module wrapper
|
||||
moduleTypeClass: 'pf-signature-table-module', // module wrapper
|
||||
|
||||
// tables
|
||||
tableToolsClass: 'pf-table-tools', // class for table toolbar
|
||||
tableToolsActionClass: 'pf-table-tools-action', // class for table toolbar action
|
||||
|
||||
// dialogs
|
||||
signatureReaderDialogId: 'pf-signature-reader-dialog', // id for signature reader dialog
|
||||
|
||||
// signature progress bar
|
||||
signatureScannedProgressBarClass: 'pf-system-progress-scanned', // class for signature progress bar
|
||||
|
||||
@@ -340,10 +337,11 @@ define([
|
||||
// and add "new" row
|
||||
let changedRowElement = addSignatureRow(signatureTableApi, currentSystemData.systemData, signatureData[i], false);
|
||||
|
||||
// highlight
|
||||
changedRowElement.pulseTableRow('changed');
|
||||
|
||||
notificationCounter.changed++;
|
||||
if(changedRowElement){
|
||||
// highlight
|
||||
changedRowElement.pulseTableRow('changed');
|
||||
notificationCounter.changed++;
|
||||
}
|
||||
}
|
||||
|
||||
// remove signature data -> all left signatures will be added
|
||||
@@ -383,13 +381,13 @@ define([
|
||||
// and add "new" row
|
||||
let newRowElement = addSignatureRow(signatureTableApi, currentSystemData.systemData, signatureData[k], false);
|
||||
|
||||
// highlight
|
||||
newRowElement.pulseTableRow('added');
|
||||
|
||||
notificationCounter.added++;
|
||||
if(newRowElement){
|
||||
// highlight
|
||||
newRowElement.pulseTableRow('added');
|
||||
notificationCounter.added++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// show notification ------------------------------------------------------------------------------------------
|
||||
if(
|
||||
notificationCounter.added > 0 ||
|
||||
@@ -399,9 +397,8 @@ define([
|
||||
// update signature bar
|
||||
moduleElement.updateScannedSignaturesBar({showNotice: true});
|
||||
|
||||
// show Notification
|
||||
let notification = notificationCounter.added + ' added<br>';
|
||||
notification += notificationCounter.changed + ' changed<br>';
|
||||
notification += notificationCounter.changed + ' updated<br>';
|
||||
notification += notificationCounter.deleted + ' deleted<br>';
|
||||
Util.showNotify({title: 'Signatures updated', text: notification, type: 'success'});
|
||||
|
||||
@@ -499,7 +496,6 @@ define([
|
||||
Util.showNotify({title: 'System is scanned', text: notification, type: 'success'});
|
||||
}
|
||||
}
|
||||
|
||||
}, 100);
|
||||
};
|
||||
|
||||
@@ -508,36 +504,23 @@ define([
|
||||
* @param systemData
|
||||
*/
|
||||
$.fn.showSignatureReaderDialog = function(systemData){
|
||||
|
||||
let moduleElement = $(this);
|
||||
|
||||
let data = {
|
||||
id: config.signatureReaderDialogId
|
||||
};
|
||||
|
||||
requirejs(['text!templates/dialog/signature_reader.html', 'mustache'], function(template, Mustache) {
|
||||
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
requirejs(['text!templates/dialog/signature_reader.html', 'mustache'], (template, Mustache) => {
|
||||
let signatureReaderDialog = bootbox.dialog({
|
||||
title: 'Signature reader',
|
||||
message: content,
|
||||
message: Mustache.render(template, {}),
|
||||
buttons: {
|
||||
close: {
|
||||
label: 'cancel',
|
||||
className: 'btn-default',
|
||||
callback: function(){
|
||||
$(signatureReaderDialog).modal('hide');
|
||||
}
|
||||
className: 'btn-default'
|
||||
},
|
||||
success: {
|
||||
label: '<i class="fas fa-paste fa-fw"></i> update signatures',
|
||||
className: 'btn-success',
|
||||
callback: function () {
|
||||
// get form Values
|
||||
let form = $('#' + config.signatureReaderDialogId).find('form');
|
||||
let formData = $(form).getFormValues();
|
||||
|
||||
let form = this.find('form');
|
||||
let formData = form.getFormValues();
|
||||
let signatureOptions = {
|
||||
deleteOld: (formData.deleteOld) ? 1 : 0
|
||||
};
|
||||
@@ -554,8 +537,6 @@ define([
|
||||
// set focus on sig-input textarea
|
||||
signatureReaderDialog.find('textarea').focus();
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
@@ -607,10 +588,8 @@ define([
|
||||
|
||||
// check if copy&paste is enabled
|
||||
if( !disableCopyFromClipboard ){
|
||||
|
||||
// parse input stream
|
||||
let signatureData = parseSignatureString(systemData, clipboard);
|
||||
|
||||
if(signatureData.length > 0){
|
||||
// valid signature data parsed
|
||||
|
||||
@@ -641,7 +620,7 @@ define([
|
||||
};
|
||||
|
||||
/**
|
||||
* parses a copy&paste string from ingame scanning window and parses it
|
||||
* parses a copy&paste string from ingame scanning window
|
||||
* @param systemData
|
||||
* @param clipboard
|
||||
* @returns {Array}
|
||||
@@ -656,9 +635,7 @@ define([
|
||||
|
||||
for(let i = 0; i < signatureRows.length; i++){
|
||||
let rowData = signatureRows[i].split(/\t/g);
|
||||
|
||||
if(rowData.length === 6){
|
||||
|
||||
// check if sig Type = anomaly or combat site
|
||||
if(validSignatureNames.indexOf( rowData[1] ) !== -1){
|
||||
|
||||
@@ -702,8 +679,6 @@ define([
|
||||
}else{
|
||||
invalidSignatures++;
|
||||
}
|
||||
}else{
|
||||
invalidSignatures++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -875,7 +850,7 @@ define([
|
||||
* @param options
|
||||
* @returns {*|jQuery}
|
||||
*/
|
||||
let getLabledButton = function(options){
|
||||
let getLabeledButton = function(options){
|
||||
|
||||
let buttonClasses = ['btn', 'btn-sm', 'btn-labeled'];
|
||||
|
||||
@@ -1002,7 +977,7 @@ define([
|
||||
let tableToolbar = $('<div>', {
|
||||
class: config.tableToolsClass
|
||||
}).append(
|
||||
getLabledButton({
|
||||
getLabeledButton({
|
||||
type: 'primary',
|
||||
label: 'add',
|
||||
icon: 'fa-plus',
|
||||
@@ -1026,7 +1001,7 @@ define([
|
||||
}
|
||||
})
|
||||
).append(
|
||||
getLabledButton({
|
||||
getLabeledButton({
|
||||
type: 'primary',
|
||||
label: 'signature reader',
|
||||
icon: 'fa-paste',
|
||||
@@ -1035,7 +1010,7 @@ define([
|
||||
}
|
||||
})
|
||||
).append(
|
||||
getLabledButton({
|
||||
getLabeledButton({
|
||||
type: 'default',
|
||||
label: 'select all',
|
||||
icon: 'fa-check-square',
|
||||
@@ -1063,7 +1038,7 @@ define([
|
||||
value: 1,
|
||||
}).attr('data-toggle', 'toggle')
|
||||
).append(
|
||||
getLabledButton({
|
||||
getLabeledButton({
|
||||
type: 'danger',
|
||||
classes: [config.sigTableClearButtonClass, 'pull-right'],
|
||||
label: 'delete',
|
||||
@@ -1812,7 +1787,7 @@ define([
|
||||
// update connection conflicts
|
||||
checkConnectionConflicts();
|
||||
|
||||
Util.showNotify({title: 'Signature deleted', text: signatureCount + ' signatures deleted', type: 'success'});
|
||||
Util.showNotify({title: 'Signature deleted', text: signatureCount + ' deleted', type: 'success'});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1843,25 +1818,25 @@ define([
|
||||
* @param animate
|
||||
* @returns {*}
|
||||
*/
|
||||
let addSignatureRow = function(signatureTableApi, systemData, signatureData, animate){
|
||||
let newSignatureData = formatSignatureData(systemData, [signatureData], fullSignatureOptions);
|
||||
let addSignatureRow = (signatureTableApi, systemData, signatureData, animate) => {
|
||||
let newRowElement = null;
|
||||
if(signatureTableApi){
|
||||
let newSignatureData = formatSignatureData(systemData, [signatureData], fullSignatureOptions);
|
||||
let newRowNode = signatureTableApi.row.add(newSignatureData.shift()).draw().nodes();
|
||||
newRowElement = newRowNode.to$();
|
||||
|
||||
let newRowNode = signatureTableApi.row.add(newSignatureData.shift()).draw().nodes();
|
||||
let newRowElement = newRowNode.to$();
|
||||
|
||||
if(animate === true){
|
||||
newRowElement.hide();
|
||||
|
||||
newRowElement.toggleTableRow(function(newRowElement){
|
||||
// make new row editable
|
||||
if(animate === true){
|
||||
newRowElement.hide();
|
||||
newRowElement.toggleTableRow(newRowElement => {
|
||||
// make new row editable
|
||||
newRowElement.makeEditable(signatureTableApi, systemData);
|
||||
|
||||
// update scan progress bar
|
||||
newRowElement.parents('.' + config.moduleClass).updateScannedSignaturesBar({showNotice: true});
|
||||
});
|
||||
}else{
|
||||
newRowElement.makeEditable(signatureTableApi, systemData);
|
||||
|
||||
// update scan progress bar
|
||||
newRowElement.parents('.' + config.moduleClass).updateScannedSignaturesBar({showNotice: true});
|
||||
});
|
||||
}else{
|
||||
newRowElement.makeEditable(signatureTableApi, systemData);
|
||||
}
|
||||
}
|
||||
|
||||
return newRowElement;
|
||||
@@ -2270,20 +2245,22 @@ define([
|
||||
|
||||
let newRowElement = addSignatureRow(primaryTableApi, systemData, data.signatures[0], true);
|
||||
|
||||
// highlight
|
||||
newRowElement.pulseTableRow('added');
|
||||
if(newRowElement){
|
||||
// highlight
|
||||
newRowElement.pulseTableRow('added');
|
||||
|
||||
// prepare "add signature" table for new entry -> reset -------------------
|
||||
let signatureData = formatSignatureData(systemData, [emptySignatureData], emptySignatureOptions);
|
||||
let newAddRowElement = secondaryTableApi.clear().row.add(signatureData.shift()).draw().nodes();
|
||||
// prepare "add signature" table for new entry -> reset -------------------
|
||||
let signatureData = formatSignatureData(systemData, [emptySignatureData], emptySignatureOptions);
|
||||
let newAddRowElement = secondaryTableApi.clear().row.add(signatureData.shift()).draw().nodes();
|
||||
|
||||
newAddRowElement.to$().makeEditable(secondaryTableApi, systemData);
|
||||
newAddRowElement.to$().makeEditable(secondaryTableApi, systemData);
|
||||
|
||||
Util.showNotify({
|
||||
title: 'Signature added',
|
||||
text: 'Name: ' + data.name,
|
||||
type: 'success'
|
||||
});
|
||||
Util.showNotify({
|
||||
title: 'Signature added',
|
||||
text: 'Name: ' + data.name,
|
||||
type: 'success'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -25,11 +25,11 @@ define([
|
||||
label: 'Reload tab',
|
||||
keyNames: ['CONTROL', 'R']
|
||||
},
|
||||
signaturePaste: {
|
||||
clipboardPaste: {
|
||||
group: 'global',
|
||||
label: 'Paste signatures from clipboard',
|
||||
label: 'Update signatures/D-Scan from clipboard',
|
||||
keyNames: ['CONTROL', 'V'],
|
||||
alias: 'paste'
|
||||
alias: 'paste'
|
||||
},
|
||||
|
||||
// map ----------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -69,7 +69,8 @@ define([
|
||||
dynamicElementWrapperId: 'pf-dialog-wrapper',
|
||||
|
||||
// system signature module
|
||||
systemSigModuleClass: 'pf-sig-table-module', // module wrapper (signatures)
|
||||
systemSignatureModuleClass: 'pf-signature-table-module', // module wrapper (signatures)
|
||||
systemIntelModuleClass: 'pf-system-intel-module', // module wrapper (intel)
|
||||
};
|
||||
|
||||
let programStatusCounter = 0; // current count down in s until next status change is possible
|
||||
@@ -137,13 +138,18 @@ define([
|
||||
location.reload();
|
||||
});
|
||||
|
||||
body.watchKey('signaturePaste', (e) => {
|
||||
body.watchKey('clipboardPaste', (e) => {
|
||||
// just send event to the current active map
|
||||
let activeMap = Util.getMapModule().getActiveMap();
|
||||
if(activeMap){
|
||||
// look for active signature module (active system)
|
||||
let signatureModuleElement = MapUtil.getTabContentElementByMapElement(activeMap).find('.' + config.systemSigModuleClass);
|
||||
if(signatureModuleElement.length){
|
||||
let mapContentElement = MapUtil.getTabContentElementByMapElement(activeMap);
|
||||
let signatureModuleElement = mapContentElement.find('.' + config.systemSignatureModuleClass);
|
||||
let intelModuleElement = mapContentElement.find('.' + config.systemIntelModuleClass);
|
||||
if(
|
||||
signatureModuleElement.length ||
|
||||
intelModuleElement.length
|
||||
){
|
||||
e = e.originalEvent;
|
||||
let targetElement = $(e.target);
|
||||
// do not read clipboard if pasting into form elements
|
||||
@@ -155,6 +161,7 @@ define([
|
||||
){
|
||||
let clipboard = (e.originalEvent || e).clipboardData.getData('text/plain');
|
||||
signatureModuleElement.trigger('pf:updateSystemSignatureModuleByClipboard', [clipboard]);
|
||||
intelModuleElement.trigger('pf:updateIntelModuleByClipboard', [clipboard]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ define([
|
||||
// headline toolbar
|
||||
moduleHeadlineIconClass: 'pf-module-icon-button', // class for toolbar icons in the head
|
||||
moduleHeadlineIconAddClass: 'pf-module-icon-button-add', // class for "add structure" icon
|
||||
moduleHeadlineIconReaderClass: 'pf-module-icon-button-reader', // class for "dScan reader" icon
|
||||
moduleHeadlineIconRefreshClass: 'pf-module-icon-button-refresh', // class for "refresh" icon
|
||||
|
||||
// system intel module
|
||||
@@ -28,6 +29,7 @@ define([
|
||||
|
||||
// structure dialog
|
||||
structureDialogId: 'pf-structure-dialog', // id for "structure" dialog
|
||||
statusSelectId: 'pf-structure-dialog-status-select', // id for "status" select
|
||||
typeSelectId: 'pf-structure-dialog-type-select', // id for "type" select
|
||||
corporationSelectId: 'pf-structure-dialog-corporation-select', // id for "corporation" select
|
||||
descriptionTextareaId: 'pf-structure-dialog-description-textarea', // id for "description" textarea
|
||||
@@ -79,6 +81,13 @@ define([
|
||||
*/
|
||||
let callbackUpdateStructureRows = (context, systemData) => {
|
||||
let touchedRows = [];
|
||||
let hadData = context.tableApi.rows().any();
|
||||
let notificationCounter = {
|
||||
added: 0,
|
||||
changed: 0,
|
||||
deleted: 0
|
||||
};
|
||||
|
||||
if(systemData){
|
||||
let corporations = Util.getObjVal(systemData, 'structures');
|
||||
if(corporations) {
|
||||
@@ -99,6 +108,7 @@ define([
|
||||
api.nodes().to$().data('animationStatus', 'changed').destroyTimestampCounter();
|
||||
|
||||
touchedRows.push(api.id());
|
||||
notificationCounter.changed++;
|
||||
}else{
|
||||
// insert new row
|
||||
//context.tableApi.row.add(structureData).nodes().to$().data('animationStatus', 'added');
|
||||
@@ -106,20 +116,29 @@ define([
|
||||
api.nodes().to$().data('animationStatus', 'added');
|
||||
|
||||
touchedRows.push(api.id());
|
||||
notificationCounter.added++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(touchedRows)
|
||||
|
||||
|
||||
if(context.removeMissing){
|
||||
context.tableApi.rows((idx, data, node) => !touchedRows.includes(node.id)).remove();
|
||||
notificationCounter.deleted += context.tableApi.rows((idx, data, node) => !touchedRows.includes(node.id)).remove().ids().count();
|
||||
}
|
||||
|
||||
context.tableApi.draw();
|
||||
|
||||
// show notification ------------------------------------------------------------------------------------------
|
||||
let notification = '';
|
||||
notification += notificationCounter.added > 0 ? notificationCounter.added + ' added<br>' : '';
|
||||
notification += notificationCounter.changed > 0 ? notificationCounter.changed + ' changed<br>' : '';
|
||||
notification += notificationCounter.deleted > 0 ? notificationCounter.deleted + ' deleted<br>' : '';
|
||||
|
||||
if(hadData && notification.length){
|
||||
Util.showNotify({title: 'Structures updated', text: notification, type: 'success'});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -129,14 +148,20 @@ define([
|
||||
*/
|
||||
let callbackDeleteStructures = (context, responseData) => {
|
||||
let structureIds = Util.getObjVal(responseData, 'deletedStructureIds');
|
||||
let deletedCounter = 0;
|
||||
if(structureIds && structureIds.length){
|
||||
for(let structureId of structureIds){
|
||||
let rowId = getRowId(context.tableApi, structureId);
|
||||
if(rowId){
|
||||
context.tableApi.row('#' + rowId).remove();
|
||||
deletedCounter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(deletedCounter){
|
||||
context.tableApi.draw();
|
||||
Util.showNotify({title: 'Structure deleted', text: deletedCounter + ' deleted', type: 'success'});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -217,6 +242,7 @@ define([
|
||||
data.selected = data.id === Util.getObjVal(structureData, 'status.id');
|
||||
return data;
|
||||
}),
|
||||
statusSelectId: config.statusSelectId,
|
||||
typeSelectId: config.typeSelectId,
|
||||
corporationSelectId: config.corporationSelectId,
|
||||
descriptionTextareaId: config.descriptionTextareaId,
|
||||
@@ -256,7 +282,9 @@ define([
|
||||
formData.corporationId = Util.getObjVal(formData, 'corporationId') | 0;
|
||||
formData.systemId = systemId | 0;
|
||||
|
||||
saveStructureData(formData,{
|
||||
saveStructureData({
|
||||
structures: [formData]
|
||||
}, {
|
||||
moduleElement: moduleElement,
|
||||
tableApi: tableApi
|
||||
}, callbackUpdateStructureRows);
|
||||
@@ -284,6 +312,10 @@ define([
|
||||
maxSelectionLength: 1
|
||||
});
|
||||
|
||||
$(this).find('#' + config.statusSelectId).select2({
|
||||
minimumResultsForSearch: -1
|
||||
});
|
||||
|
||||
// init character counter
|
||||
let textarea = $(this).find('#' + config.descriptionTextareaId);
|
||||
let charCounter = $(this).find('.' + config.descriptionTextareaCharCounter);
|
||||
@@ -300,9 +332,53 @@ define([
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* show D-Scan reader dialog
|
||||
* @param moduleElement
|
||||
* @param tableApi
|
||||
* @param systemData
|
||||
*/
|
||||
let showDscanReaderDialog = (moduleElement, tableApi, systemData) => {
|
||||
requirejs(['text!templates/dialog/dscan_reader.html', 'mustache'], (template, Mustache) => {
|
||||
let structureDialog = bootbox.dialog({
|
||||
title: 'D-Scan reader',
|
||||
message: Mustache.render(template, {}),
|
||||
show: true,
|
||||
buttons: {
|
||||
close: {
|
||||
label: 'cancel',
|
||||
className: 'btn-default'
|
||||
},
|
||||
success: {
|
||||
label: '<i class="fas fa-fw fa-paste fa-fw"></i> update intel',
|
||||
className: 'btn-success',
|
||||
callback: function (){
|
||||
let form = this.find('form');
|
||||
let formData = form.getFormValues();
|
||||
|
||||
updateStructureTableByClipboard(systemData, formData.clipboard, {
|
||||
moduleElement: moduleElement,
|
||||
tableApi: tableApi
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// dialog shown event
|
||||
structureDialog.on('shown.bs.modal', function(e) {
|
||||
// set focus on textarea
|
||||
structureDialog.find('textarea').focus();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* get module element
|
||||
* @returns {*}
|
||||
* @param parentElement
|
||||
* @param mapId
|
||||
* @param systemData
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
let getModule = (parentElement, mapId, systemData) => {
|
||||
let corporationId = Util.getCurrentUserInfo('corporationId');
|
||||
@@ -322,6 +398,10 @@ define([
|
||||
class: ['fas', 'fa-fw', 'fa-plus', config.moduleHeadlineIconClass, config.moduleHeadlineIconAddClass].join(' '),
|
||||
title: 'add'
|
||||
}).attr('data-html', 'true').attr('data-toggle', 'tooltip'),
|
||||
$('<i>', {
|
||||
class: ['fas', 'fa-fw', 'fa-paste', config.moduleHeadlineIconClass, config.moduleHeadlineIconReaderClass].join(' '),
|
||||
title: 'D-Scan reader'
|
||||
}).attr('data-html', 'true').attr('data-toggle', 'tooltip'),
|
||||
$('<i>', {
|
||||
class: ['fas', 'fa-fw', 'fa-sync', config.moduleHeadlineIconClass, config.moduleHeadlineIconRefreshClass].join(' '),
|
||||
title: 'refresh all'
|
||||
@@ -390,8 +470,8 @@ define([
|
||||
}
|
||||
},{
|
||||
targets: 2,
|
||||
title: 'structure',
|
||||
width: 50,
|
||||
title: 'type',
|
||||
width: 30,
|
||||
className: [config.tableCellEllipsisClass].join(' '),
|
||||
data: 'structure.name',
|
||||
defaultContent: '<i class="fas fa-question txt-color txt-color-orangeDark"></i>',
|
||||
@@ -590,6 +670,76 @@ define([
|
||||
return moduleElement;
|
||||
};
|
||||
|
||||
/**
|
||||
* get universe typeIds for given categoryIds
|
||||
* @param categoryIds
|
||||
* @returns {Array}
|
||||
*/
|
||||
let getUniverseTypeIdsByCategoryIds = (categoryIds) => {
|
||||
let typeIds = [];
|
||||
let mapIds = type => type.id;
|
||||
for(let categoryId of categoryIds){
|
||||
let categoryData = Util.getObjVal(Init, 'universeCategories.' + categoryId);
|
||||
if(categoryData && categoryData.groups){
|
||||
for(let groupData of categoryData.groups){
|
||||
if(groupData && groupData.types){
|
||||
typeIds = typeIds.concat(groupData.types.map(mapIds));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return typeIds;
|
||||
};
|
||||
|
||||
/**
|
||||
* parse a copy&paste string from ingame dScan windows
|
||||
* @param systemData
|
||||
* @param clipboard
|
||||
* @returns {Array}
|
||||
*/
|
||||
let parseDscanString = (systemData, clipboard) => {
|
||||
let dScanData = [];
|
||||
let structureTypeIds = getUniverseTypeIdsByCategoryIds([65]);
|
||||
|
||||
if(clipboard.length){
|
||||
let dScanRows = clipboard.split(/\r\n|\r|\n/g);
|
||||
|
||||
for(let rowData of dScanRows){
|
||||
rowData = rowData.split(/\t/g);
|
||||
|
||||
if(rowData.length === 4){
|
||||
rowData[0] = parseInt(rowData[0]);
|
||||
// valid dScan result
|
||||
if(structureTypeIds.indexOf( rowData[0] ) !== -1){
|
||||
dScanData.push({
|
||||
structureId: rowData[0],
|
||||
name: rowData[1],
|
||||
systemId: systemData.systemId
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dScanData;
|
||||
};
|
||||
|
||||
/**
|
||||
* parse clipboard data for structures and update table
|
||||
* @param systemData
|
||||
* @param clipboard
|
||||
* @param context
|
||||
*/
|
||||
let updateStructureTableByClipboard = (systemData, clipboard, context) => {
|
||||
let structureData = parseDscanString(systemData, clipboard);
|
||||
if(structureData.length){
|
||||
saveStructureData({
|
||||
structures: structureData
|
||||
}, context, callbackUpdateStructureRows);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* init intel module
|
||||
* @param moduleElement
|
||||
@@ -606,6 +756,11 @@ define([
|
||||
showStructureDialog(moduleElement, tableApi, systemData.systemId);
|
||||
});
|
||||
|
||||
// init structure dialog --------------------------------------------------------------------------------------
|
||||
moduleElement.find('.' + config.moduleHeadlineIconReaderClass).on('click', function(e){
|
||||
showDscanReaderDialog(moduleElement, tableApi, systemData);
|
||||
});
|
||||
|
||||
// init refresh button ----------------------------------------------------------------------------------------
|
||||
moduleElement.find('.' + config.moduleHeadlineIconRefreshClass).on('click', function(e){
|
||||
getStructureData({
|
||||
@@ -617,6 +772,14 @@ define([
|
||||
removeMissing: true
|
||||
}, callbackAddStructureRows);
|
||||
});
|
||||
|
||||
// init listener for global "past" dScan into this page -------------------------------------------------------
|
||||
moduleElement.on('pf:updateIntelModuleByClipboard', function(e, clipboard){
|
||||
updateStructureTableByClipboard(systemData, clipboard, {
|
||||
moduleElement: moduleElement,
|
||||
tableApi: tableApi
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@@ -3,7 +3,7 @@ define([
|
||||
'app/init',
|
||||
'app/util',
|
||||
'morris'
|
||||
], function($, Init, Util, Morris) {
|
||||
], ($, Init, Util, Morris) => {
|
||||
'use strict';
|
||||
|
||||
let config = {
|
||||
@@ -38,7 +38,7 @@ define([
|
||||
* @param options
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
let getLabel = function(text, options){
|
||||
let getLabel = (text, options) => {
|
||||
let label = $('<span>', {
|
||||
class: ['label', options.type, options.align].join(' ')
|
||||
}).text( text );
|
||||
@@ -51,7 +51,7 @@ define([
|
||||
* @param moduleElement
|
||||
* @param killboardData
|
||||
*/
|
||||
let showKillmails = function(moduleElement, killboardData){
|
||||
let showKillmails = (moduleElement, killboardData) => {
|
||||
|
||||
// show number of killMails
|
||||
let killMailCounterMax = 20;
|
||||
@@ -389,7 +389,7 @@ define([
|
||||
* minify the killboard graph element e.g. if no kills where found, or on error
|
||||
* @param killboardGraphElement
|
||||
*/
|
||||
let minifyKillboardGraphElement = function(killboardGraphElement){
|
||||
let minifyKillboardGraphElement = (killboardGraphElement) => {
|
||||
killboardGraphElement.velocity({
|
||||
height: '20px',
|
||||
marginBottom: '0px'
|
||||
@@ -438,8 +438,9 @@ define([
|
||||
/**
|
||||
* get module element
|
||||
* @param parentElement
|
||||
* @param mapId
|
||||
* @param systemData
|
||||
* @returns {*|jQuery|HTMLElement}
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
let getModule = (parentElement, mapId, systemData) => {
|
||||
// create new module container
|
||||
|
||||
@@ -23,15 +23,12 @@ define([
|
||||
moduleClass: 'pf-module', // class for each module
|
||||
|
||||
// system signature module
|
||||
moduleTypeClass: 'pf-sig-table-module', // module wrapper
|
||||
moduleTypeClass: 'pf-signature-table-module', // module wrapper
|
||||
|
||||
// tables
|
||||
tableToolsClass: 'pf-table-tools', // class for table toolbar
|
||||
tableToolsActionClass: 'pf-table-tools-action', // class for table toolbar action
|
||||
|
||||
// dialogs
|
||||
signatureReaderDialogId: 'pf-signature-reader-dialog', // id for signature reader dialog
|
||||
|
||||
// signature progress bar
|
||||
signatureScannedProgressBarClass: 'pf-system-progress-scanned', // class for signature progress bar
|
||||
|
||||
@@ -340,10 +337,11 @@ define([
|
||||
// and add "new" row
|
||||
let changedRowElement = addSignatureRow(signatureTableApi, currentSystemData.systemData, signatureData[i], false);
|
||||
|
||||
// highlight
|
||||
changedRowElement.pulseTableRow('changed');
|
||||
|
||||
notificationCounter.changed++;
|
||||
if(changedRowElement){
|
||||
// highlight
|
||||
changedRowElement.pulseTableRow('changed');
|
||||
notificationCounter.changed++;
|
||||
}
|
||||
}
|
||||
|
||||
// remove signature data -> all left signatures will be added
|
||||
@@ -383,13 +381,13 @@ define([
|
||||
// and add "new" row
|
||||
let newRowElement = addSignatureRow(signatureTableApi, currentSystemData.systemData, signatureData[k], false);
|
||||
|
||||
// highlight
|
||||
newRowElement.pulseTableRow('added');
|
||||
|
||||
notificationCounter.added++;
|
||||
if(newRowElement){
|
||||
// highlight
|
||||
newRowElement.pulseTableRow('added');
|
||||
notificationCounter.added++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// show notification ------------------------------------------------------------------------------------------
|
||||
if(
|
||||
notificationCounter.added > 0 ||
|
||||
@@ -399,9 +397,8 @@ define([
|
||||
// update signature bar
|
||||
moduleElement.updateScannedSignaturesBar({showNotice: true});
|
||||
|
||||
// show Notification
|
||||
let notification = notificationCounter.added + ' added<br>';
|
||||
notification += notificationCounter.changed + ' changed<br>';
|
||||
notification += notificationCounter.changed + ' updated<br>';
|
||||
notification += notificationCounter.deleted + ' deleted<br>';
|
||||
Util.showNotify({title: 'Signatures updated', text: notification, type: 'success'});
|
||||
|
||||
@@ -499,7 +496,6 @@ define([
|
||||
Util.showNotify({title: 'System is scanned', text: notification, type: 'success'});
|
||||
}
|
||||
}
|
||||
|
||||
}, 100);
|
||||
};
|
||||
|
||||
@@ -508,36 +504,23 @@ define([
|
||||
* @param systemData
|
||||
*/
|
||||
$.fn.showSignatureReaderDialog = function(systemData){
|
||||
|
||||
let moduleElement = $(this);
|
||||
|
||||
let data = {
|
||||
id: config.signatureReaderDialogId
|
||||
};
|
||||
|
||||
requirejs(['text!templates/dialog/signature_reader.html', 'mustache'], function(template, Mustache) {
|
||||
|
||||
let content = Mustache.render(template, data);
|
||||
|
||||
requirejs(['text!templates/dialog/signature_reader.html', 'mustache'], (template, Mustache) => {
|
||||
let signatureReaderDialog = bootbox.dialog({
|
||||
title: 'Signature reader',
|
||||
message: content,
|
||||
message: Mustache.render(template, {}),
|
||||
buttons: {
|
||||
close: {
|
||||
label: 'cancel',
|
||||
className: 'btn-default',
|
||||
callback: function(){
|
||||
$(signatureReaderDialog).modal('hide');
|
||||
}
|
||||
className: 'btn-default'
|
||||
},
|
||||
success: {
|
||||
label: '<i class="fas fa-paste fa-fw"></i> update signatures',
|
||||
className: 'btn-success',
|
||||
callback: function () {
|
||||
// get form Values
|
||||
let form = $('#' + config.signatureReaderDialogId).find('form');
|
||||
let formData = $(form).getFormValues();
|
||||
|
||||
let form = this.find('form');
|
||||
let formData = form.getFormValues();
|
||||
let signatureOptions = {
|
||||
deleteOld: (formData.deleteOld) ? 1 : 0
|
||||
};
|
||||
@@ -554,8 +537,6 @@ define([
|
||||
// set focus on sig-input textarea
|
||||
signatureReaderDialog.find('textarea').focus();
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
@@ -607,10 +588,8 @@ define([
|
||||
|
||||
// check if copy&paste is enabled
|
||||
if( !disableCopyFromClipboard ){
|
||||
|
||||
// parse input stream
|
||||
let signatureData = parseSignatureString(systemData, clipboard);
|
||||
|
||||
if(signatureData.length > 0){
|
||||
// valid signature data parsed
|
||||
|
||||
@@ -641,7 +620,7 @@ define([
|
||||
};
|
||||
|
||||
/**
|
||||
* parses a copy&paste string from ingame scanning window and parses it
|
||||
* parses a copy&paste string from ingame scanning window
|
||||
* @param systemData
|
||||
* @param clipboard
|
||||
* @returns {Array}
|
||||
@@ -656,9 +635,7 @@ define([
|
||||
|
||||
for(let i = 0; i < signatureRows.length; i++){
|
||||
let rowData = signatureRows[i].split(/\t/g);
|
||||
|
||||
if(rowData.length === 6){
|
||||
|
||||
// check if sig Type = anomaly or combat site
|
||||
if(validSignatureNames.indexOf( rowData[1] ) !== -1){
|
||||
|
||||
@@ -702,8 +679,6 @@ define([
|
||||
}else{
|
||||
invalidSignatures++;
|
||||
}
|
||||
}else{
|
||||
invalidSignatures++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -875,7 +850,7 @@ define([
|
||||
* @param options
|
||||
* @returns {*|jQuery}
|
||||
*/
|
||||
let getLabledButton = function(options){
|
||||
let getLabeledButton = function(options){
|
||||
|
||||
let buttonClasses = ['btn', 'btn-sm', 'btn-labeled'];
|
||||
|
||||
@@ -1002,7 +977,7 @@ define([
|
||||
let tableToolbar = $('<div>', {
|
||||
class: config.tableToolsClass
|
||||
}).append(
|
||||
getLabledButton({
|
||||
getLabeledButton({
|
||||
type: 'primary',
|
||||
label: 'add',
|
||||
icon: 'fa-plus',
|
||||
@@ -1026,7 +1001,7 @@ define([
|
||||
}
|
||||
})
|
||||
).append(
|
||||
getLabledButton({
|
||||
getLabeledButton({
|
||||
type: 'primary',
|
||||
label: 'signature reader',
|
||||
icon: 'fa-paste',
|
||||
@@ -1035,7 +1010,7 @@ define([
|
||||
}
|
||||
})
|
||||
).append(
|
||||
getLabledButton({
|
||||
getLabeledButton({
|
||||
type: 'default',
|
||||
label: 'select all',
|
||||
icon: 'fa-check-square',
|
||||
@@ -1063,7 +1038,7 @@ define([
|
||||
value: 1,
|
||||
}).attr('data-toggle', 'toggle')
|
||||
).append(
|
||||
getLabledButton({
|
||||
getLabeledButton({
|
||||
type: 'danger',
|
||||
classes: [config.sigTableClearButtonClass, 'pull-right'],
|
||||
label: 'delete',
|
||||
@@ -1812,7 +1787,7 @@ define([
|
||||
// update connection conflicts
|
||||
checkConnectionConflicts();
|
||||
|
||||
Util.showNotify({title: 'Signature deleted', text: signatureCount + ' signatures deleted', type: 'success'});
|
||||
Util.showNotify({title: 'Signature deleted', text: signatureCount + ' deleted', type: 'success'});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1843,25 +1818,25 @@ define([
|
||||
* @param animate
|
||||
* @returns {*}
|
||||
*/
|
||||
let addSignatureRow = function(signatureTableApi, systemData, signatureData, animate){
|
||||
let newSignatureData = formatSignatureData(systemData, [signatureData], fullSignatureOptions);
|
||||
let addSignatureRow = (signatureTableApi, systemData, signatureData, animate) => {
|
||||
let newRowElement = null;
|
||||
if(signatureTableApi){
|
||||
let newSignatureData = formatSignatureData(systemData, [signatureData], fullSignatureOptions);
|
||||
let newRowNode = signatureTableApi.row.add(newSignatureData.shift()).draw().nodes();
|
||||
newRowElement = newRowNode.to$();
|
||||
|
||||
let newRowNode = signatureTableApi.row.add(newSignatureData.shift()).draw().nodes();
|
||||
let newRowElement = newRowNode.to$();
|
||||
|
||||
if(animate === true){
|
||||
newRowElement.hide();
|
||||
|
||||
newRowElement.toggleTableRow(function(newRowElement){
|
||||
// make new row editable
|
||||
if(animate === true){
|
||||
newRowElement.hide();
|
||||
newRowElement.toggleTableRow(newRowElement => {
|
||||
// make new row editable
|
||||
newRowElement.makeEditable(signatureTableApi, systemData);
|
||||
|
||||
// update scan progress bar
|
||||
newRowElement.parents('.' + config.moduleClass).updateScannedSignaturesBar({showNotice: true});
|
||||
});
|
||||
}else{
|
||||
newRowElement.makeEditable(signatureTableApi, systemData);
|
||||
|
||||
// update scan progress bar
|
||||
newRowElement.parents('.' + config.moduleClass).updateScannedSignaturesBar({showNotice: true});
|
||||
});
|
||||
}else{
|
||||
newRowElement.makeEditable(signatureTableApi, systemData);
|
||||
}
|
||||
}
|
||||
|
||||
return newRowElement;
|
||||
@@ -2270,20 +2245,22 @@ define([
|
||||
|
||||
let newRowElement = addSignatureRow(primaryTableApi, systemData, data.signatures[0], true);
|
||||
|
||||
// highlight
|
||||
newRowElement.pulseTableRow('added');
|
||||
if(newRowElement){
|
||||
// highlight
|
||||
newRowElement.pulseTableRow('added');
|
||||
|
||||
// prepare "add signature" table for new entry -> reset -------------------
|
||||
let signatureData = formatSignatureData(systemData, [emptySignatureData], emptySignatureOptions);
|
||||
let newAddRowElement = secondaryTableApi.clear().row.add(signatureData.shift()).draw().nodes();
|
||||
// prepare "add signature" table for new entry -> reset -------------------
|
||||
let signatureData = formatSignatureData(systemData, [emptySignatureData], emptySignatureOptions);
|
||||
let newAddRowElement = secondaryTableApi.clear().row.add(signatureData.shift()).draw().nodes();
|
||||
|
||||
newAddRowElement.to$().makeEditable(secondaryTableApi, systemData);
|
||||
newAddRowElement.to$().makeEditable(secondaryTableApi, systemData);
|
||||
|
||||
Util.showNotify({
|
||||
title: 'Signature added',
|
||||
text: 'Name: ' + data.name,
|
||||
type: 'success'
|
||||
});
|
||||
Util.showNotify({
|
||||
title: 'Signature added',
|
||||
text: 'Name: ' + data.name,
|
||||
type: 'success'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
16
public/templates/dialog/dscan_reader.html
Normal file
16
public/templates/dialog/dscan_reader.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<form role="form" class="form-horizontal">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="form-dscan">D-scan</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea style="resize: vertical" rows="3" id="form-dscan" name="clipboard" class="form-control custom-scroll" autofocus></textarea>
|
||||
<span class="help-block">
|
||||
Copy and paste D-Scan result. Press <kbd>ctrl</kbd> + <kbd>c</kbd> (copy)
|
||||
then <kbd>ctrl</kbd> + <kbd>v</kbd> (paste).<br> This tool can add and update structures.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -1,34 +1,30 @@
|
||||
<div id="{{id}}">
|
||||
<form role="form" class="form-horizontal">
|
||||
<form role="form" class="form-horizontal">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="form_result">Scan result</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea style="resize: vertical" rows="3" id="form_result" name="clipboard" class="form-control custom-scroll" autofocus></textarea>
|
||||
<span class="help-block">
|
||||
Copy and paste signatures from your probe scanning window.
|
||||
Hit <kbd>ctrl</kbd> + <kbd>c</kbd> (copy)
|
||||
then <kbd>ctrl</kbd> + <kbd>v</kbd> (paste). This tool can add and update signatures.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="form_result">Scan result</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea style="resize: vertical" rows="3" id="form_result" name="clipboard" class="form-control custom-scroll" autofocus></textarea>
|
||||
<span class="help-block">
|
||||
Copy and paste signatures from your probe scanning window.
|
||||
Hit <kbd>ctrl</kbd> + <kbd>c</kbd> (copy)
|
||||
then <kbd>ctrl</kbd> + <kbd>v</kbd> (paste). This tool can add and update signatures.
|
||||
</span>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10 col-xs-9">
|
||||
<div class="checkbox checkbox-warning">
|
||||
<input id="form_delete" name="deleteOld" value="1" type="checkbox">
|
||||
<label for="form_delete" title="old signatures will be removed. Are you sure?">Delete old</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10 col-xs-9">
|
||||
<div class="checkbox checkbox-warning">
|
||||
<input id="form_delete" name="deleteOld" value="1" type="checkbox">
|
||||
<label for="form_delete" title="old signatures will be removed. Are you sure?">Delete old</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -7,15 +7,15 @@
|
||||
<label for="form_name" class="col-sm-2 control-label">Name</label>
|
||||
<div class="col-sm-10">
|
||||
<input name="name" type="text" class="form-control" id="form_name" value="{{structureData.name}}" data-error="Name required" data-minlength="3" data-minlength-error="Min. of 3 characters" required>
|
||||
<span class="note help-block with-errors">Choose a meaningful name</span>
|
||||
<span class="note help-block with-errors"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label for="form_status" class="col-sm-4 control-label">Status</label>
|
||||
<label for="{{statusSelectId}}" class="col-sm-4 control-label">Status</label>
|
||||
<div class="col-sm-8">
|
||||
<select name="statusId" id="form_status" class="form-control">
|
||||
<select name="statusId" id="{{statusSelectId}}" class="form-control pf-select2">
|
||||
{{#structureStatus}}
|
||||
<option value="{{id}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/structureStatus}}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
}
|
||||
|
||||
// signature table module ==================================================
|
||||
.pf-sig-table-module{
|
||||
.pf-signature-table-module{
|
||||
|
||||
// delete signature button
|
||||
.pf-sig-table-clear-button{
|
||||
|
||||
Reference in New Issue
Block a user