- updated "maintenance hint" with new release information v1.4.1

- improved "maintenance hint" rendering, toggle visibility by HTTP response header
This commit is contained in:
Mark Friedrich
2018-09-26 13:53:19 +02:00
parent 6e9920bd93
commit b157b5bd0b
10 changed files with 185 additions and 189 deletions

View File

@@ -173,6 +173,9 @@ class System extends Controller\AccessController {
if($cacheSystem){
$f3->set($cacheKey, $graphData, $ttl);
}
}else{
// server cache data exists -> client should cache as well
$cacheResponse = true;
}
$graphsData[$systemId] = $graphData;
}

View File

@@ -76,7 +76,12 @@ class Controller {
$this->initSession($f3);
if($f3->get('AJAX')){
header('Content-type: application/json');
header('Content-Type: application/json');
// send "maintenance" Header -> e.g. before server update
if($modeMaintenance = (int)Config::getPathfinderData('login.mode_maintenance')){
header('Pf-Maintenance: ' . $modeMaintenance);
}
}else{
$this->initResource($f3);

View File

@@ -141,7 +141,7 @@ abstract class AbstractSlackWebhookHandler extends Handler\AbstractProcessingHan
CURLOPT_URL => $this->webhookUrl,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-type: application/json'],
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => $postString
];
if (defined('CURLOPT_SAFE_UPLOAD')) {

View File

@@ -39,7 +39,6 @@ define([
Util.initDefaultEditableConfig();
// load page
// load info (maintenance) info panel (if scheduled)
$('body').loadPageStructure().setGlobalShortcuts();
// show app information in browser console
@@ -203,11 +202,6 @@ define([
// init map module
mapModule.initMapModule();
// load info (maintenance) info panel (if scheduled)
if(Init.programMode.maintenance){
$('body').showGlobalInfoPanel();
}
resolve({
action: 'initMapModule',
data: false

View File

@@ -58,9 +58,7 @@ define([
headProgramStatusClass: 'pf-head-program-status', // class for "program status" notification
// footer
pageFooterId: 'pf-footer', // id for page footer
footerLicenceLinkClass: 'pf-footer-licence', // class for "licence" link
globalInfoPanelId: 'pf-global-info', // id for "global info panel"
// menu
menuHeadMenuLogoClass: 'pf-head-menu-logo', // class for main menu logo
@@ -582,7 +580,7 @@ define([
let pageElement = $(this);
let moduleData = {
id: config.pageFooterId,
id: Util.config.footerId,
footerLicenceLinkClass: config.footerLicenceLinkClass,
currentYear: new Date().getFullYear()
};
@@ -1263,25 +1261,6 @@ define([
}
};
/**
* show information panel to active users (on bottom)
* @returns {*|jQuery|HTMLElement}
*/
$.fn.showGlobalInfoPanel = function(){
let body = $(this);
let infoTemplate = 'text!templates/ui/info_panel.html';
requirejs([infoTemplate, 'mustache'], function(template, Mustache){
let data = {
id: config.globalInfoPanelId
};
let content = $( Mustache.render(template, data) );
content.insertBefore('#' + config.pageFooterId );
});
return body;
};
/**
* get all form Values as object
* this includes all xEditable fields
@@ -1331,5 +1310,4 @@ define([
initMapContextMenus: initMapContextMenus
};
});

View File

@@ -43,6 +43,10 @@ define([
menuButtonCompactId: 'pf-menu-button-compact', // id for menu button "compact" UI map view
menuButtonMapDeleteId: 'pf-menu-button-map-delete', // id for menu button "delete map"
// footer
footerId: 'pf-footer', // id for page footer
globalInfoPanelId: 'pf-global-info', // id for "global info panel"
settingsMessageVelocityOptions: {
duration: 180
},
@@ -212,33 +216,6 @@ define([
});
};
/**
* request a captcha image
* @param reason
* @param callback
*/
let getCaptchaImage = function(reason, callback){
$.ajax({
type: 'POST',
url: Init.path.getCaptcha,
data: {
reason: reason
},
dataType: 'json'
}).done(function(responseData){
if(responseData.error.length > 0){
showNotify({title: 'getCaptchaImage', text: 'Captcha image gneration failed', type: 'error'});
}else{
callback(responseData.img);
}
}).fail(function(jqXHR, status, error){
let reason = status + ' ' + error;
showNotify({title: jqXHR.status + ': getCaptchaImage', text: reason, type: 'error'});
});
};
/**
* reset/clear form fields
* @returns {*}
@@ -855,6 +832,26 @@ define([
});
};
/**
* get all mapTabElements (<a> tags)
* or search for a specific tabElement within mapModule
* @param mapId
* @returns {JQuery|*|{}|T}
*/
$.fn.getMapTabElements = function(mapId){
let mapModule = $(this);
let mapTabElements = mapModule.find('#' + config.mapTabBarId).find('a');
if(mapId){
// search for a specific tab element
mapTabElements = mapTabElements.filter(function(i, el){
return ( $(el).data('mapId') === mapId );
});
}
return mapTabElements;
};
/*
* ===============================================================================================================
* Util functions that are global available for all modules
@@ -865,14 +862,14 @@ define([
* get current Pathfinder version number
* @returns {*|jQuery}
*/
let getVersion = function(){
let getVersion = () => {
return $('body').data('version');
};
/**
* show current program version information in browser console
*/
let showVersionInfo = function(){
let showVersionInfo = () => {
console.info('PATHFINDER ' + getVersion());
};
@@ -1140,6 +1137,31 @@ define([
'<div class="editableform-loading"><i class="fas fa-lg fa-sync fa-spin"></i></div>';
};
/**
* request a captcha image
* @param reason
* @param callback
*/
let getCaptchaImage = (reason, callback) => {
$.ajax({
type: 'POST',
url: Init.path.getCaptcha,
data: {
reason: reason
},
dataType: 'json'
}).done(function(responseData){
if(responseData.error.length > 0){
showNotify({title: 'getCaptchaImage', text: 'Captcha image generation failed', type: 'error'});
}else{
callback(responseData.img);
}
}).fail(function(jqXHR, status, error){
let reason = status + ' ' + error;
showNotify({title: jqXHR.status + ': getCaptchaImage', text: reason, type: 'error'});
});
};
/**
* get the current main trigger delay for the main trigger functions
* optional in/decrease the delay
@@ -1237,7 +1259,6 @@ define([
* @param timerName
*/
let timeStart = timerName => {
if(typeof performance === 'object'){
stopTimerCache[timerName] = performance.now();
}else{
@@ -1251,7 +1272,6 @@ define([
* @returns {number}
*/
let timeStop = timerName => {
let duration = 0;
if( stopTimerCache.hasOwnProperty(timerName) ){
@@ -1324,8 +1344,8 @@ define([
/**
* stop browser tab title "blinking"
*/
let stopTabBlink = function(){
requirejs(['notification'], function(Notification){
let stopTabBlink = () => {
requirejs(['notification'], Notification => {
Notification.stopTabBlink();
});
};
@@ -1408,6 +1428,26 @@ define([
return tabId;
};
/**
* show information panel to active users (on bottom)
* @param show
*/
let toggleGlobalInfoPanel = (show = true) => {
let infoPanel = $('#' + config.globalInfoPanelId);
if( show && !infoPanel.length){
// info panel not already shown
requirejs(['text!templates/ui/info_panel.html', 'mustache'], (template, Mustache) => {
let data = {
id: config.globalInfoPanelId
};
let content = $(Mustache.render(template, data));
content.insertBefore('#' + config.footerId);
});
}else if (!show && infoPanel.length){
infoPanel.remove();
}
};
/**
* set default jQuery AJAX configuration
*/
@@ -1422,8 +1462,13 @@ define([
if(settings.crossDomain === false){
// add current character data to ANY XHR request (HTTP HEADER)
// -> This helps to identify multiple characters on multiple browser tabs
jqXHR.setRequestHeader('Pf-Character', getCurrentCharacterId());
jqXHR.setRequestHeader('pf-character', getCurrentCharacterId());
}
},
complete: function(jqXHR, textStatus){
// show "maintenance information panel -> if scheduled
let isMaintenance = parseInt(jqXHR.getResponseHeader('pf-maintenance')) || 0;
toggleGlobalInfoPanel(isMaintenance);
}
});
};
@@ -1559,26 +1604,6 @@ define([
});
};
/**
* get all mapTabElements (<a> tags)
* or search for a specific tabElement within mapModule
* @param mapId
* @returns {JQuery|*|{}|T}
*/
$.fn.getMapTabElements = function(mapId){
let mapModule = $(this);
let mapTabElements = mapModule.find('#' + config.mapTabBarId).find('a');
if(mapId){
// search for a specific tab element
mapTabElements = mapTabElements.filter(function(i, el){
return ( $(el).data('mapId') === mapId );
});
}
return mapTabElements;
};
/**
* get mapElement from overlay or any child of that
* @param mapOverlay
@@ -1896,7 +1921,7 @@ define([
* @param trueSec
* @returns {string}
*/
let getTrueSecClassForSystem = function(trueSec){
let getTrueSecClassForSystem = (trueSec) => {
let trueSecClass = '';
trueSec = parseFloat(trueSec);
@@ -1926,8 +1951,7 @@ define([
* @param option
* @returns {string}
*/
let getStatusInfoForSystem = function(status, option){
let getStatusInfoForSystem = (status, option) => {
let statusInfo = '';
if( Init.systemStatus.hasOwnProperty(status) ){
@@ -1970,10 +1994,8 @@ define([
* @param sigGroupId
* @returns {{}}
*/
let getAllSignatureNames = function(systemTypeId, areaId, sigGroupId){
let getAllSignatureNames = (systemTypeId, areaId, sigGroupId) => {
let signatureNames = {};
if(
SignatureType[systemTypeId] &&
SignatureType[systemTypeId][areaId] &&
@@ -2198,7 +2220,7 @@ define([
* get the current log data for the current user character
* @returns {boolean}
*/
let getCurrentCharacterLog = function(){
let getCurrentCharacterLog = () => {
let characterLog = false;
let currentUserData = getCurrentUserData();
@@ -2382,7 +2404,7 @@ define([
* @param systemData
* @param type
*/
let setDestination = function(systemData, type){
let setDestination = (systemData, type) => {
let description = '';
switch(type){
case 'set_destination':
@@ -2551,7 +2573,7 @@ define([
* -> system data where current user is located
* @returns {{id: *, name: *}}
*/
let getCurrentLocationData = function(){
let getCurrentLocationData = () => {
let currentLocationLink = $('#' + config.headCurrentLocationId).find('a');
return {
id: currentLocationLink.data('systemId'),
@@ -2563,7 +2585,7 @@ define([
* get all "open" dialog elements
* @returns {*|jQuery}
*/
let getOpenDialogs = function(){
let getOpenDialogs = () => {
return $('.' + config.dialogClass).filter(':visible');
};

View File

@@ -39,7 +39,6 @@ define([
Util.initDefaultEditableConfig();
// load page
// load info (maintenance) info panel (if scheduled)
$('body').loadPageStructure().setGlobalShortcuts();
// show app information in browser console
@@ -203,11 +202,6 @@ define([
// init map module
mapModule.initMapModule();
// load info (maintenance) info panel (if scheduled)
if(Init.programMode.maintenance){
$('body').showGlobalInfoPanel();
}
resolve({
action: 'initMapModule',
data: false

View File

@@ -58,9 +58,7 @@ define([
headProgramStatusClass: 'pf-head-program-status', // class for "program status" notification
// footer
pageFooterId: 'pf-footer', // id for page footer
footerLicenceLinkClass: 'pf-footer-licence', // class for "licence" link
globalInfoPanelId: 'pf-global-info', // id for "global info panel"
// menu
menuHeadMenuLogoClass: 'pf-head-menu-logo', // class for main menu logo
@@ -582,7 +580,7 @@ define([
let pageElement = $(this);
let moduleData = {
id: config.pageFooterId,
id: Util.config.footerId,
footerLicenceLinkClass: config.footerLicenceLinkClass,
currentYear: new Date().getFullYear()
};
@@ -1263,25 +1261,6 @@ define([
}
};
/**
* show information panel to active users (on bottom)
* @returns {*|jQuery|HTMLElement}
*/
$.fn.showGlobalInfoPanel = function(){
let body = $(this);
let infoTemplate = 'text!templates/ui/info_panel.html';
requirejs([infoTemplate, 'mustache'], function(template, Mustache){
let data = {
id: config.globalInfoPanelId
};
let content = $( Mustache.render(template, data) );
content.insertBefore('#' + config.pageFooterId );
});
return body;
};
/**
* get all form Values as object
* this includes all xEditable fields
@@ -1331,5 +1310,4 @@ define([
initMapContextMenus: initMapContextMenus
};
});

View File

@@ -43,6 +43,10 @@ define([
menuButtonCompactId: 'pf-menu-button-compact', // id for menu button "compact" UI map view
menuButtonMapDeleteId: 'pf-menu-button-map-delete', // id for menu button "delete map"
// footer
footerId: 'pf-footer', // id for page footer
globalInfoPanelId: 'pf-global-info', // id for "global info panel"
settingsMessageVelocityOptions: {
duration: 180
},
@@ -212,33 +216,6 @@ define([
});
};
/**
* request a captcha image
* @param reason
* @param callback
*/
let getCaptchaImage = function(reason, callback){
$.ajax({
type: 'POST',
url: Init.path.getCaptcha,
data: {
reason: reason
},
dataType: 'json'
}).done(function(responseData){
if(responseData.error.length > 0){
showNotify({title: 'getCaptchaImage', text: 'Captcha image gneration failed', type: 'error'});
}else{
callback(responseData.img);
}
}).fail(function(jqXHR, status, error){
let reason = status + ' ' + error;
showNotify({title: jqXHR.status + ': getCaptchaImage', text: reason, type: 'error'});
});
};
/**
* reset/clear form fields
* @returns {*}
@@ -855,6 +832,26 @@ define([
});
};
/**
* get all mapTabElements (<a> tags)
* or search for a specific tabElement within mapModule
* @param mapId
* @returns {JQuery|*|{}|T}
*/
$.fn.getMapTabElements = function(mapId){
let mapModule = $(this);
let mapTabElements = mapModule.find('#' + config.mapTabBarId).find('a');
if(mapId){
// search for a specific tab element
mapTabElements = mapTabElements.filter(function(i, el){
return ( $(el).data('mapId') === mapId );
});
}
return mapTabElements;
};
/*
* ===============================================================================================================
* Util functions that are global available for all modules
@@ -865,14 +862,14 @@ define([
* get current Pathfinder version number
* @returns {*|jQuery}
*/
let getVersion = function(){
let getVersion = () => {
return $('body').data('version');
};
/**
* show current program version information in browser console
*/
let showVersionInfo = function(){
let showVersionInfo = () => {
console.info('PATHFINDER ' + getVersion());
};
@@ -1140,6 +1137,31 @@ define([
'<div class="editableform-loading"><i class="fas fa-lg fa-sync fa-spin"></i></div>';
};
/**
* request a captcha image
* @param reason
* @param callback
*/
let getCaptchaImage = (reason, callback) => {
$.ajax({
type: 'POST',
url: Init.path.getCaptcha,
data: {
reason: reason
},
dataType: 'json'
}).done(function(responseData){
if(responseData.error.length > 0){
showNotify({title: 'getCaptchaImage', text: 'Captcha image generation failed', type: 'error'});
}else{
callback(responseData.img);
}
}).fail(function(jqXHR, status, error){
let reason = status + ' ' + error;
showNotify({title: jqXHR.status + ': getCaptchaImage', text: reason, type: 'error'});
});
};
/**
* get the current main trigger delay for the main trigger functions
* optional in/decrease the delay
@@ -1237,7 +1259,6 @@ define([
* @param timerName
*/
let timeStart = timerName => {
if(typeof performance === 'object'){
stopTimerCache[timerName] = performance.now();
}else{
@@ -1251,7 +1272,6 @@ define([
* @returns {number}
*/
let timeStop = timerName => {
let duration = 0;
if( stopTimerCache.hasOwnProperty(timerName) ){
@@ -1324,8 +1344,8 @@ define([
/**
* stop browser tab title "blinking"
*/
let stopTabBlink = function(){
requirejs(['notification'], function(Notification){
let stopTabBlink = () => {
requirejs(['notification'], Notification => {
Notification.stopTabBlink();
});
};
@@ -1408,6 +1428,26 @@ define([
return tabId;
};
/**
* show information panel to active users (on bottom)
* @param show
*/
let toggleGlobalInfoPanel = (show = true) => {
let infoPanel = $('#' + config.globalInfoPanelId);
if( show && !infoPanel.length){
// info panel not already shown
requirejs(['text!templates/ui/info_panel.html', 'mustache'], (template, Mustache) => {
let data = {
id: config.globalInfoPanelId
};
let content = $(Mustache.render(template, data));
content.insertBefore('#' + config.footerId);
});
}else if (!show && infoPanel.length){
infoPanel.remove();
}
};
/**
* set default jQuery AJAX configuration
*/
@@ -1422,8 +1462,13 @@ define([
if(settings.crossDomain === false){
// add current character data to ANY XHR request (HTTP HEADER)
// -> This helps to identify multiple characters on multiple browser tabs
jqXHR.setRequestHeader('Pf-Character', getCurrentCharacterId());
jqXHR.setRequestHeader('pf-character', getCurrentCharacterId());
}
},
complete: function(jqXHR, textStatus){
// show "maintenance information panel -> if scheduled
let isMaintenance = parseInt(jqXHR.getResponseHeader('pf-maintenance')) || 0;
toggleGlobalInfoPanel(isMaintenance);
}
});
};
@@ -1559,26 +1604,6 @@ define([
});
};
/**
* get all mapTabElements (<a> tags)
* or search for a specific tabElement within mapModule
* @param mapId
* @returns {JQuery|*|{}|T}
*/
$.fn.getMapTabElements = function(mapId){
let mapModule = $(this);
let mapTabElements = mapModule.find('#' + config.mapTabBarId).find('a');
if(mapId){
// search for a specific tab element
mapTabElements = mapTabElements.filter(function(i, el){
return ( $(el).data('mapId') === mapId );
});
}
return mapTabElements;
};
/**
* get mapElement from overlay or any child of that
* @param mapOverlay
@@ -1896,7 +1921,7 @@ define([
* @param trueSec
* @returns {string}
*/
let getTrueSecClassForSystem = function(trueSec){
let getTrueSecClassForSystem = (trueSec) => {
let trueSecClass = '';
trueSec = parseFloat(trueSec);
@@ -1926,8 +1951,7 @@ define([
* @param option
* @returns {string}
*/
let getStatusInfoForSystem = function(status, option){
let getStatusInfoForSystem = (status, option) => {
let statusInfo = '';
if( Init.systemStatus.hasOwnProperty(status) ){
@@ -1970,10 +1994,8 @@ define([
* @param sigGroupId
* @returns {{}}
*/
let getAllSignatureNames = function(systemTypeId, areaId, sigGroupId){
let getAllSignatureNames = (systemTypeId, areaId, sigGroupId) => {
let signatureNames = {};
if(
SignatureType[systemTypeId] &&
SignatureType[systemTypeId][areaId] &&
@@ -2198,7 +2220,7 @@ define([
* get the current log data for the current user character
* @returns {boolean}
*/
let getCurrentCharacterLog = function(){
let getCurrentCharacterLog = () => {
let characterLog = false;
let currentUserData = getCurrentUserData();
@@ -2382,7 +2404,7 @@ define([
* @param systemData
* @param type
*/
let setDestination = function(systemData, type){
let setDestination = (systemData, type) => {
let description = '';
switch(type){
case 'set_destination':
@@ -2551,7 +2573,7 @@ define([
* -> system data where current user is located
* @returns {{id: *, name: *}}
*/
let getCurrentLocationData = function(){
let getCurrentLocationData = () => {
let currentLocationLink = $('#' + config.headCurrentLocationId).find('a');
return {
id: currentLocationLink.data('systemId'),
@@ -2563,7 +2585,7 @@ define([
* get all "open" dialog elements
* @returns {*|jQuery}
*/
let getOpenDialogs = function(){
let getOpenDialogs = () => {
return $('.' + config.dialogClass).filter(':visible');
};

View File

@@ -1,4 +1,4 @@
<div id="{{id}}" class="alert alert-warning">
<div class="ui-pnotify-icon"><span class="fas fa-exclamation fa-fw fa-lg"></span></div>
<h4 class="ui-pnotify-title">Scheduled maintenance: <small> Pathfinder upgrade. v1.3.6 <i class="fas fa-long-arrow-alt-right"></i> v1.4.0; Shutdown: ~13:00 (UTC). ETA ~14:00 (UTC)</small></h4>
<h4 class="ui-pnotify-title">Scheduled maintenance: Update <kbd>v1.4.0</kbd> <i class="fas fa-long-arrow-alt-right"></i> <kbd>v1.4.1</kbd>; Shutdown: ~11:00 (UTC). ETA ~11:15 (UTC)</h4>
</div>