Latest changes to Inventory help. Re-styled dialogs. Fixed presentation so that Next and Previous are possible. Added close button.

This commit is contained in:
Chris Houseknecht
2014-01-31 17:32:10 -05:00
parent a21332a2d4
commit 763ed5241d
6 changed files with 202 additions and 168 deletions

View File

@@ -7,59 +7,59 @@
* *
* @dict * @dict
*/ */
angular.module('InventoryGroupsHelpDefinition', []) angular.module('InventoryGroupsHelpDefinition', [])
.value( .value(
'InventoryGroupsHelp', { 'InventoryGroupsHelp', {
story: { story: {
hdr: 'Building your inventory', hdr: 'Building your inventory',
steps: { width: 510,
step1: { height: 560,
intro: 'Start by creating a group:', steps: [
img: { src: 'groups001.png', maxWidth: 338 , maxHeight: 222 }, {
box: "Click <i class=\"fa fa-plus\"></i> on the groups list (the left side of the page) to add a new group.", intro: 'Start by creating a group:',
autoOffNotice: true, img: { src: 'groups001.png', maxWidth: 338 , maxHeight: 222 },
height: 500 box: "Click <i class=\"fa fa-plus\"></i> on the groups list (the left side of the page) to add a new group.",
}, autoOffNotice: true
step2: { },
intro: ' ', {
img: { src: 'groups002.png', maxWidth: 443, maxHeight: 251 }, intro: 'Enter group properties:',
box: "Provide a name, description and any variables.", img: { src: 'groups002.png', maxWidth: 443, maxHeight: 251 },
height: 500 box: 'Enter the group name, a description and any inventory variables. Variables can be entered using either JSON or YAML syntax. ' +
}, 'For more on inventory variables, see <a href=\"http://docs.ansible.com/intro_inventory.html\" target="_blank"> ' +
step3: { 'docs.ansible.com/intro_inventory.html</a>'
intro: ' ', },
img: { src: 'groups003.png', maxWidth: 412, maxHeight: 215 }, {
box: "If this is a cloud inventory, choose a Source and provide credentials.", intro: 'Cloud inventory: select cloud source',
height: 500 img: { src: 'groups003.png', maxWidth: 412, maxHeight: 215 },
}, box: "For a cloud inventory, choose the cloud provider from the list and select your credentials. If you have not already setup " +
step4: { "credentials for the provider, you will need to do that first on the <a href=\"/#/credentials\" " +
intro: ' ', "target=\"_blank\">Credentials</a> tab."
img: { src: 'groups004.png', maxWidth: 261, maxHeight: 221 }, },
box: "For a cloud inventory, start the sync process by clicking <i class=\"fa fa-exchange\"></i>.", {
height: 500 intro: 'Cloud inventory: synchronize Tower with the cloud',
}, img: { src: 'groups004.png', maxWidth: 261, maxHeight: 221 },
step5: { box: "To pull the cloud inventory into Tower, initiate an inventory sync by clicking <i class=\"fa fa-exchange\"></i>.",
intro: "Groups can have subgroups:", },
img: { src: 'groups005.png', maxWidth: 430, maxHeight: 206 }, {
box: "<div class=\"text-left\">First, select a group. Then click <i class=\"fa fa-plus\"></i> to create a new group. The new group " + intro: "Groups can have subgroups:",
"will be added to the selected group.</div>", img: { src: 'groups005.png', maxWidth: 430, maxHeight: 206 },
height: 500 box: "<div class=\"text-left\">First, select a group. Then click <i class=\"fa fa-plus\"></i> to create a new group. The new group " +
}, "will be added to the selected group.</div>"
step6: { },
intro: 'Copy or move groups:', {
img: { src: 'groups006.png', maxWidth: 263, maxHeight: 211 }, intro: 'Copy or move groups:',
box: "<div class=\"text-left\">Copy or move a group by dragging and dropping its name onto another group name. A dialog will appear asking " + img: { src: 'groups006.png', maxWidth: 263, maxHeight: 211 },
"if the group should be coppied or moved.</div>", box: "<div class=\"text-left\">Copy or move a group by dragging and dropping its name onto another group name. A dialog will appear " +
height: 500 "asking if the group should be coppied or moved.</div>"
}, },
step7: { {
intro: 'Next, add hosts:', intro: 'Adding hosts:',
img: { src: 'groups007.png', maxWidth: 466, maxHeight: 178 }, img: { src: 'groups007.png', maxWidth: 466, maxHeight: 178 },
box: "<div class=\"text-left\"><p>First, select a Group. " + box: "<div class=\"text-left\"><p>First, select a Group. " +
"Then click <i class=\"fa fa-plus\"></i> on the hosts list (the right side of the page) to create a host. " + "Then click <i class=\"fa fa-plus\"></i> on the hosts list (the right side of the page) to create a host. " +
"The new host will be part of the selected group.</p><p>Note hosts cannot be added to the All Hosts group.</p></div>", "The new host will be part of the selected group.</p><p>Note hosts cannot be added to the All Hosts group.</p></div>"
height: 500
}
} }
]
} }
}); });

View File

@@ -78,6 +78,7 @@ angular.module('JobsHelper', ['Utilities', 'FormGenerator', 'JobSummaryDefinitio
y = (500 > wh) ? wh : 500; y = (500 > wh) ? wh : 500;
maxrows = 10; maxrows = 10;
} }
// Create the modal // Create the modal
$('#status-modal-dialog').dialog({ $('#status-modal-dialog').dialog({
buttons: { "OK": function() { $( this ).dialog( "close" ); } }, buttons: { "OK": function() { $( this ).dialog( "close" ); } },

View File

@@ -75,7 +75,7 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
$rootScope.breadcrumbs = []; $rootScope.breadcrumbs = [];
var paths = $location.path().split('/'); var paths = $location.path().split('/');
paths.splice(0,1); paths.splice(0,1);
var path, title; var path, title, j;
for (var i=0; i < paths.length; i++) { for (var i=0; i < paths.length; i++) {
if (/^\d+/.test(paths[i])) { if (/^\d+/.test(paths[i])) {
path=''; path='';

View File

@@ -17,6 +17,7 @@
@blue-link: #1778c3; @blue-link: #1778c3;
@blue-dark: #2a6496; /* link hover */ @blue-dark: #2a6496; /* link hover */
@grey: #A9A9A9; @grey: #A9A9A9;
@grey-txt: #707070;
@well: #f5f5f5; /* well background color */ @well: #f5f5f5; /* well background color */
@info: #d9edf7; /* alert info background color */ @info: #d9edf7; /* alert info background color */
@info-border: #bce8f1; /* alert info border color */ @info-border: #bce8f1; /* alert info border color */
@@ -1341,37 +1342,35 @@ tr td button i {
margin-bottom: 5px; margin-bottom: 5px;
} }
/* help dialog */
/* Help modal dialog */
#help-modal { #help-modal {
overflow: hidden; overflow: hidden;
padding: 10px; padding: 10px;
text-align: center;
img {
max-width: 450px;
margin-top: 15px;
margin-bottom: 15px;
border: 1px solid @grey;
box-shadow: 3px 3px 5px 0 @grey;
}
}
#help-modal .img-container {
width: 100%;
text-align: center;
} }
.help-box { .help-box {
text-align: center; width: 100%;
border: 1px solid @info-border; margin-top: 15px;
border-radius: 6px; border-radius: 6px;
margin-top: 10px; padding: 8px;
margin-bottom: 10px; color: @grey-txt;
padding: 10px; font-size: 14px;
background-color: @info; }
color: @info-color;
}
.help-intro {
width: 100;
text-align: left;
margin: 15px 0 30px 0;
font-weight: normal;
font-size: 16px;
color: #888;
}
.step-no {
font-weight: bold;
}
/* Activity Stream Widget */ /* Activity Stream Widget */

View File

@@ -57,8 +57,14 @@
} }
.ui-dialog-buttonset { .ui-dialog-buttonset {
button.btn.btn-default.ui-state-hover,
button.btn.btn-default.ui-state-active,
button.btn.btn-default.ui-state-focus {
font-weight: normal;
}
button.btn.btn-primary.ui-state-hover, button.btn.btn-primary.ui-state-hover,
button.btn.btn-primary.ui-state-active { button.btn.btn-primary.ui-state-active,
button.btn.btn-primary.ui-state-focus {
background-image: none; background-image: none;
color: @white; color: @white;
background-color: @blue-dark; background-color: @blue-dark;

View File

@@ -29,6 +29,13 @@ angular.module('Utilities',['RestServices', 'Utilities'])
$(this).remove(); $(this).remove();
}); });
try {
$('#help-modal').dialog('close');
}
catch(e) {
// ignore
}
$(window).unbind('resize'); $(window).unbind('resize');
} }
@@ -250,112 +257,133 @@ angular.module('Utilities',['RestServices', 'Utilities'])
// HelpDialog({ defn: <HelpDefinition> }) // HelpDialog({ defn: <HelpDefinition> })
// //
function showHelp(params) { var defn = params.defn;
// Using a function inside a function so we can recurse var current_step = params.step;
// over the steps in the help story var autoShow = params.autoShow || false;
var defn = params.defn; function showHelp(step) {
var nxtStory = { story: { steps: { } } }; var width, height, isOpen=false;
var width, height; current_step = step;
var autoShow = params.autoShow || false;
function buildHtml(step) { function buildHtml(step) {
var html = ''; var html = '';
html += (step.intro) ? "<div class=\"help-intro\">" + step.intro + "</div>" : ""; //html += (step.intro) ? "<div class=\"help-intro\">" + step.intro + "</div>" : "";
if (step.img) { html += "<h4>" + step.intro + "</h4>\n";
html += "<img src=\"" + $basePath + "img/help/" + step.img.src + "\" "; html += "<div class=\"img-container\">\n";
html += "style=\""; html += "<img src=\"" + $basePath + "img/help/" + step.img.src + "\" >";
html += (step.img.maxWidth) ? "max-width:" + step.img.maxWidth + "px;" : ""; html += "</div>\n";
html += (step.img.maxHeight) ? " max-height: " + step.img.maxHeight + "px;" : ""; html += "<div class=\"help-box\">" + step.box + "</div>";
html += "\" ";
html += ">";
}
html += (step.box) ? "<div class=\"help-box\">" + step.box + "</div>" : "";
html += (autoShow && step.autoOffNotice) ? "<div class=\"help-auto-off\"><label><input type=\"checkbox\" name=\"auto-off-checkbox\" " + 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" : ""; "id=\"auto-off-checkbox\"> Do not show this message in the future</label></div>\n" : "";
return html; return html;
} }
var nxt; width = (defn.story.width) ? defn.story.width : 510;
for (var step in defn.story.steps) { height = (defn.story.height) ? defn.story.height : 600;
nxt = step;
break; // Limit modal width to width of viewport
} var ww = $(document).width();
width = (width > ww) ? ww : width;
width = (defn.story.steps[nxt].width !== undefined) ? defn.story.steps[nxt].width : 500;
height = (defn.story.steps[nxt].height !== undefined) ? defn.story.steps[nxt].height : 600;
if (Object.keys(defn.story.steps).length > 1) {
// We have multiple steps
for (var step in defn.story.steps) {
if (step !== nxt) {
nxtStory.story.steps[step] = defn.story.steps[step];
}
}
nxtStory.story.hdr = defn.story.hdr;
var nxtStep = function() { try {
showHelp({ defn: nxtStory }); isOpen = $('#help-modal').dialog('isOpen');
} }
catch(e) {
try { // ignore
$('#help-modal').dialog('hide'); }
}
catch(e) { if (isOpen) {
// ignore $('#help-modal').html(buildHtml(defn.story.steps[current_step]));
}
$('#help-modal').html(buildHtml(defn.story.steps[nxt])).dialog({
position: { my: "center top", at: "center top+150", of: 'body' },
title: defn.story.hdr,
width: width,
height: height,
buttons: [{ text: "Next", click: nxtStep }],
closeOnEscape: true,
show: 500,
hide: 500,
close: function() { $('#help-modal').empty(); },
focus: function() { $('.ui-dialog-buttonset button').blur(); }
});
$('.ui-dialog-buttonset button').attr({ 'class': 'btn btn-primary' }).blur();
$('.ui-dialog[aria-describedby="help-modal"]').find('.ui-dialog-titlebar button')
.empty().attr({ 'class': 'close' }).text('x');
} }
else { else {
try { // Define buttons based on story length
$('#help-modal').dialog('hide'); var btns = [];
} if (defn.story.steps.length > 1) {
catch(e) { btns.push({
// ignore text: "Prev",
} click: function(e, ui) {
$('#help-modal').html(buildHtml(defn.story.steps[nxt])).dialog({ if (current_step - 1 == 0) {
position: { my: "center top", at: "center top+150", of: 'body' }, $(e.target).button('disable');
title: defn.story.hdr, }
width: width, if (current_step - 1 < defn.story.steps.length - 1) {
height: height, $(e.target).next().button('enable');
buttons: [ { text: "OK", click: function() { $( this ).dialog( "close" ); } } ], }
closeOnEscape: true, showHelp(current_step - 1);
show: 500, },
hide: 500, disabled: true
close: function() { $('#help-modal').empty(); }, });
focus: function() { $('.ui-dialog-buttonset button').blur(); } btns.push({
}); text: "Next",
$('.ui-dialog-buttonset button').attr({ 'class': 'btn btn-primary' }).blur(); click: function(e, ui) {
$('.ui-dialog[aria-describedby="help-modal"]').find('.ui-dialog-titlebar button') if (current_step + 1 > 0) {
.empty().attr({ 'class': 'close' }).text('x'); $(e.target).prev().button('enable');
}
if (current_step + 1 == defn.story.steps.length - 1) {
$(e.target).button('disable');
}
showHelp(current_step + 1);
}
});
}
btns.push({ text: "Close",
click: function() { $('#help-modal').dialog('close'); }
});
// Show the dialog
$('#help-modal').html(buildHtml(defn.story.steps[current_step])).dialog({
position: { my: "center top", at: "center top+150", of: 'body' },
title: defn.story.hdr,
width: width,
height: height,
buttons: btns,
closeOnEscape: true,
show: 500,
hide: 500,
close: function() { $('#help-modal').empty(); },
resizeStop: function(e, ui) {
// for some reason, after resizing the dialog the content doesn't expand to 100%
var dialog = $('.ui-dialog[aria-describedby="help-modal"]');
var content = dialog.find('#help-modal');
content.width( dialog.width() - 20);
}
});
// Make the buttons look like TB and add FA icons
$('.ui-dialog-buttonset button').each( function(idx) {
var c, h, l;
l = $(this).text();
if (l === 'Close') {
h = "fa-times";
c = "btn btn-default";
$(this).attr({ 'class': c }).html("<i class=\"fa " + h + "\"></i> Close");
}
else if (l === 'Prev') {
h = "fa-chevron-left";
c = "btn btn-primary";
$(this).attr({ 'class': c }).html("<i class=\"fa " + h + "\"></i> Prev");
}
else {
h = "fa-chevron-right";
c = "btn btn-primary";
$(this).attr({ 'class': c }).html("Next <i class=\"fa " + h + "\"></i>").css({ 'margin-right': '20px'});
}
});
$('.ui-dialog[aria-describedby="help-modal"]').find('.ui-dialog-titlebar button')
.empty().attr({ 'class': 'close' }).text('x');
// If user clicks the checkbox, update local storage
$('#auto-off-checkbox').click(function() {
if ($('input[name="auto-off-checkbox"]:checked').length) {
Store('inventoryAutoHelp','off');
}
else {
Store('inventoryAutoHelp','on');
}
});
} }
// If user clicks the checkbox, update local storage
$('#auto-off-checkbox').click(function() {
if ($('input[name="auto-off-checkbox"]:checked').length) {
Store('inventoryAutoHelp','off');
}
else {
Store('inventoryAutoHelp','on');
}
});
} }
showHelp(params); showHelp(0);
} }
}]) }])