From f4bba01271e2e26ff4af74b46d6677edce4876ad Mon Sep 17 00:00:00 2001 From: chouseknecht Date: Tue, 9 Jul 2013 17:07:02 -0400 Subject: [PATCH] Added help pop-overs and new help button to the Add Existing Host s and Add Groups dialogs on Inventories page. --- awx/ui/static/js/awx-min.js | 27 +++++++++++---------- awx/ui/static/js/helpers/Hosts.js | 2 +- awx/ui/static/js/lists/Groups.js | 12 +++++++++ awx/ui/static/js/lists/Hosts.js | 12 ++++++++- awx/ui/static/lib/ansible/list-generator.js | 6 ++++- 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/awx/ui/static/js/awx-min.js b/awx/ui/static/js/awx-min.js index c98ecf834f..3fe35589f5 100644 --- a/awx/ui/static/js/awx-min.js +++ b/awx/ui/static/js/awx-min.js @@ -4,7 +4,7 @@ * * awx-min.js * - * master-9bbee34, Tue Jul 9 15:25:41 2013 -0400 + * master-e3d0344, Tue Jul 9 15:40:33 2013 -0400 * */ var urlPrefix="/static/"; @@ -262,9 +262,9 @@ function(c,e){for(var l=[],a=0;a button to create a new user.',editInstructions:"Create a new credential from either the Teams tab or the Users tab. Teams and Users each have an associated set of Credentials.",index:!0, hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Description"},team:{label:"Team",ngBind:"credential.summary_fields.team.name",sourceModel:"team",sourceField:"name"},user:{label:"User",ngBind:"credential.summary_fields.user.usename",sourceModel:"user",sourceField:"username"}},actions:{add:{icon:"icon-plus",label:"Add",mode:"all",ngClick:"addCredential()",basePaths:["teams","users"],"class":"btn-success btn-small",awToolTip:"Create a new credential"}},fieldActions:{edit:{ngClick:"editCredential({{ credential.id }})", -icon:"icon-edit",label:"Edit","class":"btn-small btn-success",awToolTip:"View/Edit credential"},"delete":{ngClick:"deleteCredential({{ credential.id }},'{{ credential.name }}')",icon:"icon-remove",label:"Delete","class":"btn-small btn-danger",awToolTip:"Delete credential"}}});angular.module("GroupListDefinition",[]).value("GroupList",{name:"groups",iterator:"group",selectTitle:"Add Group",editTitle:"Groups",index:!0,well:!1,fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},actions:{add:{label:"Create New Group",icon:"icon-plus",mode:"all",ngClick:"createGroup()","class":"btn-success btn-small",awToolTip:"Create a new group"}},fieldActions:{edit:{label:"Edit",ngClick:"editGroup({{ group.id }})",icon:"icon-edit","class":"btn-small btn-success",awToolTip:"View/Edit group"}, -"delete":{label:"Delete",ngClick:"deleteGroup({{ group.id }},'{{ group.name }}')",icon:"icon-remove","class":"btn-small btn-danger",awToolTip:"Delete group"}}});angular.module("HostListDefinition",[]).value("HostList",{name:"hosts",iterator:"host",selectTitle:"Select Host",editTitle:"Hosts",index:!0,well:!0,fields:{name:{key:!0,label:"Host Name",linkTo:"/inventories/{{ inventory_id }}/hosts/{{ host.id }}"},description:{label:"Description"}},actions:{},fieldActions:{edit:{label:"Edit",ngClick:"editHost({{ host.id }})",icon:"icon-edit","class":"btn-small btn-success",awToolTip:"View/Edit host"},"delete":{label:"Delete",ngClick:"deleteHost({{ host.id }},'{{ host.name }}')", -icon:"icon-remove","class":"btn-small btn-danger",awToolTip:"Delete host"}}});angular.module("InventoriesListDefinition",[]).value("InventoryList",{name:"inventories",iterator:"inventory",selectTitle:"Add Inventories",editTitle:"Inventories",selectInstructions:'Click on a row to select it, and click Finished when done. Use the green button to create a new row.',index:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Descriptions"},organization:{label:"Organization",ngBind:"inventory.summary_fields.organization.name",sourceModel:"organization", +icon:"icon-edit",label:"Edit","class":"btn-small btn-success",awToolTip:"View/Edit credential"},"delete":{ngClick:"deleteCredential({{ credential.id }},'{{ credential.name }}')",icon:"icon-remove",label:"Delete","class":"btn-small btn-danger",awToolTip:"Delete credential"}}});angular.module("GroupListDefinition",[]).value("GroupList",{name:"groups",iterator:"group",selectTitle:"Add Group",editTitle:"Groups",index:!0,well:!1,fields:{name:{key:!0,label:"Name"},description:{label:"Description"}},actions:{add:{label:"Create New Group",icon:"icon-plus",mode:"all",ngClick:"createGroup()","class":"btn-success btn-small",awToolTip:"Create a new group"},help:{awPopOver:"Select groups by clicking on each group you wish to add. Add the selected groups to your inventory or to the selected parent group by clicking the Select button. You can also create a new group by clicking the Create New Group button.", +dataPlacement:"left",dataContainer:"#form-modal",icon:"icon-question-sign",mode:"all","class":"btn-small btn-info",awToolTip:"Click for help",dataTitle:"Adding Groups"}},fieldActions:{edit:{label:"Edit",ngClick:"editGroup({{ group.id }})",icon:"icon-edit","class":"btn-small btn-success",awToolTip:"View/Edit group"},"delete":{label:"Delete",ngClick:"deleteGroup({{ group.id }},'{{ group.name }}')",icon:"icon-remove","class":"btn-small btn-danger",awToolTip:"Delete group"}}});angular.module("HostListDefinition",[]).value("HostList",{name:"hosts",iterator:"host",selectTitle:"Select Host",editTitle:"Hosts",index:!0,well:!0,fields:{name:{key:!0,label:"Host Name",linkTo:"/inventories/{{ inventory_id }}/hosts/{{ host.id }}"},description:{label:"Description"}},actions:{help:{awPopOver:"Select hosts by clicking on each host you wish to add. Add the selected hosts to the group by clicking the Select button.",dataPlacement:"left",dataContainer:"#form-modal",icon:"icon-question-sign", +mode:"all","class":"btn-small btn-info",awToolTip:"Click for help",dataTitle:"Selecting Hosts"}},fieldActions:{edit:{label:"Edit",ngClick:"editHost({{ host.id }})",icon:"icon-edit","class":"btn-small btn-success",awToolTip:"View/Edit host"},"delete":{label:"Delete",ngClick:"deleteHost({{ host.id }},'{{ host.name }}')",icon:"icon-remove","class":"btn-small btn-danger",awToolTip:"Delete host"}}});angular.module("InventoriesListDefinition",[]).value("InventoryList",{name:"inventories",iterator:"inventory",selectTitle:"Add Inventories",editTitle:"Inventories",selectInstructions:'Click on a row to select it, and click Finished when done. Use the green button to create a new row.',index:!0,hover:!0,fields:{name:{key:!0,label:"Name"},description:{label:"Descriptions"},organization:{label:"Organization",ngBind:"inventory.summary_fields.organization.name",sourceModel:"organization", sourceField:"name"},has_active_failures:{label:"Failed Jobs?",showValue:!1,text:"View failures",ngShow:"{{ inventory.has_active_failures }}",icon:"icon-exclamation-sign","class":"active-failures-{{ inventory.has_active_failures }}",ngClick:"viewJobs({{ inventory.id }})",searchField:"has_active_failures",searchType:"boolean",searchOptions:[{name:"No",value:0},{name:"Yes",value:1}],excludeModal:!0}},actions:{add:{label:"Add",icon:"icon-plus",mode:"all",ngClick:"addInventory()","class":"btn-small btn-success", awToolTip:"Create a new inventory"}},fieldActions:{edit:{label:"Edit",ngClick:"editInventory({{ inventory.id }})",icon:"icon-edit","class":"btn-small btn-success",awToolTip:"View/Edit inventory"},"delete":{label:"Delete",ngClick:"deleteInventory({{ inventory.id }},'{{ inventory.name }}')",icon:"icon-remove","class":"btn-small btn-danger",awToolTip:"Delete inventory"}}});angular.module("JobEventsListDefinition",[]).value("JobEventList",{name:"jobevents",iterator:"jobevent",editTitle:"Job Events",index:!1,hover:!0,hasChildren:!0,filterBy:"{ show: true }",fields:{created:{label:"Date",key:!0,nosort:!0,searchable:!1,link:!1},status:{label:"Status",icon:"icon-circle","class":"job-{{ jobevent.status }}",searchField:"failed",searchType:"boolean",searchOptions:[{name:"success",value:0},{name:"error",value:1}],nosort:!0,searchable:!1},event_display:{label:"Event",hasChildren:!0, ngClick:"toggleChildren({{ jobevent.id }}, '{{ jobevent.related.children }}')",nosort:!0,searchable:!1,ngClass:"{{ jobevent.class }}",appendHTML:"jobevent.event_detail"},host:{label:"Host",ngBind:"jobevent.summary_fields.host.name",searchField:"hosts__name",nosort:!0,id:"job-event-host-header"}},actions:{refresh:{ngClick:"refresh()",icon:"icon-refresh",label:"Refresh",awToolTip:"Refresh the page","class":"btn-small btn-success",mode:"all"},edit:{label:"Details",ngClick:"jobDetails()",icon:"icon-zoom-in", @@ -329,7 +329,7 @@ this.buildField(b,d,c));a+="\x3c!-- column 2 --\x3e\n";a+="\x3c!-- i '
\n';a+=g({iterator:this.form.items[itm].iterator,template:this.form.items[itm],mini:!1,label:"Filter Events"});a+='
Viewing {{ '+this.form.items[itm].iterator+"Page + 1 }} of {{ "+this.form.items[itm].iterator+"Count }}
\n";a+="
\n";a+='\n";a+='
\n';for(b in this.form.items[itm].fields)d=this.form.items[itm].fields[b],a+=this.buildField(b,d,c);a+="
\n";a+='\n";a+="
\x3c!-- well --\x3e\n"}"inventory"==this.form.name&&"edit"==c.mode?a+=this.buildTree(c):!this.modal&&(c.related&&this.form.related)&&(a+=this.buildCollections(c)); -return a},buildTree:function(f){var a=1,d=this.form;html='
\n';html+="

Inventory Content

\n";html+="
\n";for(var b in d.related){if("tree"==d.related[b].type)html+='
',html+='
',html+='', +return a},buildTree:function(f){var a=1,d=this.form;html='
\n';html+="

Inventory Content

\n";html+="
\n";for(var b in d.related){if("tree"==d.related[b].type)html+='
',html+='
',html+='', html+='',html+='',html+="
\n",html+='
\n', html+='
\n',html+="
\n";else{html+='
\n';html+='
\n';html+='

'+d.related[b].title+"

\n";html+=g({iterator:d.related[b].iterator,template:d.related[b],mini:!0});html+='
\n'; for(var h in d.related[b].actions)html+='
\n";"select"==f.mode&&d.selectInstructions?(a+='
\n',a+='\n',a+="Hint: "+d.selectInstructions+"\n",a+="
\n"):"edit"==f.mode&&d.editInstructions&&(a+='
\n',a+='\n', a+="Hint: "+d.editInstructions+"\n",a+="
\n");if("lookup"!=f.mode&&(void 0==d.well||"true"==d.well))a+='
\n';a="lookup"==f.mode||void 0!=f.id?a+g({iterator:d.iterator,template:d,mini:!0}):a+g({iterator:d.iterator,template:d,mini:!1});if("lookup"!=f.mode){var b=h.path().replace(/^\//,"").split("/")[0],a=a+'
\n';for(action in d.actions)if("all"==d.actions[action].mode||d.actions[action].mode==f.mode)if(void 0==d.actions[action].basePaths|| -d.actions[action].basePaths&&-1 Finished\n';a+="
\n"}a+='"+d.fields[k].label;if(void 0===d.fields[k].nosort||!0!==d.fields[k].nosort)a+=' \n");a+="\n";a+="\n";a+="\n";a+="\n");var m=2,b=d.base?d.base:d.name,b=b.replace(/^\//,"");for(k in d.fields)if(m++,(void 0==d.fields[k].searchOnly||!1==d.fields[k].searchOnly)&&!("lookup"==f.mode&&void 0!==d.fields[k].excludeModal&&!0==d.fields[k].excludeModal))a+=e({list:d,fld:k,options:f,base:b});if("select"==f.mode)a+='';else if("edit"== -f.mode){a+='"}a+="\n";a+='\n';a+='\n';a+="\n";a+='\n';a+='\n'; -a+="\n";a+="\n";a+="
';for(action in d.fieldActions)a+=' ";a+="
No records matched your search.
Loading...
\n";if("lookup"!=f.mode&&(void 0==d.well||"true"==d.well))a+="
\n";return a="lookup"==f.mode||f.id&&"form-modal-body"==f.id?a+c({set:d.name,iterator:d.iterator,mini:!0,mode:"lookup"}):a+c({set:d.name,iterator:d.iterator,mini:!0})}}}]);angular.module("PromptDialog",["Utilities"]).factory("Prompt",["Alert",function(h){return function(h){var k=angular.element(document.getElementById("prompt-modal")),g=k.scope();g.promptHeader=h.hdr;g.promptBody=h.body;var c=null==h["class"]||void 0==h["class"]?"btn-danger":h["class"];$("#prompt-action-btn").addClass(c);g.promptAction=h.action;$(k).modal({backdrop:"static",keyboard:!0,show:!0})}}]);angular.module("RestServices",["ngCookies","AuthService"]).factory("Rest",["$http","$rootScope","$cookieStore","Authorization",function(h,m,k,g){return{setUrl:function(c){this.url=c},auth:{Authorization:"Token "+g.getToken()},pReplace:function(){var c,g;for(c in this.params)g=RegExp("\\:"+c,"gm"),g.test(this.url)&&(this.url=this.url.replace(g,this.params[c]),delete this.params[c])},get:function(c){c=c?c:{};this.params=c.params?c.params:null;this.pReplace();return h({method:"GET",url:this.url,headers:this.auth, +d.actions[action].basePaths&&-1"+this.icon(d.actions[action].icon),a+=d.actions[action].label?" "+d.actions[action].label:"",a+=" ";if("select"==f.mode&&(void 0==f.selectButton||!0==f.selectButton))a+=' \n'; +a+="
\n"}a+='"+d.fields[k].label;if(void 0===d.fields[k].nosort||!0!==d.fields[k].nosort)a+=' Select":"edit"==f.mode&&(a+="\n");a+="\n";a+="\n";a+="\n";a+="\n");var m=2,b=d.base?d.base:d.name,b=b.replace(/^\//,"");for(k in d.fields)if(m++,(void 0==d.fields[k].searchOnly||!1==d.fields[k].searchOnly)&&!("lookup"==f.mode&& +void 0!==d.fields[k].excludeModal&&!0==d.fields[k].excludeModal))a+=e({list:d,fld:k,options:f,base:b});if("select"==f.mode)a+='';else if("edit"==f.mode){a+='"}a+="\n";a+='\n';a+='\n';a+="\n";a+='\n';a+='\n';a+="\n";a+="\n";a+="
';for(action in d.fieldActions)a+=' ";a+="
No records matched your search.
Loading...
\n";if("lookup"!=f.mode&&(void 0==d.well||"true"==d.well))a+="
\n";return a="lookup"==f.mode||f.id&&"form-modal-body"==f.id?a+c({set:d.name,iterator:d.iterator,mini:!0,mode:"lookup"}): +a+c({set:d.name,iterator:d.iterator,mini:!0})}}}]);angular.module("PromptDialog",["Utilities"]).factory("Prompt",["Alert",function(h){return function(h){var k=angular.element(document.getElementById("prompt-modal")),g=k.scope();g.promptHeader=h.hdr;g.promptBody=h.body;var c=null==h["class"]||void 0==h["class"]?"btn-danger":h["class"];$("#prompt-action-btn").addClass(c);g.promptAction=h.action;$(k).modal({backdrop:"static",keyboard:!0,show:!0})}}]);angular.module("RestServices",["ngCookies","AuthService"]).factory("Rest",["$http","$rootScope","$cookieStore","Authorization",function(h,m,k,g){return{setUrl:function(c){this.url=c},auth:{Authorization:"Token "+g.getToken()},pReplace:function(){var c,g;for(c in this.params)g=RegExp("\\:"+c,"gm"),g.test(this.url)&&(this.url=this.url.replace(g,this.params[c]),delete this.params[c])},get:function(c){c=c?c:{};this.params=c.params?c.params:null;this.pReplace();return h({method:"GET",url:this.url,headers:this.auth, params:this.params})},post:function(c){return h({method:"POST",url:this.url,headers:this.auth,data:c})},put:function(c){return h({method:"PUT",url:this.url,headers:this.auth,data:c})},destroy:function(c){return h({method:"DELETE",url:this.url,headers:this.auth,data:c})}}}]);angular.module("Utilities",[]).factory("ClearScope",function(){return function(h){h=document.getElementById(h);angular.element(h).scope().$destroy()}}).factory("ToggleClass",function(){return function(h,m){$(h)&&$(h).hasClass(m)?$(h).removeClass(m):$(h)&&$(h).addClass(m)}}).factory("Alert",["$rootScope","$location",function(h,m){return function(k,g,c,m,f,e){if(f){if(h.alertHeader2=k,h.alertBody2=g,h.alertClass2=c?c:"alert-error",$("#alert-modal2").modal({show:!0,keyboard:!0,backdrop:"static"}),h.disableButtons2= e?!0:!1,m)$("#alert-modal2").on("hidden",function(){m()})}else if(h.alertHeader=k,h.alertBody=g,h.alertClass=c?c:"alert-error",$("#alert-modal").modal({show:!0,keyboard:!0,backdrop:"static"}),h.disableButtons=e?!0:!1,m)$("#alert-modal").on("hidden",function(){m()})}}]).factory("ProcessErrors",["$log","Alert",function(h,m){return function(h,g,c,p,f){if(403==c)h="The API responded with a 403 Access Denied error. You do not have permission to perform the requested action. ",h=g.detail?h+("Detail: "+ g.detail):h+"Please contact your system administrator.",m("Access Denied",h);else if(g.non_field_errors)m("Error!",g.non_field_errors);else if(g.detail)m(f.hdr,f.msg+" "+g.detail);else if(g.__all__)m("Error!",g.__all__);else if(p){c=!1;for(var e in p.fields)p.fields[e].realName&&g[p.fields[e].realName]&&(h[e+"_api_error"]=g[p.fields[e]][0],c=!0),p.fields[e].sourceModel?g[e]&&(h[p.fields[e].sourceModel+"_"+p.fields[e].sourceField+"_api_error"]=g[e][0],c=!0):g[e]&&(h[e+"_api_error"]=g[e][0],c=!0);!c&& diff --git a/awx/ui/static/js/helpers/Hosts.js b/awx/ui/static/js/helpers/Hosts.js index 78e5526002..8fad3b1423 100644 --- a/awx/ui/static/js/helpers/Hosts.js +++ b/awx/ui/static/js/helpers/Hosts.js @@ -25,7 +25,7 @@ angular.module('HostsHelper', [ 'RestServices', 'Utilities', 'ListGenerator', 'H var list = HostList; var defaultUrl = GetBasePath('inventory') + inventory_id + '/hosts/'; var view = GenerateList; - + var scope = view.inject(HostList, { id: 'form-modal-body', mode: 'select', diff --git a/awx/ui/static/js/lists/Groups.js b/awx/ui/static/js/lists/Groups.js index a0ad24790a..457cbb741b 100644 --- a/awx/ui/static/js/lists/Groups.js +++ b/awx/ui/static/js/lists/Groups.js @@ -35,6 +35,18 @@ angular.module('GroupListDefinition', []) ngClick: 'createGroup()', "class": 'btn-success btn-small', awToolTip: 'Create a new group' + }, + help: { + awPopOver: "Select groups by clicking on each group you wish to add. Add the selected groups to your inventory " + + "or to the selected parent group by clicking the Select button. You can also create a new group by clicking the " + + "Create New Group button.", + dataPlacement: 'left', + dataContainer: "#form-modal", + icon: "icon-question-sign", + mode: 'all', + 'class': 'btn-small btn-info', + awToolTip: 'Click for help', + dataTitle: 'Adding Groups' } }, diff --git a/awx/ui/static/js/lists/Hosts.js b/awx/ui/static/js/lists/Hosts.js index fa2fae7993..2920eef044 100644 --- a/awx/ui/static/js/lists/Hosts.js +++ b/awx/ui/static/js/lists/Hosts.js @@ -16,7 +16,7 @@ angular.module('HostListDefinition', []) editTitle: 'Hosts', index: true, well: true, - + fields: { name: { key: true, @@ -29,6 +29,16 @@ angular.module('HostListDefinition', []) }, actions: { + help: { + awPopOver: "Select hosts by clicking on each host you wish to add. Add the selected hosts to the group by clicking the Select button.", + dataPlacement: 'left', + dataContainer: "#form-modal", + icon: "icon-question-sign", + mode: 'all', + 'class': 'btn-small btn-info', + awToolTip: 'Click for help', + dataTitle: 'Selecting Hosts' + } }, fieldActions: { diff --git a/awx/ui/static/lib/ansible/list-generator.js b/awx/ui/static/lib/ansible/list-generator.js index 81bd5a2dd1..90e12319d7 100644 --- a/awx/ui/static/lib/ansible/list-generator.js +++ b/awx/ui/static/lib/ansible/list-generator.js @@ -128,7 +128,11 @@ angular.module('ListGenerator', ['GeneratorHelpers']) html += "\" "; html += (list.actions[action].ngHide) ? this.attr(list.actions[action],'ngHide') : ""; html += (list.actions[action].awToolTip) ? this.attr(list.actions[action],'awToolTip') : ""; - html += (list.actions[action].awToolTip) ? "data-placement=\"top\" " : ""; + html += (list.actions[action].awToolTip && list.actions[action].dataPlacement == undefined) ? "data-placement=\"top\" " : ""; + html += (list.actions[action].awPopOver) ? this.attr(list.actions[action],'awPopOver') : ""; + html += (list.actions[action].dataPlacement) ? this.attr(list.actions[action], 'dataPlacement') : ""; + html += (list.actions[action].dataContainer) ? this.attr(list.actions[action], 'dataContainer') : ""; + html += (list.actions[action].dataTitle) ? this.attr(list.actions[action], 'dataTitle') : ""; html += " >" + this.icon(list.actions[action].icon); html += (list.actions[action].label) ? " " + list.actions[action].label : ""; html += " ";