diff --git a/awx/ui/static/css/custom-theme/jquery-ui-1.10.3.custom.css b/awx/ui/static/css/custom-theme/jquery-ui-1.10.3.custom.css index a05b962cc1..a268ebf601 100644 --- a/awx/ui/static/css/custom-theme/jquery-ui-1.10.3.custom.css +++ b/awx/ui/static/css/custom-theme/jquery-ui-1.10.3.custom.css @@ -608,7 +608,7 @@ button.ui-button::-moz-focus-inner { height: 100%; } .ui-progressbar .ui-progressbar-overlay { - background: url("images/animated-overlay.gif"); + background: url("/static/css/custom-theme/images/animated-overlay.gif"); height: 100%; filter: alpha(opacity=25); opacity: 0.25; @@ -806,7 +806,7 @@ body .ui-tooltip { } .ui-widget-content { border: 1px solid #a6c9e2; - background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; + background: #fcfdfd url(/static/css/custom-theme/images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #36454F; font-weight: normal; } @@ -815,7 +815,7 @@ body .ui-tooltip { } .ui-widget-header { border: 1px solid #a6c9e2; - background: #ffffff url(images/ui-bg_flat_50_ffffff_40x100.png) 50% 50% repeat-x; + background: #ffffff url(/static/css/custom-theme/images/ui-bg_flat_50_ffffff_40x100.png) 50% 50% repeat-x; color: #36454F; font-weight: bold; } @@ -829,7 +829,7 @@ body .ui-tooltip { .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #a6c9e2; - background: #ffffff url(images/ui-bg_flat_100_ffffff_40x100.png) 50% 50% repeat-x; + background: #ffffff url(/static/css/custom-theme/images/ui-bg_flat_100_ffffff_40x100.png) 50% 50% repeat-x; font-weight: bold; color: #0088cc; } @@ -846,7 +846,7 @@ body .ui-tooltip { .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #e3e3e3; - background: #e5e3e3 url(images/ui-bg_flat_75_e5e3e3_40x100.png) 50% 50% repeat-x; + background: #e5e3e3 url(/static/css/images/ui-bg_flat_75_e5e3e3_40x100.png) 50% 50% repeat-x; font-weight: bold; color: #005580; } @@ -861,7 +861,7 @@ body .ui-tooltip { .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #e3e3e3; - background: #f5f5f5 url(images/ui-bg_inset-hard_100_f5f5f5_1x100.png) 50% 50% repeat-x; + background: #f5f5f5 url(/static/css/custom-theme/images/ui-bg_inset-hard_100_f5f5f5_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #36454F; } @@ -878,7 +878,7 @@ body .ui-tooltip { .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight { border: 1px solid #fad42e; - background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x; + background: #fbec88 url(/static/css/custom-theme/images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x; color: #363636; } .ui-state-highlight a, @@ -890,7 +890,7 @@ body .ui-tooltip { .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error { border: 1px solid #cd0a0a; - background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; + background: #fef1ec url(/static/css/custom-theme/images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } .ui-state-error a, @@ -936,27 +936,27 @@ body .ui-tooltip { } .ui-icon, .ui-widget-content .ui-icon { - background-image: url(images/ui-icons_469bdd_256x240.png); + background-image: url(/static/css/custom-theme/images/ui-icons_469bdd_256x240.png); } .ui-widget-header .ui-icon { - background-image: url(images/ui-icons_36454F_256x240.png); + background-image: url(/static/css/custom-theme/images/ui-icons_36454F_256x240.png); } .ui-state-default .ui-icon { - background-image: url(images/ui-icons_0088cc_256x240.png); + background-image: url(/static/css/custom-theme/images/ui-icons_0088cc_256x240.png); } .ui-state-hover .ui-icon, .ui-state-focus .ui-icon { - background-image: url(images/ui-icons_217bc0_256x240.png); + background-image: url(/static/css/custom-theme/images/ui-icons_217bc0_256x240.png); } .ui-state-active .ui-icon { - background-image: url(images/ui-icons_36454F_256x240.png); + background-image: url(/static/css/custom-theme/images/ui-icons_36454F_256x240.png); } .ui-state-highlight .ui-icon { - background-image: url(images/ui-icons_2e83ff_256x240.png); + background-image: url(/static/css/custom-theme/images/ui-icons_2e83ff_256x240.png); } .ui-state-error .ui-icon, .ui-state-error-text .ui-icon { - background-image: url(images/ui-icons_cd0a0a_256x240.png); + background-image: url(/static/css/custom-theme/images/ui-icons_cd0a0a_256x240.png); } /* positioning */ @@ -1169,14 +1169,14 @@ body .ui-tooltip { /* Overlays */ .ui-widget-overlay { - background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; + background: #aaaaaa url(/static/css/custom-theme/images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .3; filter: Alpha(Opacity=30); } .ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; - background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; + background: #aaaaaa url(/static/css/custom-theme/images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .3; filter: Alpha(Opacity=30); border-radius: 8px; diff --git a/awx/ui/static/img/help/help001.png b/awx/ui/static/img/help/help001.png new file mode 100644 index 0000000000..0455fa7f8b Binary files /dev/null and b/awx/ui/static/img/help/help001.png differ diff --git a/awx/ui/static/img/help/help002.png b/awx/ui/static/img/help/help002.png new file mode 100644 index 0000000000..f2df800be8 Binary files /dev/null and b/awx/ui/static/img/help/help002.png differ diff --git a/awx/ui/static/js/app.js b/awx/ui/static/js/app.js index 5af7f5541b..ae2831ac18 100644 --- a/awx/ui/static/js/app.js +++ b/awx/ui/static/js/app.js @@ -75,7 +75,8 @@ angular.module('ansible', [ 'SCMSyncStatusWidget', 'ObjectCountWidget', 'JobsHelper', - 'InventoryStatusDefinition' + 'InventoryStatusDefinition', + 'InventorySummaryHelpDefinition' ]) .config(['$routeProvider', function($routeProvider) { $routeProvider. diff --git a/awx/ui/static/js/controllers/Groups.js b/awx/ui/static/js/controllers/Groups.js index 42eb95f02a..18f293c461 100644 --- a/awx/ui/static/js/controllers/Groups.js +++ b/awx/ui/static/js/controllers/Groups.js @@ -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' ]; \ No newline at end of file diff --git a/awx/ui/static/js/controllers/Hosts.js b/awx/ui/static/js/controllers/Hosts.js index 3c354fb151..1e49b9f966 100644 --- a/awx/ui/static/js/controllers/Hosts.js +++ b/awx/ui/static/js/controllers/Hosts.js @@ -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' ]; diff --git a/awx/ui/static/js/help/InventorySummary.js b/awx/ui/static/js/help/InventorySummary.js new file mode 100644 index 0000000000..f58bc7382e --- /dev/null +++ b/awx/ui/static/js/help/InventorySummary.js @@ -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 Create New 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 Hosts using the drop-down menu, where you can add hosts to the new group", + height: 480 + } + } + } + }); \ No newline at end of file diff --git a/awx/ui/static/js/helpers/Groups.js b/awx/ui/static/js/helpers/Groups.js index 2555f8f5ab..2dee159da2 100644 --- a/awx/ui/static/js/helpers/Groups.js +++ b/awx/ui/static/js/helpers/Groups.js @@ -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 Refresh ' + + '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 Refresh ' + - '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 ' + @@ -433,6 +455,8 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', ' } } } + + ShowGroupHelp({ scope: scope }); } }]) diff --git a/awx/ui/static/js/helpers/inventory.js b/awx/ui/static/js/helpers/inventory.js index 1106e17288..54c1e79fab 100644 --- a/awx/ui/static/js/helpers/inventory.js +++ b/awx/ui/static/js/helpers/inventory.js @@ -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 }); }); } }]) diff --git a/awx/ui/static/js/lists/InventorySummary.js b/awx/ui/static/js/lists/InventorySummary.js index 374245cd91..9146d238a0 100644 --- a/awx/ui/static/js/lists/InventorySummary.js +++ b/awx/ui/static/js/lists/InventorySummary.js @@ -109,22 +109,13 @@ angular.module('InventorySummaryDefinition', []) dataPlacement: 'top' }, help: { - awPopOver: - "
\n" + - "
failed
Errors were encountered with the most recent inventory update.
\n" + - "
n/a
The group is not configured for inventory update.
\n" + - "
never
The inventory update has never run for the group.
\n" + - "
successful
The most recent inventory update ran to completion without incident.
\n" + - "
updating
The inventory update is currently running.
\n" + - "
\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, diff --git a/awx/ui/static/js/lists/JobHosts.js b/awx/ui/static/js/lists/JobHosts.js index 5358879aad..38ed204d73 100644 --- a/awx/ui/static/js/lists/JobHosts.js +++ b/awx/ui/static/js/lists/JobHosts.js @@ -109,7 +109,7 @@ angular.module('JobHostDefinition', []) "
Unreachable
Times the ansible server could not reach the host.
\n" + "
Skipped
Tasks bypassed and not performed on the host due to prior task failure or the host being unreachable.
\n" + "\n", - dataPlacement: 'top', + dataPlacement: 'left', dataContainer: "body", icon: "icon-question-sign", mode: 'all', diff --git a/awx/ui/static/js/lists/Projects.js b/awx/ui/static/js/lists/Projects.js index ca74747ca9..d4a2937924 100644 --- a/awx/ui/static/js/lists/Projects.js +++ b/awx/ui/static/js/lists/Projects.js @@ -60,7 +60,7 @@ angular.module('ProjectsListDefinition', []) "
Missing
The local project directory is missing.
\n" + "
N/A
The project does not use SCM, so an update status is not available.
\n" + "\n", - dataPlacement: 'top', + dataPlacement: 'left', dataContainer: 'body', icon: "icon-question-sign", mode: 'all', diff --git a/awx/ui/static/js/widgets/ObjectCount.js b/awx/ui/static/js/widgets/ObjectCount.js index c61e11be49..e677e6b688 100644 --- a/awx/ui/static/js/widgets/ObjectCount.js +++ b/awx/ui/static/js/widgets/ObjectCount.js @@ -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 = "
\n"; html += "
System Summary
\n"; html += "
\n"; diff --git a/awx/ui/static/less/ansible-ui.less b/awx/ui/static/less/ansible-ui.less index 046bc5bf44..01279404b2 100644 --- a/awx/ui/static/less/ansible-ui.less +++ b/awx/ui/static/less/ansible-ui.less @@ -7,15 +7,18 @@ * */ -@black: #171717; -@warning: #FF9900; -@red: #da4f49; -@red-hover: #AE3F3A; -@green: #5bb75b; -@blue: #1778c3; /* logo blue */ -@blue-link: #0088cc; -@grey: #A9A9A9; -@green: #5bb75b; +@black: #171717; +@warning: #FF9900; +@red: #da4f49; +@red-hover: #AE3F3A; +@green: #5bb75b; +@blue: #1778c3; /* logo blue */ +@blue-link: #0088cc; +@grey: #A9A9A9; +@green: #5bb75b; +@info: #d9edf7; /* alert info background color */ +@info-border: #bce8f1; /* alert info border color */ +@info-color: #3a87ad; html { background-color: @black; @@ -1204,6 +1207,44 @@ tr td button i { margin-bottom: 5px; } +/* help dialog */ + +#help-modal { + overflow: hidden; + padding: 10px; + text-align: center; +} + +.help-box { + text-align: center; + border: 1px solid @info-border; + border-radius: 6px; + margin-top: 0; + margin-bottom: 10px; + padding: 10px; + 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; +} + +.ui-dialog-titlebar.ui-widget-header { + color: #0088cc; + background-color: #F0F0F0; + background-image: none; +} + /* Large desktop */ diff --git a/awx/ui/static/lib/ansible/Utilities.js b/awx/ui/static/lib/ansible/Utilities.js index 8240d3bef2..0f11e5d876 100644 --- a/awx/ui/static/lib/ansible/Utilities.js +++ b/awx/ui/static/lib/ansible/Utilities.js @@ -5,7 +5,7 @@ * Utility functions * */ -angular.module('Utilities',['RestServices']) +angular.module('Utilities',['RestServices', 'Utilities']) .factory('ClearScope', function() { return function(id) { @@ -219,6 +219,83 @@ angular.module('Utilities',['RestServices']) } } }]) + + .factory('HelpDialog', ['$rootScope', '$location', function($rootScope, $location) { + return function(params) { + // Display a help dialog + // + // HelpDialog({ defn: }) + // + + function showHelp(params) { + // Using a function inside a function so we can recurse + // over the steps in the help story + + var defn = params.defn; + var nxtStory = { story: { steps: { } } }; + var width, height; + + function buildHtml(step) { + var html = ''; + html += (step.intro) ? "
" + step.intro + "
" : ""; + html += (step.img) ? "" : ""; + html += (step.box) ? "
" + step.box + "
" : ""; + return html; + } + + var nxt; + for (var step in defn.story.steps) { + nxt = step; + break; + } + + 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; + + nxtStep = function() { + showHelp({ defn: nxtStory }); + } + + $('#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, + close: function() { $('#help-modal').empty(); } + }); + $('.ui-dialog-buttonset button').addClass('btn btn-primary').focus(); + $('.ui-dialog-titlebar-close').empty().removeClass('close').removeClass('ui-dialog-titlebar-close').addClass('close').append('x'); + } + else { + $('#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: "OK", click: function() { $( this ).dialog( "close" ); } } ], + closeOnEscape: true, + close: function() { $('#help-modal').empty(); } + }); + $('.ui-dialog-buttonset button').addClass('btn btn-primary').focus(); + $('.ui-dialog-titlebar button').empty().removeClass('close').removeClass('ui-dialog-titlebar-close').addClass('close').append('x'); + } + } + + showHelp(params); + + } + }]) .factory('ReturnToCaller', ['$location', function($location) { return function(idx) { diff --git a/awx/ui/static/lib/ansible/form-generator.js b/awx/ui/static/lib/ansible/form-generator.js index 75eb3705e2..7d7bc873fb 100644 --- a/awx/ui/static/lib/ansible/form-generator.js +++ b/awx/ui/static/lib/ansible/form-generator.js @@ -105,11 +105,13 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies']) label.addClass('prepend-asterisk'); } }); - - // Remove leftover timer, if any - //if ((!options.modal) && this.scope.timer) { - // clearInterval(this.scope.timer); - //} + + try { + $('#help-modal').empty().dialog('destroy'); + } + catch(e) { + //ignore any errors should the dialog not be initialized + } if (options.modal) { this.scope.formModalActionDisabled = false; @@ -1198,12 +1200,12 @@ angular.module('FormGenerator', ['GeneratorHelpers', 'ngCookies']) html += this.breadCrumbs(options, navigation); // build the groups page - html += "
\n"; - html += "\n"; - html += "

Hint: Get started building your inventory by adding a group. After creating a group, " + - "use the Inventories->Hosts page to " + - "add hosts to the group.

"; - html += "
\n"; + //html += "
\n"; + //html += "\n"; + //html += "

Hint: Get started building your inventory by adding a group. After creating a group " + + // "go to the Hosts page to " + + // "add hosts to the group.

"; + //html += "
\n"; /* html += "
\n"; diff --git a/awx/ui/static/lib/ansible/list-generator.js b/awx/ui/static/lib/ansible/list-generator.js index de280e2fd9..a27902d933 100644 --- a/awx/ui/static/lib/ansible/list-generator.js +++ b/awx/ui/static/lib/ansible/list-generator.js @@ -72,6 +72,13 @@ angular.module('ListGenerator', ['GeneratorHelpers']) // remove lingering popover
. Seems to be a bug in TB3 RC1 $(this).remove(); }); + + try { + $('#help-modal').empty().dialog('destroy'); + } + catch(e) { + //ignore any errors should the dialog not be initialized + } if (options.mode == 'lookup') { // options should include {hdr: , action: } diff --git a/awx/ui/templates/ui/index.html b/awx/ui/templates/ui/index.html index 1fb2bdf440..db1138495e 100644 --- a/awx/ui/templates/ui/index.html +++ b/awx/ui/templates/ui/index.html @@ -14,7 +14,9 @@ {% endif %} - + @@ -112,6 +114,7 @@ + {% endif %} @@ -336,7 +339,10 @@
- + + +
+