1
0
mirror of https://github.com/ansible/awx.git synced 2024-11-01 08:21:15 +03:00

Websocket Help

Show browser aware help for troubleshooting web socket connection problems.
This commit is contained in:
Chris Houseknecht 2014-07-28 16:59:10 -04:00
parent f231c31038
commit ccf974ed83
18 changed files with 300 additions and 57 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -101,7 +101,8 @@ angular.module('Tower', [
'JobDetailHelper',
'SocketIO',
'lrInfiniteScroll',
'LoadConfigHelper'
'LoadConfigHelper',
'SocketHelper'
])
.constant('AngularScheduler.partials', $basePath + 'lib/angular-scheduler/lib/')
@ -409,9 +410,9 @@ angular.module('Tower', [
}])
.run(['$compile', '$cookieStore', '$rootScope', '$log', 'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'ViewLicense',
'Timer', 'ClearScope', 'HideStream', 'Socket', 'LoadConfig', 'Store',
'Timer', 'ClearScope', 'HideStream', 'Socket', 'LoadConfig', 'Store', 'ShowSocketHelp',
function ($compile, $cookieStore, $rootScope, $log, CheckLicense, $location, Authorization, LoadBasePaths, ViewLicense,
Timer, ClearScope, HideStream, Socket, LoadConfig, Store) {
Timer, ClearScope, HideStream, Socket, LoadConfig, Store, ShowSocketHelp) {
var e, html, sock, checkCount = 0;
@ -421,16 +422,16 @@ angular.module('Tower', [
if (ua.search("MSIE") >= 0) {
browser = "MSIE";
}
else if (navigator.userAgent.search("Chrome") >= 0) {
else if (navigator.userAgent.search("Chrome") >= 0 && navigator.userAgent.search("OPR") < 0) {
browser = "CHROME";
}
else if (navigator.userAgent.search("Firefox") >= 0) {
browser = "FF";
}
else if (navigator.userAgent.search("Safari") >= 0 && navigator.userAgent.search("Chrome") < 0) {
else if (navigator.userAgent.search("Safari") >= 0 && navigator.userAgent.search("Chrome") < 0 && navigator.userAgent.search("OPR") < 0) {
browser = "SAFARI";
}
else if (navigator.userAgent.search("Opera") >= 0) {
else if (navigator.userAgent.search("OPR") >= 0) {
browser = "OPERA";
}
return browser;
@ -540,8 +541,12 @@ angular.module('Tower', [
$('#' + tabs + ' #' + tab).tab('show');
};
html = "<a href=\"\" aw-pop-over=\"{{ socketTip }}\" aw-pop-over-watch=\"socketTip\" data-placement=\"bottom\" data-trigger=\"hover\" " +
"data-popover-title=\"Live Updates\" data-container=\"body\" style=\"font-size: 10px;\"><i class=\"fa icon-socket-{{ socketStatus }}\"></i></a>";
$rootScope.socketHelp = function() {
ShowSocketHelp();
};
html = "<a href=\"\" ng-click=\"socketHelp()\" aw-pop-over=\"{{ socketTip }}\" aw-pop-over-watch=\"socketTip\" data-placement=\"bottom\" data-trigger=\"hover\" " +
"data-popover-title=\"Live Events\" data-container=\"body\" style=\"font-size: 10px;\"><i class=\"fa icon-socket-{{ socketStatus }}\"></i></a>";
e = angular.element(document.getElementById('socket-beacon-div'));
e.empty().append(html);
$compile(e)($rootScope);

View File

@ -0,0 +1,39 @@
/*********************************************
* Copyright (c) 2014 AnsibleWorks, Inc.
*
* ChromeSocketHelp.js
*
* Help object for socket connection troubleshooting
*
*/
'use strict';
angular.module('ChromeSocketHelpDefinition', [])
.value('ChromeSocketHelp', {
story: {
hdr: 'Live Events',
width: 510,
height: 560,
steps: [{
intro: 'Connection status indicator:',
img: {
src: 'socket_indicator.png',
maxWidth: 360
},
box: "<p>When live events are streaming the connection status indicator will be green. Red or orange indicates the " +
"browser is having difficulty connecting to the server, and live events are no longer being received.</p><p>If the indicator " +
"appears red or orange, click next for troubleshooting help.</p>"
}, {
intro: 'Live events connection:',
icon: {
"class": "fa fa-5x fa-rss {{ socketStatus }}-color",
style: "margin-top: 75px;",
containerHeight: 200
},
box: "<p><strong>{{ browserName }}</strong> is connecting to the live events server on port <strong>{{ socketPort }}</strong>. The current connection status is " +
"<i class=\"fa icon-socket-{{ socketStatus }}\"></i> <strong>{{ socketStatus }}</strong>.</p><p>If the connection status indicator is not green, have the " +
"system administrator verify this is the correct port and that access to the port is not blocked by a firewall."
}]
}
});

View File

@ -0,0 +1,77 @@
/*********************************************
* Copyright (c) 2014 AnsibleWorks, Inc.
*
* FireFoxSocketHelp.js
*
* Help object for socket connection troubleshooting
*
*/
'use strict';
angular.module('FFSocketHelpDefinition', [])
.value('FFSocketHelp', {
story: {
hdr: 'Live Events',
width: 510,
height: 560,
steps: [{
intro: 'Connection status indicator:',
img: {
src: 'socket_indicator.png',
maxWidth: 360
},
box: "<p>When live events are streaming the connection status indicator will be green. Red or orange indicates the " +
"browser is having difficulty connecting to the server, and live events are no longer being received.</p><p>If the indicator " +
"appears red or orange, click Next for troubleshooting help.</p>"
}, {
intro: 'Live events connection:',
icon: {
"class": "fa fa-5x fa-rss {{ socketStatus }}-color",
style: "margin-top: 75px;",
containerHeight: 200
},
box: "<p><strong>{{ browserName }}</strong> is connecting to the live events server on port <strong>{{ socketPort }}</strong>. The current connection status is " +
"<i class=\"fa icon-socket-{{ socketStatus }}\"></i> <strong>{{ socketStatus }}</strong>.</p><p>If the connection status indicator is not green, have the " +
"system administrator verify this is the correct port and that access to the port is not blocked by a firewall.</p>"
}, {
intro: 'Self signed certificate:',
icon: {
"class": "fa fa-5x fa-check ok-color",
style: "margin-top: 75px;",
containerHeight: 200
},
box: "<p>If the Tower web server is using a self signed security certificate, Firefox needs to accept the certificate and allow the " +
"connection.</p><p>Click Next for help accepting a self signed certificate.</p>"
}, {
intro: 'Accepting a self-signed certificate:',
img: {
src: 'understand_the_risk.png',
maxWidth: 440
},
box: "<p>Navigate to <a href=\"{{ socketURL }}\" target=\"_blank\">{{ socketURL }}</a> The above warning will appear.</p><p>Click <i>I Understand the Risks</i></p>"
}, {
intro: 'Accepting a self-signed certificate:',
img: {
src: 'add_exception.png',
maxWidth: 440
},
box: "<p>Click the <i>Add Exception</i> button."
}, {
intro: 'Accepting a self-signed certificate:',
img: {
src: 'confirm_exception.png',
maxWidth: 340
},
box: "<p>Click the <i>Confirm the Security Exception</i> button. This will add the self signed certificate from the Tower server to Firefox's list of trusted certificates.<p>"
}, {
intro: 'Accepting a self-signed certificate:',
img: {
src: 'refresh_firefox.png',
maxWidth: 480
},
box: "<p>Now that Firefox has accepted the security certificate the live event connection status indicator should turn green. If it does not, reload Tower by clicking the " +
"Firefox refresh button."
}]
}
});

View File

@ -0,0 +1,49 @@
/*********************************************
* Copyright (c) 2014 AnsibleWorks, Inc.
*
* SafairSocketHelp.js
*
* Help object for socket connection troubleshooting
*
*/
'use strict';
angular.module('SafariSocketHelpDefinition', [])
.value('SafariSocketHelp', {
story: {
hdr: 'Live Events',
width: 510,
height: 560,
steps: [{
intro: 'Connection status indicator:',
img: {
src: 'socket_indicator.png',
maxWidth: 360
},
box: "<p>When live events are streaming the connection status indicator will be green. Red or orange indicates the " +
"browser is having difficulty connecting to the server, and live events are no longer being received.</p><p>If the indicator " +
"appears red or orange, click next for troubleshooting help.</p>"
}, {
intro: 'Live events connection:',
icon: {
"class": "fa fa-5x fa-rss {{ socketStatus }}-color",
style: "margin-top: 75px;",
containerHeight: 200
},
box: "<p><strong>{{ browserName }}</strong> is connecting to the live events server on port <strong>{{ socketPort }}</strong>. The current connection status is " +
"<i class=\"fa icon-socket-{{ socketStatus }}\"></i> <strong>{{ socketStatus }}</strong>.</p><p>If the connection status indicator is not green, have the " +
"system administrator verify this is the correct port and that access to the port is not blocked by a firewall.</p>"
}, {
intro: 'Self signed certificate:',
icon: {
"class": "fa fa-5x fa-check ok-color",
style: "margin-top: 75px;",
containerHeight: 200
},
box: "<p>Safari will not connect to the live event port when the Tower web server is configured with a self signed certificate. Check with a system administrator to" +
"determine if Tower is using a self signed certificate. Installing a signed certificate will fix the problem.</p>" +
"<p>Switching browsers to either Chrome or Firefox will work as well.</p>"
}]
}
});

View File

@ -0,0 +1,41 @@
/*********************************************
* Copyright (c) 2014 AnsibleWorks, Inc.
*
* SocketHelper.js
*
* Show web socket troubleshooting help
*
*/
'use strict';
angular.module('SocketHelper', ['Utilities', 'FFSocketHelpDefinition', 'SafariSocketHelpDefinition' , 'ChromeSocketHelpDefinition'])
.factory('ShowSocketHelp', ['$location', '$rootScope', 'FFSocketHelp', 'SafariSocketHelp', 'ChromeSocketHelp', 'HelpDialog',
function($location, $rootScope, FFSocketHelp, SafariSocketHelp, ChromeSocketHelp, HelpDialog) {
return function() {
var scope = $rootScope.$new();
scope.socketPort = $AnsibleConfig.websocket_port;
scope.socketURL = 'https://' + $location.host() + ':' + scope.socketPort + '/';
if ($rootScope.browser === "FF") {
scope.browserName = "Firefox";
HelpDialog({ defn: FFSocketHelp, scope: scope });
}
else if ($rootScope.browser === "SAFARI") {
scope.browserName = "Safari";
HelpDialog({ defn: SafariSocketHelp, scope: scope });
}
else {
if ($rootScope.browser === "MSIE") {
scope.browserName = "Internet Explorer";
}
else if ($rootScope.browser === "CHROME") {
scope.browserName = "Chrome";
}
else if ($rootScope.browser === "OPERA") {
scope.browserName = "Opera";
}
HelpDialog({ defn: ChromeSocketHelp, scope: scope });
}
};
}]);

View File

@ -1125,8 +1125,17 @@ input[type="checkbox"].checkbox-no-label {
content: "\f111";
}
.error-color {
color:@red;
}
.connecting-color {
color: @warning;
}
.ok-color,
.icon-cloud-true {
color: @green;
color: @green;
}
.icon-cloud-false {
@ -1511,34 +1520,37 @@ tr td button i {
/* Help modal dialog */
#help-modal {
#help-modal-dialog {
overflow: hidden;
padding: 10px;
img {
max-width: 450px;
margin-top: 15px;
margin-bottom: 15px;
border: 1px solid @grey;
box-shadow: 3px 3px 5px 0 @grey;
}
margin-top: 15px;
margin-bottom: 15px;
border: 1px solid @grey;
box-shadow: 3px 3px 5px 0 @grey;
}
.img-container,
.icon-container {
width: 100%;
text-align: center;
}
.icon-container {
margin-top: 15px;
margin-bottom: 15px;
}
.help-box {
width: 100%;
margin-top: 15px;
border-radius: 6px;
color: @grey-txt;
font-size: 14px;
}
}
#help-modal .img-container {
width: 100%;
text-align: center;
}
.help-box {
width: 100%;
margin-top: 15px;
border-radius: 6px;
padding: 8px;
color: @grey-txt;
font-size: 14px;
}
/* Activity Stream Widget */
#stream-container {

View File

@ -37,14 +37,13 @@ angular.module('SocketIO', ['AuthService', 'Utilities'])
var result = '';
switch(status) {
case 'error':
result = "There was an error connecting to the websocket server. Click for troubleshooting help.";
result = "Live events: error connecting to the Tower server. Click for troubleshooting help.";
break;
case 'connecting':
result = "Attempting to connect to the websocket server. Click for troubleshooting help.";
result = "Live events: attempting to connect to the Tower server. Click for troubleshooting help.";
break;
case "ok":
result = "Connected to the websocket server. Pages containing job status information for playbook runs, SCM updates and inventory " +
"sync processes will automatically update in real-time.";
result = "Live events: connected. Pages containing job status information will automatically update in real-time.";
}
return result;
}

View File

@ -312,26 +312,43 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
* HelpDialog({ defn: <HelpDefinition> })
*
*/
.factory('HelpDialog', ['$rootScope', '$location', 'Store',
function ($rootScope, $location, Store) {
.factory('HelpDialog', ['$rootScope', '$compile', '$location', 'Store',
function ($rootScope, $compile, $location, Store) {
return function (params) {
var defn = params.defn,
current_step = params.step,
autoShow = params.autoShow || false;
autoShow = params.autoShow || false,
scope = (params.scope) ? params.scope : $rootScope.$new();
function setButtonMargin() {
var width = ($('.ui-dialog[aria-describedby="help-modal-dialog"] .ui-dialog-buttonpane').innerWidth() / 2) - $('#help-next-button').outerWidth() - 93;
$('#help-next-button').css({'margin-right': width + 'px'});
}
function showHelp(step) {
var btns, ww, width, height, isOpen = false;
var e, btns, ww, width, height, isOpen = false;
current_step = step;
function buildHtml(step) {
var html = '';
//html += (step.intro) ? "<div class=\"help-intro\">" + step.intro + "</div>" : "";
html += "<h4>" + step.intro + "</h4>\n";
html += "<div class=\"img-container\">\n";
html += "<img src=\"" + $basePath + "img/help/" + step.img.src + "\" >";
html += "</div>\n";
if (step.img) {
html += "<div class=\"img-container\">\n";
html += "<img src=\"" + $basePath + "img/help/" + step.img.src + "\" ";
html += (step.img.maxWidth) ? "style=\"max-width:" + step.img.maxWidth + "px\" " : "";
html += ">";
html += "</div>\n";
}
if (step.icon) {
html += "<div class=\"icon-container\"";
html += (step.icon.containerHeight) ? "style=\"height:" + step.icon.containerHeight + "px;\">\n" : "";
html += "<i class=\"" + step.icon['class'] + "\" ";
html += (step.icon.style) ? "style=\"" + step.icon.style + "\" " : "";
html += "></i>\n";
html += "</div>\n";
}
html += "<div class=\"help-box\">" + step.box + "</div>";
html += (autoShow && step.autoOffNotice) ? "<div class=\"help-auto-off\"><label><input type=\"checkbox\" " +
"name=\"auto-off-checkbox\" id=\"auto-off-checkbox\"> Do not show this message in the future</label></div>\n" : "";
@ -346,14 +363,16 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
width = (width > ww) ? ww : width;
try {
isOpen = $('#help-modal').dialog('isOpen');
} catch (e) {
isOpen = $('#help-modal-dialog').dialog('isOpen');
} catch (err) {
// ignore
}
if (isOpen) {
$('#help-modal').html(buildHtml(defn.story.steps[current_step]));
} else {
e = angular.element(document.getElementById('help-modal-dialog'));
e.empty().html(buildHtml(defn.story.steps[current_step]));
setTimeout(function() { scope.$apply(function() { $compile(e)(scope); }); });
if (!isOpen) {
// Define buttons based on story length
btns = [];
if (defn.story.steps.length > 1) {
@ -386,11 +405,11 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
btns.push({
text: "Close",
click: function () {
$('#help-modal').dialog('close');
$('#help-modal-dialog').dialog('close');
}
});
// Show the dialog
$('#help-modal').html(buildHtml(defn.story.steps[current_step])).dialog({
$('#help-modal-dialog').dialog({
position: {
my: "center top",
at: "center top+150",
@ -405,7 +424,7 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
hide: 500,
resizable: false,
close: function () {
$('#help-modal').empty();
$('#help-modal-dialog').empty();
}
});
@ -442,7 +461,7 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
}
});
$('.ui-dialog[aria-describedby="help-modal"]').find('.ui-dialog-titlebar button')
$('.ui-dialog[aria-describedby="help-modal-dialog"]').find('.ui-dialog-titlebar button')
.empty().attr({
'class': 'close'
}).text('x');
@ -455,11 +474,12 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
Store('inventoryAutoHelp', 'on');
}
});
setButtonMargin();
}
}
showHelp(0);
};
}
])

View File

@ -25,5 +25,3 @@
<div ng-include="'/static/partials/schedule_dialog.html'"></div>
<div ng-include="'/static/partials/logviewer.html'"></div>
<div id="host-modal-dialog" style="display: none;" class="dialog-content"></div>

View File

@ -125,6 +125,7 @@
<script src="{{ STATIC_URL }}js/lists/Hosts.js"></script>
<script src="{{ STATIC_URL }}js/lists/Schedules.js"></script>
<script src="{{ STATIC_URL }}js/lists/ScheduledJobs.js"></script>
<script src="{{ STATIC_URL }}js/helpers/SocketHelper.js"></script>
<script src="{{ STATIC_URL }}js/helpers/LoadConfig.js"></script>
<script src="{{ STATIC_URL }}js/helpers/refresh-related.js"></script>
<script src="{{ STATIC_URL }}js/helpers/related-search.js"></script>
@ -163,6 +164,9 @@
<script src="{{ STATIC_URL }}js/widgets/DashboardJobs.js"></script>
<script src="{{ STATIC_URL }}js/widgets/Stream.js"></script>
<script src="{{ STATIC_URL }}js/help/InventoryGroups.js"></script>
<script src="{{ STATIC_URL }}js/help/FireFoxSocketHelp.js"></script>
<script src="{{ STATIC_URL }}js/help/SafariSocketHelp.js"></script>
<script src="{{ STATIC_URL }}js/help/ChromeSocketHelp.js"></script>
{% endif %}
</head>
@ -388,8 +392,7 @@
</div><!-- modal-dialog -->
</div><!-- modal -->
<!-- Help dialog -->
<div id="help-modal" style="display: none;"></div>
<div id="help-modal-dialog" style="display: none;"></div>
</div><!-- container -->