/**
* map overlay functions
*/
define([
'jquery',
'app/init',
'app/util',
'app/map/util'
], function($, Init, Util, MapUtil) {
'use strict';
let config = {
logTimerCount: 3, // map log timer in seconds
// map
mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable)
// map overlay positions
mapOverlayClass: 'pf-map-overlay', // class for all map overlays
mapOverlayTimerClass: 'pf-map-overlay-timer', // class for map overlay timer e.g. map timer
mapOverlayInfoClass: 'pf-map-overlay-info', // class for map overlay info e.g. map info
overlayLocalClass: 'pf-map-overlay-local', // class for map overlay "local" table
// system
systemHeadClass: 'pf-system-head', // class for system head
// overlay IDs
connectionOverlayId: 'pf-map-connection-overlay', // connection "normal size" ID (jsPlumb)
connectionOverlayEolId: 'pf-map-connection-eol-overlay', // connection EOL overlay ID (jsPlumb)
connectionOverlayArrowId: 'pf-map-connection-arrow-overlay', // connection Arrows overlay ID (jsPlumb)
connectionOverlaySmallId: 'pf-map-connection-small-overlay', // connection "smaller" overlay ID (jsPlumb)
// overlay classes
connectionOverlayClass: 'pf-map-connection-overlay', // class for "normal size" overlay
connectionArrowOverlayClass: 'pf-map-connection-arrow-overlay', // class for "connection arrow" overlay
connectionDiamondOverlayClass: 'pf-map-connection-diamond-overlay', // class for "connection diamond" overlay
connectionOverlaySmallClass: 'pf-map-connection-small-overlay' // class for "smaller" overlays
};
/**
* get MapObject (jsPlumb) from mapElement
* @param mapElement
* @returns {*}
*/
let getMapObjectFromMapElement = (mapElement) => {
let Map = require('app/map/map');
return Map.getMapInstance( mapElement.data('id') );
};
/**
* get map object (jsPlumb) from iconElement
* @param overlayIcon
* @returns {*}
*/
let getMapObjectFromOverlayIcon = (overlayIcon) => {
let mapElement = Util.getMapElementFromOverlay(overlayIcon);
return getMapObjectFromMapElement( mapElement );
};
/**
* add overlays to connections (signature based data)
* @param connections
* @param connectionsData
*/
let addConnectionsOverlay = (connections, connectionsData) => {
let SystemSignatures = require('app/ui/system_signature');
/**
* add label to endpoint
* @param endpoint
* @param label
*/
let addEndpointOverlay = (endpoint, label) => {
endpoint.addOverlay([
'Label',
{
label: MapUtil.getEndpointOverlayContent(label),
id: config.connectionOverlaySmallId,
cssClass: config.connectionOverlaySmallClass,
location: [ 0.9, 0.9 ]
}
]);
};
// loop through all map connections (get from DOM)
for(let connection of connections) {
let connectionId = connection.getParameter('connectionId');
let sourceEndpoint = connection.endpoints[0];
let targetEndpoint = connection.endpoints[1];
let sourceSystem = $(sourceEndpoint.element);
let targetSystem = $(targetEndpoint.element);
let sourceId = sourceSystem.data('id');
let targetId = targetSystem.data('id');
let signatureTypeNames = {
sourceLabels: [],
targetLabels: []
};
// ... find matching connectionData (from Ajax)
for(let connectionData of connectionsData){
if(connectionData.id === connectionId){
signatureTypeNames = MapUtil.getConnectionDataFromSignatures(connection, connectionData);
// ... connection matched -> continue with next one
break;
}
}
let sourceLabel = signatureTypeNames.sourceLabels;
let targetLabel = signatureTypeNames.targetLabels;
// add endpoint overlays ------------------------------------------------------
addEndpointOverlay(sourceEndpoint, sourceLabel);
addEndpointOverlay(targetEndpoint, targetLabel);
// add arrow (connection) overlay that points from "XXX" => "K162" ------------
let overlayType = 'Diamond'; // not specified
let arrowDirection = 1;
if(
(sourceLabel.indexOf('K162') !== -1 && targetLabel.indexOf('K162') !== -1) ||
(sourceLabel.length === 0 && targetLabel.length === 0) ||
(
sourceLabel.length > 0 && targetLabel.length > 0 &&
sourceLabel.indexOf('K162') === -1 && targetLabel.indexOf('K162') === -1
)
){
// unknown direction
overlayType = 'Diamond'; // not specified
arrowDirection = 1;
}else if(
(sourceLabel.indexOf('K162') !== -1) ||
(sourceLabel.length === 0 && targetLabel.indexOf('K162') === -1)
){
// convert default arrow direction
overlayType = 'Arrow';
arrowDirection = -1;
}else{
// default arrow direction is fine
overlayType = 'Arrow';
arrowDirection = 1;
}
connection.addOverlay([
overlayType,
{
width: 12,
length: 15,
location: 0.5,
foldback: 0.85,
direction: arrowDirection,
id: config.connectionOverlayArrowId,
cssClass: (overlayType === 'Arrow') ? config.connectionArrowOverlayClass : config.connectionDiamondOverlayClass
}
]);
}
};
/**
* remove overviews from a Tooltip
* @param endpoint
* @param i
*/
let removeEndpointOverlay = (endpoint, i) => {
endpoint.removeOverlays(config.connectionOverlaySmallId);
};
/**
* format json object with "time parts" into string
* @param parts
* @returns {string}
*/
let formatTimeParts = (parts) => {
let label = '';
if(parts.days){
label += parts.days + 'd ';
}
label += ('00' + parts.hours).slice(-2);
label += ':' + ('00' + parts.min).slice(-2);
return label;
};
/**
* hide default icon and replace it with "loading" icon
* @param iconElement
*/
let showLoading = (iconElement) => {
iconElement = $(iconElement);
let dataName = 'default-icon';
let defaultIconClass = iconElement.data(dataName);
// get default icon class
if( !defaultIconClass ){
// index 0 == 'fa-fw', index 1 == IconName
defaultIconClass = $(iconElement).attr('class').match(/\bfa-\S*/g)[1];
iconElement.data(dataName, defaultIconClass);
}
iconElement.toggleClass( defaultIconClass + ' fa-sync fa-spin' );
};
/**
* hide "loading" icon and replace with default icon
* @param iconElement
*/
let hideLoading = (iconElement) => {
iconElement = $(iconElement);
let dataName = 'default-icon';
let defaultIconClass = iconElement.data(dataName);
iconElement.toggleClass( defaultIconClass + ' fa-sync fa-spin' );
};
/**
* git signature data that is linked to a connection for a mapId
* @param mapElement
* @param connections
* @param callback
*/
let getConnectionSignatureData = (mapElement, connections, callback) => {
let mapOverlay = $(mapElement).getMapOverlay('info');
let overlayConnectionIcon = mapOverlay.find('.pf-map-overlay-endpoint');
showLoading(overlayConnectionIcon);
let requestData = {
mapId: mapElement.data('id'),
addData : ['signatures'],
filterData : ['signatures']
};
$.ajax({
type: 'POST',
url: Init.path.getMapConnectionData,
data: requestData,
dataType: 'json',
context: {
mapElement: mapElement,
connections: connections,
overlayConnectionIcon: overlayConnectionIcon
}
}).done(function(connectionsData){
// hide all connection before add them (refresh)
this.mapElement.hideEndpointOverlays();
// ... add overlays
callback(this.connections, connectionsData);
}).always(function() {
hideLoading(this.overlayConnectionIcon);
});
};
/**
* showEndpointOverlays
* -> used by "refresh" overlays (hover) AND/OR initial menu trigger
*/
$.fn.showEndpointOverlays = function(){
let mapElement = $(this);
let map = getMapObjectFromMapElement(mapElement);
let MapUtil = require('app/map/util');
let connections = MapUtil.searchConnectionsByScopeAndType(map, 'wh');
// get connection signature information ---------------------------------------
getConnectionSignatureData(mapElement, connections, addConnectionsOverlay);
};
/**
* hideEndpointOverlays
* -> see showEndpointOverlays()
*/
$.fn.hideEndpointOverlays = function(){
let map = getMapObjectFromMapElement($(this));
let MapUtil = require('app/map/util');
let connections = MapUtil.searchConnectionsByScopeAndType(map, 'wh');
for (let connection of connections){
connection.removeOverlays(config.connectionOverlayArrowId);
connection.endpoints.forEach(removeEndpointOverlay);
}
};
/**
* Overlay options (all available map options shown in overlay)
* "active": (active || hover) indicated whether an icon/option
* is marked as "active".
* "active": Makes icon active when visible
* "hover": Make icon active on hover
*/
let options = {
filter: {
title: 'active filter',
trigger: 'active',
class: 'pf-map-overlay-filter',
iconClass: ['fas', 'fa-fw', 'fa-filter']
},
mapSnapToGrid: {
title: 'active grid',
trigger: 'active',
class: 'pf-map-overlay-grid',
iconClass: ['glyphicon', 'glyphicon-th']
},
mapMagnetizer: {
title: 'active magnetizer',
trigger: 'active',
class: 'pf-map-overlay-magnetizer',
iconClass: ['fas', 'fa-fw', 'fa-magnet']
},
systemRegion: {
title: 'show regions',
trigger: 'hover',
class: 'pf-map-overlay-region',
iconClass: ['fas', 'fa-fw', 'fa-tags'],
hoverIntent: {
over: function(e){
let mapElement = Util.getMapElementFromOverlay(this);
mapElement.find('.' + config.systemHeadClass).each(function(){
let system = $(this);
// init tooltip if not already exists
if ( !system.data('bs.tooltip') ){
system.tooltip({
container: mapElement,
placement: 'right',
title: function(){
return $(this).parent().data('region');
},
trigger: 'manual'
});
}
system.tooltip('show');
});
},
out: function(e){
let mapElement = Util.getMapElementFromOverlay(this);
mapElement.find('.' + config.systemHeadClass).tooltip('hide');
}
}
},
mapEndpoint: {
title: 'refresh signature overlays',
trigger: 'refresh',
class: 'pf-map-overlay-endpoint',
iconClass: ['fas', 'fa-fw', 'fa-link'],
hoverIntent: {
over: function(e){
let mapElement = Util.getMapElementFromOverlay(this);
mapElement.showEndpointOverlays();
},
out: function(e){
// just "refresh" on hover
}
}
},
connection: {
title: 'WH data',
trigger: 'hover',
class: 'pf-map-overlay-connection',
iconClass: ['fas', 'fa-fw', 'fa-fighter-jet'],
hoverIntent: {
over: function(e){
let map = getMapObjectFromOverlayIcon(this);
let MapUtil = require('app/map/util');
let connections = MapUtil.searchConnectionsByScopeAndType(map, 'wh');
let serverDate = Util.getServerTime();
// show connection overlays ---------------------------------------------------
for (let connection of connections) {
let createdTimestamp = connection.getParameter('created');
let updatedTimestamp = connection.getParameter('updated');
let createdDate = Util.convertTimestampToServerTime(createdTimestamp);
let updatedDate = Util.convertTimestampToServerTime(updatedTimestamp);
let createdDiff = Util.getTimeDiffParts(createdDate, serverDate);
let updatedDiff = Util.getTimeDiffParts(updatedDate, serverDate);
// format overlay label
let labels = [
' ' + formatTimeParts(createdDiff),
' ' + formatTimeParts(updatedDiff)
];
// add label overlay ------------------------------------------------------
connection.addOverlay([
'Label',
{
label: labels.join('
'),
id: config.connectionOverlayId,
cssClass: config.connectionOverlaySmallClass,
location: 0.35
}
]);
}
},
out: function(e){
let map = getMapObjectFromOverlayIcon(this);
let MapUtil = require('app/map/util');
let connections = MapUtil.searchConnectionsByScopeAndType(map, 'wh');
for (let connection of connections){
connection.removeOverlays(config.connectionOverlayId);
}
}
}
},
connectionEol: {
title: 'EOL timer',
trigger: 'hover',
class: 'pf-map-overlay-connection-eol',
iconClass: ['far', 'fa-fw', 'fa-clock'],
hoverIntent: {
over: function(e){
let map = getMapObjectFromOverlayIcon(this);
let MapUtil = require('app/map/util');
let connections = MapUtil.searchConnectionsByScopeAndType(map, 'wh', ['wh_eol']);
let serverDate = Util.getServerTime();
for (let connection of connections) {
let eolTimestamp = connection.getParameter('eolUpdated');
let eolDate = Util.convertTimestampToServerTime(eolTimestamp);
let diff = Util.getTimeDiffParts(eolDate, serverDate);
connection.addOverlay([
'Label',
{
label: ' ' + formatTimeParts(diff),
id: config.connectionOverlayEolId,
cssClass: [config.connectionOverlayClass, 'eol'].join(' '),
location: 0.25
}
]);
}
},
out: function(e){
let map = getMapObjectFromOverlayIcon(this);
let MapUtil = require('app/map/util');
let connections = MapUtil.searchConnectionsByScopeAndType(map, 'wh', ['wh_eol']);
for (let connection of connections) {
connection.removeOverlay(config.connectionOverlayEolId);
}
}
}
}
};
/**
* get map overlay element by type e.g. timer/counter, info - overlay
* @param overlayType
* @returns {*}
*/
$.fn.getMapOverlay = function(overlayType){
let mapWrapperElement = $(this).parents('.' + config.mapWrapperClass);
let mapOverlay = null;
switch(overlayType){
case 'timer':
mapOverlay = mapWrapperElement.find('.' + config.mapOverlayTimerClass);
break;
case 'info':
mapOverlay = mapWrapperElement.find('.' + config.mapOverlayInfoClass);
break;
case 'local':
mapOverlay = mapWrapperElement.find('.' + config.overlayLocalClass);
break;
}
return mapOverlay;
};
/**
* draws the map update counter to the map overlay timer
* @param percent
* @param value
* @returns {*}
*/
$.fn.setMapUpdateCounter = function(percent, value){
let mapOverlayTimer = $(this);
// check if counter already exists
let counterChart = mapOverlayTimer.getMapCounter();
if(counterChart.length === 0){
// create new counter
counterChart = $('