Created new help widget and applied to Inventory-> Groups. Help can now be a movable dialog with images and text. Help definitions (objects) can include many steps to tell a story or walk through a process.

This commit is contained in:
chouseknecht
2013-10-15 02:56:39 -04:00
parent c563f040ba
commit 4bcda34c3c
18 changed files with 257 additions and 106 deletions

View File

@@ -75,7 +75,8 @@ angular.module('ansible', [
'SCMSyncStatusWidget',
'ObjectCountWidget',
'JobsHelper',
'InventoryStatusDefinition'
'InventoryStatusDefinition',
'InventorySummaryHelpDefinition'
])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.

View File

@@ -10,7 +10,7 @@
function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeParams, InventoryGroupsForm,
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, Prompt,
TreeInit, GetBasePath, GroupsList, GroupsAdd, GroupsEdit, LoadInventory,
GroupsDelete, RefreshGroupName, EditInventory, SetShowGroupHelp, InventoryStatus)
GroupsDelete, RefreshGroupName, EditInventory, InventoryStatus)
{
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
//scope.
@@ -34,7 +34,6 @@ function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeP
scope.inventoryLoadedRemove = scope.$on('inventoryLoaded', function() {
LoadBreadCrumbs({ path: '/inventories/' + id, title: scope.inventory_name });
TreeInit(scope.TreeParams);
SetShowGroupHelp({ scope: scope });
if (!scope.$$phase) {
scope.$digest();
}
@@ -242,6 +241,6 @@ function InventoryGroups ($scope, $rootScope, $compile, $location, $log, $routeP
InventoryGroups.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'InventoryGroupsForm',
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'Prompt',
'TreeInit', 'GetBasePath', 'GroupsList', 'GroupsAdd', 'GroupsEdit', 'LoadInventory',
'GroupsDelete', 'RefreshGroupName', 'EditInventory', 'SetShowGroupHelp', 'InventoryStatus'
'GroupsDelete', 'RefreshGroupName', 'EditInventory', 'InventoryStatus'
];

View File

@@ -13,7 +13,7 @@ function InventoryHosts ($scope, $rootScope, $compile, $location, $log, $routePa
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit,
RelatedPaginateInit, ReturnToCaller, ClearScope, LookUpInit, Prompt,
GetBasePath, HostsList, HostsAdd, HostsEdit, HostsDelete,
HostsReload, LoadSearchTree, EditHostGroups, SetShowGroupHelp)
HostsReload, LoadSearchTree, EditHostGroups)
{
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
//scope.
@@ -36,7 +36,6 @@ function InventoryHosts ($scope, $rootScope, $compile, $location, $log, $routePa
}
scope.loadBreadCrumbsRemove = scope.$on('buildAllGroups', function(e, inventory_name) {
LoadBreadCrumbs({ path: '/inventories/' + id, title: inventory_name });
SetShowGroupHelp({ scope: scope });
});
// Sets up the search tree and loads All Hosts for the inventory
@@ -138,6 +137,6 @@ InventoryHosts.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$lo
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit',
'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'LookUpInit', 'Prompt',
'GetBasePath', 'HostsList', 'HostsAdd', 'HostsEdit', 'HostsDelete',
'HostsReload', 'LoadSearchTree', 'EditHostGroups', 'SetShowGroupHelp'
'HostsReload', 'LoadSearchTree', 'EditHostGroups'
];

View File

@@ -0,0 +1,29 @@
/*********************************************
* Copyright (c) 2013 AnsibleWorks, Inc.
*
* InventorySummary.js
* Help object for Inventory-> Groups page.
*
* @dict
*/
angular.module('InventorySummaryHelpDefinition', [])
.value(
'InventorySummaryHelp', {
story: {
hdr: 'Getting Started',
steps: {
step1: {
intro: 'Start by creating a group:',
img: 'help002.png',
box: "Click the <em>Create New</em> button and add a new group to the inventory.",
height: 400
},
step2: {
intro: 'After creating a group, add hosts:',
img: 'help001.png',
box: "Navigate to <em>Hosts</em> using the drop-down menu, where you can add hosts to the new group",
height: 480
}
}
}
});

View File

@@ -9,7 +9,8 @@
angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'GroupListDefinition',
'SearchHelper', 'PaginateHelper', 'ListGenerator', 'AuthService', 'GroupsHelper',
'InventoryHelper', 'SelectionHelper', 'JobSubmissionHelper', 'RefreshHelper'
'InventoryHelper', 'SelectionHelper', 'JobSubmissionHelper', 'RefreshHelper',
'PromptDialog', 'InventorySummaryHelpDefinition'
])
.factory('GetSourceTypeOptions', [ function() {
@@ -169,9 +170,10 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
.factory('InventoryStatus', [ '$rootScope', '$routeParams', 'Rest', 'Alert', 'ProcessErrors', 'GetBasePath', 'FormatDate', 'InventorySummary',
'GenerateList', 'ClearScope', 'SearchInit', 'PaginateInit', 'Refresh', 'InventoryUpdate', 'GroupsEdit', 'ShowUpdateStatus',
'GenerateList', 'ClearScope', 'SearchInit', 'PaginateInit', 'Refresh', 'InventoryUpdate', 'GroupsEdit', 'ShowUpdateStatus', 'HelpDialog',
'ShowGroupHelp', 'InventorySummaryHelp',
function($rootScope, $routeParams, Rest, Alert, ProcessErrors, GetBasePath, FormatDate, InventorySummary, GenerateList, ClearScope, SearchInit,
PaginateInit, Refresh, InventoryUpdate, GroupsEdit, ShowUpdateStatus) {
PaginateInit, Refresh, InventoryUpdate, GroupsEdit, ShowUpdateStatus, HelpDialog, ShowGroupHelp, InventorySummaryHelp) {
return function(params) {
//Build a summary of a given inventory
@@ -267,6 +269,17 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
}
scope.search(list.iterator);
if (scope.removeShowHelp) {
scope.removeShowHelp();
}
scope.removeShowHelp = scope.$on('ShowHelp', function() {
HelpDialog({ defn: InventorySummaryHelp });
});
scope.showHelp = function() {
scope.$emit('ShowHelp');
}
scope.viewUpdateStatus = function(id) {
var found = false;
@@ -365,20 +378,29 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
break;
}
}
if (found && group.related.current_update) {
Rest.setUrl(group.related.current_update);
Rest.get()
.success( function(data, status, headers, config) {
scope.$emit('Check_Cancel', data);
})
.error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, null,
{ hdr: 'Error!', msg: 'Call to ' + group.related.current_update + ' failed. GET status: ' + status });
});
if (group.summary_fields.inventory_source.source !== '' &&
group.summary_fields.inventory_source.source !== null) {
// the group has a source
if (group.related.current_update) {
// there is an update currently running
Rest.setUrl(group.related.current_update);
Rest.get()
.success( function(data, status, headers, config) {
scope.$emit('Check_Cancel', data);
})
.error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, null,
{ hdr: 'Error!', msg: 'Call to ' + group.related.current_update + ' failed. GET status: ' + status });
});
}
else {
Alert('Update Not Found', 'An Inventory update does not appear to be running for group: ' + name + '. Click the <em>Refresh</em> ' +
'button to view the latet status.', 'alert-info');
}
}
else {
Alert('Update Not Found', 'An Inventory update does not appear to be running for group: ' + name + '. Click the <em>Refresh</em> ' +
'button to view the latet status.', 'alert-info');
Alert('Missing Configuration', 'The selected group is not configured for updates. You must first edit the group and provide external Source settings ' +
'before attempting an update.', 'alert-info');
}
}
@@ -394,8 +416,8 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
for (var i=0; i < scope.groups.length; i++) {
if (scope.groups[i].id == id) {
if (scope.groups[i].summary_fields.inventory_source.source == "" || scope.groups[i].summary_fields.inventory_source.source == null) {
Alert('Missing Configuration', 'The selected group is not configured for updates. You must first edit the group, provide Source settings, ' +
'and then run an update.', 'alert-info');
Alert('Missing Configuration', 'The selected group is not configured for updates. You must first edit the group and provide ' +
'external Source settings before attempting an update.', 'alert-info');
}
else if (scope.groups[i].summary_fields.inventory_source.status == 'updating') {
Alert('Update in Progress', 'The inventory update process is currently running for group <em>' +
@@ -433,6 +455,8 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', '
}
}
}
ShowGroupHelp({ scope: scope });
}
}])

View File

@@ -560,25 +560,20 @@ angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationLi
}
}])
.factory('SetShowGroupHelp', ['Rest', 'ProcessErrors', 'GetBasePath', function(Rest, ProcessErrors, GetBasePath) {
.factory('ShowGroupHelp', ['Rest', 'ProcessErrors', 'GetBasePath', function(Rest, ProcessErrors, GetBasePath) {
return function(params) {
// Check if inventory has groups. If not, turn on hints to let user know groups are required
// before hosts can be added
var scope = params.scope;
var url = GetBasePath('inventory') + scope.inventory_id + '/groups/';
var url = GetBasePath('inventory') + scope.inventory_id + '/groups/?page=1';
Rest.setUrl(url);
Rest.get()
.success( function(data, status, headers, config) {
if (data.results.length > 0) {
scope.showGroupHelp = false;
}
else {
scope.showGroupHelp = true;
}
scope.$emit('ShowHelp');
})
.error( function(data, status, headers, config) {
ProcessErrors(scope, data, status, form,
{ hdr: 'Error!', msg: 'Failed to retrieve inventory groups. GET returned status: ' + status });
{ hdr: 'Error!', msg: 'Failed to retrieve inventory group count. ' + url + ' GET status: ' + status });
});
}
}])

View File

@@ -109,22 +109,13 @@ angular.module('InventorySummaryDefinition', [])
dataPlacement: 'top'
},
help: {
awPopOver:
"<dl>\n" +
"<dt>failed</dt><dd>Errors were encountered with the most recent inventory update.</dd>\n" +
"<dt>n/a</dt><dd>The group is not configured for inventory update.</dd>\n" +
"<dt>never</dt><dd>The inventory update has never run for the group.</dd>\n" +
"<dt>successful</dt><dd>The most recent inventory update ran to completion without incident.</dd>\n" +
"<dt>updating</dt><dd>The inventory update is currently running.</dd>\n" +
"</dl>\n",
dataPlacement: 'top',
dataContainer: 'body',
icon: "icon-question-sign",
mode: 'all',
'class': 'btn-xs btn-info btn-help',
awToolTip: 'Click for help',
dataTitle: 'Update Status',
iconSize: 'large'
iconSize: 'large',
ngClick: "showHelp()"
},
refresh: {
awRefresh: true,

View File

@@ -109,7 +109,7 @@ angular.module('JobHostDefinition', [])
"<dt>Unreachable</dt><dd>Times the ansible server could not reach the host.</dd>\n" +
"<dt>Skipped</dt><dd>Tasks bypassed and not performed on the host due to prior task failure or the host being unreachable.</dd>\n" +
"</dl>\n",
dataPlacement: 'top',
dataPlacement: 'left',
dataContainer: "body",
icon: "icon-question-sign",
mode: 'all',

View File

@@ -60,7 +60,7 @@ angular.module('ProjectsListDefinition', [])
"<dt>Missing</dt><dd>The local project directory is missing.</dd>\n" +
"<dt>N/A</dt><dd>The project does not use SCM, so an update status is not available.</dd>\n" +
"</dl>\n",
dataPlacement: 'top',
dataPlacement: 'left',
dataContainer: 'body',
icon: "icon-question-sign",
mode: 'all',

View File

@@ -31,26 +31,6 @@ angular.module('ObjectCountWidget', ['RestServices', 'Utilities'])
cnt++;
}
if (cnt == expected) {
// sort the list of objs
//for (var key in counts) {
// if (key !== 'hosts' && key !== 'groups') {
// keys.push(key);
// }
//}
// sort the keys, forcing groups and hosts to appear directlry after inventory
//keys.sort();
//var new_keys = [];
//for (var i=0; i < keys.length; i++) {
// if (keys[i] == 'inventory') {
// new_keys.push('inventory');
// new_keys.push('groups');
// new_keys.push('hosts');
// }
// else {
// new_keys.push(keys[i]);
// }
//}
//keys = new_keys;
html = "<div class=\"panel panel-default\">\n";
html += "<div class=\"panel-heading\">System Summary</div>\n";
html += "<div class=\"panel-body\">\n";