diff --git a/app/main/controller/api/signature.php b/app/main/controller/api/signature.php
index 3d2c8cb4..fe6e8545 100644
--- a/app/main/controller/api/signature.php
+++ b/app/main/controller/api/signature.php
@@ -68,7 +68,6 @@ class Signature extends Controller\AccessController {
// delete all signatures that are not available in this request
$deleteOldSignatures = (bool)$requestData['deleteOld'];
-
$return = (object) [];
$return->error = [];
$return->signatures = [];
@@ -135,9 +134,17 @@ class Signature extends Controller\AccessController {
$data['name'] => $data['value']
];
- // if groupID changed -> typeID set to 0
+ // if groupId changed
if($data['name'] == 'groupId'){
+ // -> typeId set to 0
$newData['typeId'] = 0;
+ // -> connectionId set to 0
+ $newData['connectionId'] = 0;
+ }
+
+ // if connectionId changed
+ if($data['name'] == 'connectionId'){
+ $newData['connectionId'] = (int)$newData['connectionId'];
}
}else{
diff --git a/app/main/model/connectionmodel.php b/app/main/model/connectionmodel.php
index 0b50281c..0b674f2f 100644
--- a/app/main/model/connectionmodel.php
+++ b/app/main/model/connectionmodel.php
@@ -79,9 +79,7 @@ class ConnectionModel extends BasicModel{
* @param $systemData
*/
public function setData($systemData){
-
foreach((array)$systemData as $key => $value){
-
if( !is_array($value) ){
if( $this->exists($key) ){
$this->$key = $value;
@@ -98,7 +96,6 @@ class ConnectionModel extends BasicModel{
* @return array
*/
public function getData(){
-
$connectionData = [
'id' => $this->id,
'source' => $this->source->id,
@@ -140,7 +137,11 @@ class ConnectionModel extends BasicModel{
* @return mixed
*/
public function hasAccess(CharacterModel $characterModel){
- return $this->mapId->hasAccess($characterModel);
+ $access = false;
+ if( !$this->dry() ){
+ $access = $this->mapId->hasAccess($characterModel);
+ }
+ return $access;
}
/**
diff --git a/app/main/model/systemsignaturemodel.php b/app/main/model/systemsignaturemodel.php
index 44385146..30db870e 100644
--- a/app/main/model/systemsignaturemodel.php
+++ b/app/main/model/systemsignaturemodel.php
@@ -46,6 +46,18 @@ class SystemSignatureModel extends BasicModel {
'index' => true,
'activity-log' => true
],
+ 'connectionId' => [
+ 'type' => Schema::DT_INT,
+ 'index' => true,
+ 'belongs-to-one' => 'Model\ConnectionModel',
+ 'constraint' => [
+ [
+ 'table' => 'connection',
+ 'on-delete' => 'CASCADE'
+ ]
+ ],
+ 'activity-log' => true
+ ],
'name' => [
'type' => Schema::DT_VARCHAR128,
'nullable' => false,
@@ -117,6 +129,11 @@ class SystemSignatureModel extends BasicModel {
$signatureData->name = $this->name;
$signatureData->description = $this->description;
+ if($connection = $this->getConnection()){
+ $signatureData->connection = (object) [];
+ $signatureData->connection->id = $connection->_id;
+ }
+
$signatureData->created = (object) [];
$signatureData->created->created = strtotime($this->created);
if( is_object($this->createdCharacterId) ){
@@ -132,6 +149,48 @@ class SystemSignatureModel extends BasicModel {
return $signatureData;
}
+ /**
+ * setter for connectionId
+ * @param $connectionId
+ * @return int|null
+ */
+ public function set_connectionId($connectionId){
+ $connectionId = (int)$connectionId;
+ $validConnectionId = null;
+
+ if($connectionId > 0){
+ // check if connectionId is valid
+ $systemId = (int) $this->get('systemId', true);
+
+ /**
+ * @var $connection ConnectionModel
+ */
+ $connection = $this->rel('connectionId');
+ $connection->getById($connectionId);
+
+ if(
+ !$connection->dry() &&
+ (
+ $connection->get('source', true) === $systemId||
+ $connection->get('target', true) === $systemId
+ )
+ ){
+ // connectionId belongs to same system as $this signature -> is valid
+ $validConnectionId = $connectionId;
+ }
+ }
+
+ return $validConnectionId;
+ }
+
+ /**
+ * get the connection (if attached)
+ * @return \Model\ConnectionModel|null
+ */
+ public function getConnection(){
+ return $this->connectionId;
+ }
+
/**
* compares a new data set (array) with the current values
* and checks if something has changed
diff --git a/js/app/map/map.js b/js/app/map/map.js
index 4e6cc5af..478c5cdb 100644
--- a/js/app/map/map.js
+++ b/js/app/map/map.js
@@ -32,7 +32,6 @@ define([
mapClass: 'pf-map', // class for all maps
mapIdPrefix: 'pf-map-', // id prefix for all maps
- systemIdPrefix: 'pf-system-', // id prefix for a system
systemClass: 'pf-system', // class for all systems
systemActiveClass: 'pf-system-active', // class for an active system in a map
systemSelectedClass: 'pf-system-selected', // class for selected systems in a map
@@ -453,7 +452,7 @@ define([
$.fn.getSystem = function(map, data){
// get map container for mapId information
let mapContainer = $(this);
- let systemId = config.systemIdPrefix + mapContainer.data('id') + '-' + data.id;
+ let systemId = MapUtil.getSystemId(mapContainer.data('id'), data.id);
// check if system already exists
let system = document.getElementById( systemId );
@@ -753,8 +752,8 @@ define([
let mapId = mapContainer.data('id');
let connectionId = connectionData.id || 0;
let connection;
- let sourceSystem = $('#' + config.systemIdPrefix + mapId + '-' + connectionData.source);
- let targetSystem = $('#' + config.systemIdPrefix + mapId + '-' + connectionData.target);
+ let sourceSystem = $('#' + MapUtil.getSystemId(mapId, connectionData.source) );
+ let targetSystem = $('#' + MapUtil.getSystemId(mapId, connectionData.target) );
// check if both systems exists
// (If not -> something went wrong e.g. DB-Foreign keys for "ON DELETE",...)
@@ -851,10 +850,10 @@ define([
// check if source or target has changed
if(connectionData.source !== newConnectionData.source ){
- map.setSource(connection, config.systemIdPrefix + mapId + '-' + newConnectionData.source);
+ map.setSource(connection, MapUtil.getSystemId(mapId, newConnectionData.source) );
}
if(connectionData.target !== newConnectionData.target ){
- map.setTarget(connection, config.systemIdPrefix + mapId + '-' + newConnectionData.target);
+ map.setTarget(connection, MapUtil.getSystemId(mapId, newConnectionData.target) );
}
// connection.targetId
@@ -998,7 +997,7 @@ define([
}
if(deleteThisSystem === true){
- let deleteSystem = $('#' + config.systemIdPrefix + mapContainer.data('id') + '-' + currentSystemData[a].id);
+ let deleteSystem = $('#' + MapUtil.getSystemId(mapContainer.data('id'), currentSystemData[a].id) );
// system not found -> delete system
System.removeSystems(mapConfig.map, deleteSystem);
@@ -1423,7 +1422,6 @@ define([
* @returns {{id: Number, source: Number, sourceName: (*|T|JQuery|{}), target: Number, targetName: (*|T|JQuery), scope: *, type: *, updated: Number}}
*/
let getDataByConnection = function(connection){
-
let source = $(connection.source);
let target = $(connection.target);
@@ -2786,7 +2784,7 @@ define([
$(mapContainer).on('pf:menuSelectSystem', function(e, data){
let tempMapContainer = $(this);
- let systemId = config.systemIdPrefix + tempMapContainer.data('id') + '-' + data.systemId;
+ let systemId = MapUtil.getSystemId(tempMapContainer.data('id'), data.systemId);
let system = $(this).find('#' + systemId);
if(system.length === 1){
@@ -3309,7 +3307,6 @@ define([
return {
getMapInstance: getMapInstance,
clearMapInstance: clearMapInstance,
-
getDataByConnection: getDataByConnection
};
diff --git a/js/app/map/util.js b/js/app/map/util.js
index c9c4a1f1..fdc36bdc 100644
--- a/js/app/map/util.js
+++ b/js/app/map/util.js
@@ -17,6 +17,7 @@ define([
mapLocalStoragePrefix: 'map_', // prefix for map data local storage key
mapTabContentClass: 'pf-map-tab-content', // Tab-Content element (parent element)
+ systemIdPrefix: 'pf-system-', // id prefix for a system
systemClass: 'pf-system', // class for all systems
mapGridClass: 'pf-grid-small' // class for map grid snapping
};
@@ -191,7 +192,6 @@ define([
return this.find('.' + config.systemClass);
};
-
/**
* search connections by systems
* @param {Object} map - jsPlumb
@@ -200,7 +200,7 @@ define([
*/
let searchConnectionsBySystems = function(map, systems){
let connections = [];
- let withBackConnection = false;
+ let withBackConnection = true;
$.each(systems, function(i, system){
// get connections where system is source
@@ -571,6 +571,16 @@ define([
});
};
+ /**
+ * get systemId string (selector
+ * @param mapId
+ * @param systemId
+ * @returns {string}
+ */
+ let getSystemId = (mapId, systemId) => {
+ return config.systemIdPrefix + mapId + '-' + systemId;
+ };
+
return {
config: config,
mapOptions: mapOptions,
@@ -593,6 +603,7 @@ define([
storeDefaultMapId: storeDefaultMapId,
getLocaleData: getLocaleData,
storeLocalData: storeLocalData,
- deleteLocalData: deleteLocalData
+ deleteLocalData: deleteLocalData,
+ getSystemId: getSystemId
};
});
\ No newline at end of file
diff --git a/js/app/ui/dialog/map_info.js b/js/app/ui/dialog/map_info.js
index 0d747d74..10140f7b 100644
--- a/js/app/ui/dialog/map_info.js
+++ b/js/app/ui/dialog/map_info.js
@@ -36,8 +36,6 @@ define([
tableActionCellClass: 'pf-table-action-cell', // class for table "action" cells
tableCounterCellClass: 'pf-table-counter-cell', // class for table "counter" cells
- systemIdPrefix: 'pf-system-', // id prefix for a system
-
loadingOptions: { // config for loading overlay
icon: {
size: 'fa-2x'
@@ -430,7 +428,7 @@ define([
let deleteRowElement = $(target).parents('tr');
let activeMap = Util.getMapModule().getActiveMap();
- let systemElement = $('#' + config.systemIdPrefix + mapData.config.id + '-' + rowData.id);
+ let systemElement = MapUtil.getSystemId(mapData.config.id, rowData.id);
if(systemElement){
// trigger system delete event
diff --git a/js/app/ui/system_signature.js b/js/app/ui/system_signature.js
index ba8ae690..e45baae7 100644
--- a/js/app/ui/system_signature.js
+++ b/js/app/ui/system_signature.js
@@ -7,8 +7,10 @@ define([
'app/init',
'app/util',
'app/render',
- 'bootbox'
-], function($, Init, Util, Render, bootbox) {
+ 'bootbox',
+ 'app/map/map',
+ 'app/map/util'
+], function($, Init, Util, Render, bootbox, Map, MapUtil) {
'use strict';
let config = {
@@ -40,10 +42,12 @@ define([
sigTableEditSigNameInput: 'pf-sig-table-edit-name-input', // class for editable fields (input)
sigTableEditSigGroupSelect: 'pf-sig-table-edit-group-select', // class for editable fields (sig group)
sigTableEditSigTypeSelect: 'pf-sig-table-edit-type-select', // class for editable fields (sig type)
+ sigTableEditSigConnectionSelect: 'pf-sig-table-edit-connection-select', // class for editable fields (sig connection)
sigTableEditSigDescriptionTextarea: 'pf-sig-table-edit-desc-text', // class for editable fields (sig description)
sigTableCreatedCellClass: 'pf-sig-table-created', // class for "created" cells
sigTableUpdatedCellClass: 'pf-sig-table-updated', // class for "updated" cells
+ sigTableConnectionClass: 'pf-table-connection-cell', // class for "connection" cells
sigTableCounterClass: 'pf-table-counter-cell', // class for "counter" cells
sigTableActionCellClass: 'pf-table-action-cell', // class for "action" cells
@@ -159,7 +163,7 @@ define([
let updateCell = signatureTableApi.cell( rowIndex, cellIndex );
let updateCellElement = updateCell.nodes().to$();
- if(cellIndex === 6){
+ if(cellIndex === 7){
// clear existing counter interval
clearInterval( updateCellElement.data('interval') );
}
@@ -167,7 +171,7 @@ define([
// set new value
updateCell.data( data ).draw();
- if(cellIndex === 6){
+ if(cellIndex === 7){
updateCellElement.initTimestampCounter();
}
};
@@ -694,6 +698,27 @@ define([
tempData.type = sigType;
+ // set connection (to target system) ------------------------------------------------------------------
+ let sigConnection = ' 0){
+ sigConnection += 'data-pk="' + data.id + '" ';
+ }
+
+ // set disabled if group is not wromhole
+ if(data.groupId !== 5){
+ sigConnection += 'data-disabled="1" ';
+ }
+
+ if(data.connection){
+ sigConnection += 'data-value="' + data.connection.id + '" ';
+ }
+ sigConnection += '>';
+
+ tempData.connection = {
+ render: sigConnection,
+ connection: data.connection
+ };
+
// set description ------------------------------------------------------------------------------------
let sigDescription = ' 0){
@@ -1014,6 +1039,7 @@ define([
let sigGroupFields = tableElement.find('.' + config.sigTableEditSigGroupSelect);
let sigTypeFields = tableElement.find('.' + config.sigTableEditSigTypeSelect);
let sigDescriptionFields = tableElement.find('.' + config.sigTableEditSigDescriptionTextarea);
+ let sigConnectionFields = tableElement.find('.' + config.sigTableEditSigConnectionSelect);
// jump to "next" editable field on save
let openNextEditDialogOnSave = function(fields){
@@ -1038,8 +1064,16 @@ define([
};
// helper function - get the next editable field in next table column
- let getNextEditableField = function(field){
- let nextEditableField = $(field).closest('td').next().find('.editable');
+ let getNextEditableField = function(field, selector){
+ let nextEditableField = null;
+ if(selector){
+ // search specific sibling
+ nextEditableField = $(field).closest('td').nextAll(selector).find('.editable');
+ }else{
+ // get next sibling
+ nextEditableField = $(field).closest('td').next().find('.editable');
+ }
+
return $(nextEditableField);
};
@@ -1108,7 +1142,7 @@ define([
updateTooltip(columnElement, newValue);
// update "updated" cell
- updateSignatureCell(rowElement, 6, newRowData.updated);
+ updateSignatureCell(rowElement, 7, newRowData.updated);
}
}
});
@@ -1145,7 +1179,7 @@ define([
let newRowData = response.signatures[0];
// update "updated" cell
- updateSignatureCell(rowElement, 6, newRowData.updated);
+ updateSignatureCell(rowElement, 7, newRowData.updated);
}
// find related "type" select (same row) and change options
@@ -1166,6 +1200,18 @@ define([
}else{
typeSelect.editable('disable');
}
+
+ // find "connection" select (same row) and change "enabled" flag
+ let connectionSelect = getNextEditableField(signatureTypeField, '.' + config.sigTableConnectionClass);
+ connectionSelect.editable('setValue', null);
+
+ if(newValue === 5){
+ // wormhole
+ connectionSelect.editable('enable');
+ }else{
+ checkConnectionConflicts();
+ connectionSelect.editable('disable');
+ }
}
});
@@ -1204,7 +1250,7 @@ define([
let newRowData = response.signatures[0];
// update "updated" cell
- updateSignatureCell(rowElement, 6, newRowData.updated);
+ updateSignatureCell(rowElement, 7, newRowData.updated);
}
}
});
@@ -1227,7 +1273,61 @@ define([
let newRowData = response.signatures[0];
// update "updated" cell
- updateSignatureCell(rowElement, 6, newRowData.updated);
+ updateSignatureCell(rowElement, 7, newRowData.updated);
+ }
+ }
+ });
+
+ // Select connection (target system) --------------------------------------------------------------------------
+ let initCount = 0;
+ sigConnectionFields.on('init', function(e, editable) {
+ if(++initCount >= sigConnectionFields.length){
+ checkConnectionConflicts();
+ }
+ });
+
+ sigConnectionFields.editable({
+ type: 'select',
+ title: 'system',
+ name: 'connectionId',
+ emptytext: 'unknown',
+ onblur: 'submit',
+ showbuttons: false,
+ params: modifyFieldParamsOnSend,
+ display: function(value, sourceData) {
+ let editableElement = $(this);
+ let newValue = '';
+
+ if(value !== null){
+ let selected = $.fn.editableutils.itemsByValue(value, sourceData);
+ if(
+ selected.length &&
+ selected[0].text !== ''
+ ){
+ newValue += '';
+ newValue += ' ' + selected[0].text;
+ }else{
+ newValue = 'unknown';
+ }
+ }
+
+ editableElement.html(newValue);
+ },
+ source: function(a,b){
+ let activeMap = Util.getMapModule().getActiveMap();
+ let mapId = activeMap.data('id');
+ let availableConnections = getSignatureConnectionOptions(mapId, systemData);
+
+ return availableConnections;
+ },
+ success: function(response, newValue){
+ if(response){
+ let signatureConnectionField = $(this);
+ let rowElement = signatureConnectionField.parents('tr');
+ let newRowData = response.signatures[0];
+
+ // update "updated" cell
+ updateSignatureCell(rowElement, 7, newRowData.updated);
}
}
});
@@ -1244,11 +1344,106 @@ define([
tableElement.parents('.' + config.tableToolsActionClass).css( 'height', '-=35px' );
});
+ // save events
+ sigConnectionFields.on('save', function(e, editable){
+ checkConnectionConflicts();
+ });
+
// open next field dialog -------------------------------------------------------------------------------------
openNextEditDialogOnSave(sigNameFields);
openNextEditDialogOnSave(sigGroupFields);
};
+ /**
+ * get all connection select options
+ * @param mapId
+ * @param systemData
+ * @returns {Array}
+ */
+ let getSignatureConnectionOptions = (mapId, systemData) => {
+ let map = Map.getMapInstance( mapId );
+ let systemId = MapUtil.getSystemId(mapId, systemData.id);
+ let systemConnections = MapUtil.searchConnectionsBySystems(map, [systemId]);
+ let connectionOptions = [];
+
+ for(let i = 0; i < systemConnections.length; i++){
+ let connectionData = Map.getDataByConnection(systemConnections[i]);
+
+ // connectionId is required (must be stored)
+ if(connectionData.id){
+ // check whether "source" or "target" system is relevant for this connection
+ // -> hint "source" === 'target' --> loop
+ if(systemData.id !== connectionData.target){
+ // take target...
+ connectionOptions.push({
+ value: connectionData.id,
+ text: connectionData.targetName
+ });
+ }else if(systemData.id !== connectionData.source){
+ // take source...
+ connectionOptions.push({
+ value: connectionData.id,
+ text: connectionData.sourceName
+ });
+ }
+ }
+ }
+
+ // add empty entry
+ connectionOptions.unshift({ value: null, text: ''});
+
+ return connectionOptions;
+ };
+
+ /**
+ * check connectionIds for conflicts (multiple signatures -> same connection)
+ * -> show "conflict" icon next to select
+ */
+ let checkConnectionConflicts = () => {
+ setTimeout(function() {
+ let connectionSelects = $('.' + config.sigTableConnectionClass + ' .editable');
+ let connectionIds = [];
+ let duplicateConnectionIds = [];
+ let groupedSelects = [];
+
+ connectionSelects.each(function(){
+ let select = $(this);
+ let value = parseInt(select.editable('getValue', true) )|| 0;
+
+ if(
+ connectionIds.indexOf(value) > -1 &&
+ duplicateConnectionIds.indexOf(value) === -1
+ ){
+ // duplicate found
+ duplicateConnectionIds.push(value);
+ }
+
+ if(groupedSelects[value] !== undefined){
+ groupedSelects[value].push(select[0]);
+ }else{
+ groupedSelects[value] = [select[0]];
+ }
+
+ connectionIds.push(value);
+ });
+
+ // update "conflict" icon next to select label for connectionIds
+ connectionSelects.each(function(){
+ let select = $(this);
+ let value = parseInt(select.editable('getValue', true) )|| 0;
+ let conflictIcon = select.find('.fa-exclamation-triangle');
+ if(
+ duplicateConnectionIds.indexOf(value) > -1 &&
+ groupedSelects[value].indexOf(select[0]) > -1
+ ){
+ conflictIcon.removeClass('hide');
+ }else{
+ conflictIcon.addClass('hide');
+ }
+ });
+ }, 200);
+ };
+
/**
* get all signatures that can exist for a given system
* @param systemData
@@ -1451,6 +1646,9 @@ define([
// update signature bar
moduleElement.updateScannedSignaturesBar({showNotice: false});
+ // update connection conflicts
+ checkConnectionConflicts();
+
Util.showNotify({title: 'Signature deleted', text: signatureCount + ' signatures deleted', type: 'success'});
}
};
@@ -1789,6 +1987,18 @@ define([
data: 'description'
},{
targets: 5,
+ orderable: false,
+ searchable: false,
+ className: [config.sigTableConnectionClass].join(' '),
+ title: 'leads to',
+ type: 'html',
+ width: '70px',
+ data: 'connection',
+ render: {
+ _: 'render'
+ }
+ },{
+ targets: 6,
title: 'created',
width: '90px',
searchable: false,
@@ -1802,7 +2012,7 @@ define([
$(cell).initTimestampCounter();
}
},{
- targets: 6,
+ targets: 7,
title: 'updated',
width: '90px',
searchable: false,
@@ -1824,7 +2034,7 @@ define([
}
}
},{
- targets: 7,
+ targets: 8,
title: '',
orderable: false,
searchable: false,
@@ -1845,7 +2055,7 @@ define([
}
}
},{
- targets: 8,
+ targets: 9,
title: '',
orderable: false,
searchable: false,
diff --git a/public/js/v1.2.1/app/map/map.js b/public/js/v1.2.1/app/map/map.js
index 4e6cc5af..478c5cdb 100644
--- a/public/js/v1.2.1/app/map/map.js
+++ b/public/js/v1.2.1/app/map/map.js
@@ -32,7 +32,6 @@ define([
mapClass: 'pf-map', // class for all maps
mapIdPrefix: 'pf-map-', // id prefix for all maps
- systemIdPrefix: 'pf-system-', // id prefix for a system
systemClass: 'pf-system', // class for all systems
systemActiveClass: 'pf-system-active', // class for an active system in a map
systemSelectedClass: 'pf-system-selected', // class for selected systems in a map
@@ -453,7 +452,7 @@ define([
$.fn.getSystem = function(map, data){
// get map container for mapId information
let mapContainer = $(this);
- let systemId = config.systemIdPrefix + mapContainer.data('id') + '-' + data.id;
+ let systemId = MapUtil.getSystemId(mapContainer.data('id'), data.id);
// check if system already exists
let system = document.getElementById( systemId );
@@ -753,8 +752,8 @@ define([
let mapId = mapContainer.data('id');
let connectionId = connectionData.id || 0;
let connection;
- let sourceSystem = $('#' + config.systemIdPrefix + mapId + '-' + connectionData.source);
- let targetSystem = $('#' + config.systemIdPrefix + mapId + '-' + connectionData.target);
+ let sourceSystem = $('#' + MapUtil.getSystemId(mapId, connectionData.source) );
+ let targetSystem = $('#' + MapUtil.getSystemId(mapId, connectionData.target) );
// check if both systems exists
// (If not -> something went wrong e.g. DB-Foreign keys for "ON DELETE",...)
@@ -851,10 +850,10 @@ define([
// check if source or target has changed
if(connectionData.source !== newConnectionData.source ){
- map.setSource(connection, config.systemIdPrefix + mapId + '-' + newConnectionData.source);
+ map.setSource(connection, MapUtil.getSystemId(mapId, newConnectionData.source) );
}
if(connectionData.target !== newConnectionData.target ){
- map.setTarget(connection, config.systemIdPrefix + mapId + '-' + newConnectionData.target);
+ map.setTarget(connection, MapUtil.getSystemId(mapId, newConnectionData.target) );
}
// connection.targetId
@@ -998,7 +997,7 @@ define([
}
if(deleteThisSystem === true){
- let deleteSystem = $('#' + config.systemIdPrefix + mapContainer.data('id') + '-' + currentSystemData[a].id);
+ let deleteSystem = $('#' + MapUtil.getSystemId(mapContainer.data('id'), currentSystemData[a].id) );
// system not found -> delete system
System.removeSystems(mapConfig.map, deleteSystem);
@@ -1423,7 +1422,6 @@ define([
* @returns {{id: Number, source: Number, sourceName: (*|T|JQuery|{}), target: Number, targetName: (*|T|JQuery), scope: *, type: *, updated: Number}}
*/
let getDataByConnection = function(connection){
-
let source = $(connection.source);
let target = $(connection.target);
@@ -2786,7 +2784,7 @@ define([
$(mapContainer).on('pf:menuSelectSystem', function(e, data){
let tempMapContainer = $(this);
- let systemId = config.systemIdPrefix + tempMapContainer.data('id') + '-' + data.systemId;
+ let systemId = MapUtil.getSystemId(tempMapContainer.data('id'), data.systemId);
let system = $(this).find('#' + systemId);
if(system.length === 1){
@@ -3309,7 +3307,6 @@ define([
return {
getMapInstance: getMapInstance,
clearMapInstance: clearMapInstance,
-
getDataByConnection: getDataByConnection
};
diff --git a/public/js/v1.2.1/app/map/util.js b/public/js/v1.2.1/app/map/util.js
index c9c4a1f1..fdc36bdc 100644
--- a/public/js/v1.2.1/app/map/util.js
+++ b/public/js/v1.2.1/app/map/util.js
@@ -17,6 +17,7 @@ define([
mapLocalStoragePrefix: 'map_', // prefix for map data local storage key
mapTabContentClass: 'pf-map-tab-content', // Tab-Content element (parent element)
+ systemIdPrefix: 'pf-system-', // id prefix for a system
systemClass: 'pf-system', // class for all systems
mapGridClass: 'pf-grid-small' // class for map grid snapping
};
@@ -191,7 +192,6 @@ define([
return this.find('.' + config.systemClass);
};
-
/**
* search connections by systems
* @param {Object} map - jsPlumb
@@ -200,7 +200,7 @@ define([
*/
let searchConnectionsBySystems = function(map, systems){
let connections = [];
- let withBackConnection = false;
+ let withBackConnection = true;
$.each(systems, function(i, system){
// get connections where system is source
@@ -571,6 +571,16 @@ define([
});
};
+ /**
+ * get systemId string (selector
+ * @param mapId
+ * @param systemId
+ * @returns {string}
+ */
+ let getSystemId = (mapId, systemId) => {
+ return config.systemIdPrefix + mapId + '-' + systemId;
+ };
+
return {
config: config,
mapOptions: mapOptions,
@@ -593,6 +603,7 @@ define([
storeDefaultMapId: storeDefaultMapId,
getLocaleData: getLocaleData,
storeLocalData: storeLocalData,
- deleteLocalData: deleteLocalData
+ deleteLocalData: deleteLocalData,
+ getSystemId: getSystemId
};
});
\ No newline at end of file
diff --git a/public/js/v1.2.1/app/ui/dialog/map_info.js b/public/js/v1.2.1/app/ui/dialog/map_info.js
index 0d747d74..10140f7b 100644
--- a/public/js/v1.2.1/app/ui/dialog/map_info.js
+++ b/public/js/v1.2.1/app/ui/dialog/map_info.js
@@ -36,8 +36,6 @@ define([
tableActionCellClass: 'pf-table-action-cell', // class for table "action" cells
tableCounterCellClass: 'pf-table-counter-cell', // class for table "counter" cells
- systemIdPrefix: 'pf-system-', // id prefix for a system
-
loadingOptions: { // config for loading overlay
icon: {
size: 'fa-2x'
@@ -430,7 +428,7 @@ define([
let deleteRowElement = $(target).parents('tr');
let activeMap = Util.getMapModule().getActiveMap();
- let systemElement = $('#' + config.systemIdPrefix + mapData.config.id + '-' + rowData.id);
+ let systemElement = MapUtil.getSystemId(mapData.config.id, rowData.id);
if(systemElement){
// trigger system delete event
diff --git a/public/js/v1.2.1/app/ui/system_signature.js b/public/js/v1.2.1/app/ui/system_signature.js
index ba8ae690..e45baae7 100644
--- a/public/js/v1.2.1/app/ui/system_signature.js
+++ b/public/js/v1.2.1/app/ui/system_signature.js
@@ -7,8 +7,10 @@ define([
'app/init',
'app/util',
'app/render',
- 'bootbox'
-], function($, Init, Util, Render, bootbox) {
+ 'bootbox',
+ 'app/map/map',
+ 'app/map/util'
+], function($, Init, Util, Render, bootbox, Map, MapUtil) {
'use strict';
let config = {
@@ -40,10 +42,12 @@ define([
sigTableEditSigNameInput: 'pf-sig-table-edit-name-input', // class for editable fields (input)
sigTableEditSigGroupSelect: 'pf-sig-table-edit-group-select', // class for editable fields (sig group)
sigTableEditSigTypeSelect: 'pf-sig-table-edit-type-select', // class for editable fields (sig type)
+ sigTableEditSigConnectionSelect: 'pf-sig-table-edit-connection-select', // class for editable fields (sig connection)
sigTableEditSigDescriptionTextarea: 'pf-sig-table-edit-desc-text', // class for editable fields (sig description)
sigTableCreatedCellClass: 'pf-sig-table-created', // class for "created" cells
sigTableUpdatedCellClass: 'pf-sig-table-updated', // class for "updated" cells
+ sigTableConnectionClass: 'pf-table-connection-cell', // class for "connection" cells
sigTableCounterClass: 'pf-table-counter-cell', // class for "counter" cells
sigTableActionCellClass: 'pf-table-action-cell', // class for "action" cells
@@ -159,7 +163,7 @@ define([
let updateCell = signatureTableApi.cell( rowIndex, cellIndex );
let updateCellElement = updateCell.nodes().to$();
- if(cellIndex === 6){
+ if(cellIndex === 7){
// clear existing counter interval
clearInterval( updateCellElement.data('interval') );
}
@@ -167,7 +171,7 @@ define([
// set new value
updateCell.data( data ).draw();
- if(cellIndex === 6){
+ if(cellIndex === 7){
updateCellElement.initTimestampCounter();
}
};
@@ -694,6 +698,27 @@ define([
tempData.type = sigType;
+ // set connection (to target system) ------------------------------------------------------------------
+ let sigConnection = ' 0){
+ sigConnection += 'data-pk="' + data.id + '" ';
+ }
+
+ // set disabled if group is not wromhole
+ if(data.groupId !== 5){
+ sigConnection += 'data-disabled="1" ';
+ }
+
+ if(data.connection){
+ sigConnection += 'data-value="' + data.connection.id + '" ';
+ }
+ sigConnection += '>';
+
+ tempData.connection = {
+ render: sigConnection,
+ connection: data.connection
+ };
+
// set description ------------------------------------------------------------------------------------
let sigDescription = ' 0){
@@ -1014,6 +1039,7 @@ define([
let sigGroupFields = tableElement.find('.' + config.sigTableEditSigGroupSelect);
let sigTypeFields = tableElement.find('.' + config.sigTableEditSigTypeSelect);
let sigDescriptionFields = tableElement.find('.' + config.sigTableEditSigDescriptionTextarea);
+ let sigConnectionFields = tableElement.find('.' + config.sigTableEditSigConnectionSelect);
// jump to "next" editable field on save
let openNextEditDialogOnSave = function(fields){
@@ -1038,8 +1064,16 @@ define([
};
// helper function - get the next editable field in next table column
- let getNextEditableField = function(field){
- let nextEditableField = $(field).closest('td').next().find('.editable');
+ let getNextEditableField = function(field, selector){
+ let nextEditableField = null;
+ if(selector){
+ // search specific sibling
+ nextEditableField = $(field).closest('td').nextAll(selector).find('.editable');
+ }else{
+ // get next sibling
+ nextEditableField = $(field).closest('td').next().find('.editable');
+ }
+
return $(nextEditableField);
};
@@ -1108,7 +1142,7 @@ define([
updateTooltip(columnElement, newValue);
// update "updated" cell
- updateSignatureCell(rowElement, 6, newRowData.updated);
+ updateSignatureCell(rowElement, 7, newRowData.updated);
}
}
});
@@ -1145,7 +1179,7 @@ define([
let newRowData = response.signatures[0];
// update "updated" cell
- updateSignatureCell(rowElement, 6, newRowData.updated);
+ updateSignatureCell(rowElement, 7, newRowData.updated);
}
// find related "type" select (same row) and change options
@@ -1166,6 +1200,18 @@ define([
}else{
typeSelect.editable('disable');
}
+
+ // find "connection" select (same row) and change "enabled" flag
+ let connectionSelect = getNextEditableField(signatureTypeField, '.' + config.sigTableConnectionClass);
+ connectionSelect.editable('setValue', null);
+
+ if(newValue === 5){
+ // wormhole
+ connectionSelect.editable('enable');
+ }else{
+ checkConnectionConflicts();
+ connectionSelect.editable('disable');
+ }
}
});
@@ -1204,7 +1250,7 @@ define([
let newRowData = response.signatures[0];
// update "updated" cell
- updateSignatureCell(rowElement, 6, newRowData.updated);
+ updateSignatureCell(rowElement, 7, newRowData.updated);
}
}
});
@@ -1227,7 +1273,61 @@ define([
let newRowData = response.signatures[0];
// update "updated" cell
- updateSignatureCell(rowElement, 6, newRowData.updated);
+ updateSignatureCell(rowElement, 7, newRowData.updated);
+ }
+ }
+ });
+
+ // Select connection (target system) --------------------------------------------------------------------------
+ let initCount = 0;
+ sigConnectionFields.on('init', function(e, editable) {
+ if(++initCount >= sigConnectionFields.length){
+ checkConnectionConflicts();
+ }
+ });
+
+ sigConnectionFields.editable({
+ type: 'select',
+ title: 'system',
+ name: 'connectionId',
+ emptytext: 'unknown',
+ onblur: 'submit',
+ showbuttons: false,
+ params: modifyFieldParamsOnSend,
+ display: function(value, sourceData) {
+ let editableElement = $(this);
+ let newValue = '';
+
+ if(value !== null){
+ let selected = $.fn.editableutils.itemsByValue(value, sourceData);
+ if(
+ selected.length &&
+ selected[0].text !== ''
+ ){
+ newValue += '';
+ newValue += ' ' + selected[0].text;
+ }else{
+ newValue = 'unknown';
+ }
+ }
+
+ editableElement.html(newValue);
+ },
+ source: function(a,b){
+ let activeMap = Util.getMapModule().getActiveMap();
+ let mapId = activeMap.data('id');
+ let availableConnections = getSignatureConnectionOptions(mapId, systemData);
+
+ return availableConnections;
+ },
+ success: function(response, newValue){
+ if(response){
+ let signatureConnectionField = $(this);
+ let rowElement = signatureConnectionField.parents('tr');
+ let newRowData = response.signatures[0];
+
+ // update "updated" cell
+ updateSignatureCell(rowElement, 7, newRowData.updated);
}
}
});
@@ -1244,11 +1344,106 @@ define([
tableElement.parents('.' + config.tableToolsActionClass).css( 'height', '-=35px' );
});
+ // save events
+ sigConnectionFields.on('save', function(e, editable){
+ checkConnectionConflicts();
+ });
+
// open next field dialog -------------------------------------------------------------------------------------
openNextEditDialogOnSave(sigNameFields);
openNextEditDialogOnSave(sigGroupFields);
};
+ /**
+ * get all connection select options
+ * @param mapId
+ * @param systemData
+ * @returns {Array}
+ */
+ let getSignatureConnectionOptions = (mapId, systemData) => {
+ let map = Map.getMapInstance( mapId );
+ let systemId = MapUtil.getSystemId(mapId, systemData.id);
+ let systemConnections = MapUtil.searchConnectionsBySystems(map, [systemId]);
+ let connectionOptions = [];
+
+ for(let i = 0; i < systemConnections.length; i++){
+ let connectionData = Map.getDataByConnection(systemConnections[i]);
+
+ // connectionId is required (must be stored)
+ if(connectionData.id){
+ // check whether "source" or "target" system is relevant for this connection
+ // -> hint "source" === 'target' --> loop
+ if(systemData.id !== connectionData.target){
+ // take target...
+ connectionOptions.push({
+ value: connectionData.id,
+ text: connectionData.targetName
+ });
+ }else if(systemData.id !== connectionData.source){
+ // take source...
+ connectionOptions.push({
+ value: connectionData.id,
+ text: connectionData.sourceName
+ });
+ }
+ }
+ }
+
+ // add empty entry
+ connectionOptions.unshift({ value: null, text: ''});
+
+ return connectionOptions;
+ };
+
+ /**
+ * check connectionIds for conflicts (multiple signatures -> same connection)
+ * -> show "conflict" icon next to select
+ */
+ let checkConnectionConflicts = () => {
+ setTimeout(function() {
+ let connectionSelects = $('.' + config.sigTableConnectionClass + ' .editable');
+ let connectionIds = [];
+ let duplicateConnectionIds = [];
+ let groupedSelects = [];
+
+ connectionSelects.each(function(){
+ let select = $(this);
+ let value = parseInt(select.editable('getValue', true) )|| 0;
+
+ if(
+ connectionIds.indexOf(value) > -1 &&
+ duplicateConnectionIds.indexOf(value) === -1
+ ){
+ // duplicate found
+ duplicateConnectionIds.push(value);
+ }
+
+ if(groupedSelects[value] !== undefined){
+ groupedSelects[value].push(select[0]);
+ }else{
+ groupedSelects[value] = [select[0]];
+ }
+
+ connectionIds.push(value);
+ });
+
+ // update "conflict" icon next to select label for connectionIds
+ connectionSelects.each(function(){
+ let select = $(this);
+ let value = parseInt(select.editable('getValue', true) )|| 0;
+ let conflictIcon = select.find('.fa-exclamation-triangle');
+ if(
+ duplicateConnectionIds.indexOf(value) > -1 &&
+ groupedSelects[value].indexOf(select[0]) > -1
+ ){
+ conflictIcon.removeClass('hide');
+ }else{
+ conflictIcon.addClass('hide');
+ }
+ });
+ }, 200);
+ };
+
/**
* get all signatures that can exist for a given system
* @param systemData
@@ -1451,6 +1646,9 @@ define([
// update signature bar
moduleElement.updateScannedSignaturesBar({showNotice: false});
+ // update connection conflicts
+ checkConnectionConflicts();
+
Util.showNotify({title: 'Signature deleted', text: signatureCount + ' signatures deleted', type: 'success'});
}
};
@@ -1789,6 +1987,18 @@ define([
data: 'description'
},{
targets: 5,
+ orderable: false,
+ searchable: false,
+ className: [config.sigTableConnectionClass].join(' '),
+ title: 'leads to',
+ type: 'html',
+ width: '70px',
+ data: 'connection',
+ render: {
+ _: 'render'
+ }
+ },{
+ targets: 6,
title: 'created',
width: '90px',
searchable: false,
@@ -1802,7 +2012,7 @@ define([
$(cell).initTimestampCounter();
}
},{
- targets: 6,
+ targets: 7,
title: 'updated',
width: '90px',
searchable: false,
@@ -1824,7 +2034,7 @@ define([
}
}
},{
- targets: 7,
+ targets: 8,
title: '',
orderable: false,
searchable: false,
@@ -1845,7 +2055,7 @@ define([
}
}
},{
- targets: 8,
+ targets: 9,
title: '',
orderable: false,
searchable: false,
diff --git a/public/templates/dialog/credit.html b/public/templates/dialog/credit.html
index 4e036800..31f05a65 100644
--- a/public/templates/dialog/credit.html
+++ b/public/templates/dialog/credit.html
@@ -28,7 +28,7 @@
pathfinder
Repository
GitHub
- Community
+ Social
Google+