diff --git a/awx/ui/static/js/controllers/Home.js b/awx/ui/static/js/controllers/Home.js index 73f978b026..e3a8c2dd38 100644 --- a/awx/ui/static/js/controllers/Home.js +++ b/awx/ui/static/js/controllers/Home.js @@ -27,43 +27,11 @@ */ export function Home($scope, $compile, $routeParams, $rootScope, $location, $log, Wait, DashboardCounts, DashboardJobs, - ClearScope, Stream, Rest, GetBasePath, ProcessErrors, Button, $window, graphData){ + ClearScope, Stream, Rest, GetBasePath, ProcessErrors, $window, graphData){ ClearScope('home'); - var buttons, html, e, borderStyles; - - // Add buttons to the top of the Home page. We're using lib/ansible/generator_helpers.js-> Buttons() - // to build buttons dynamically and insure all styling and icons match the rest of the application. - buttons = { - refresh: { - mode: 'all', - awToolTip: "Refresh the page", - ngClick: "refresh()", - ngShow:"socketStatus == 'error'" - }, - stream: { - ngClick: "showActivity()", - awToolTip: "View Activity Stream", - mode: 'all' - } - }; - - html = Button({ - btn: buttons.refresh, - action: 'refresh', - toolbar: true - }); - - html += Button({ - btn: buttons.stream, - action: 'stream', - toolbar: true - }); - - e = angular.element(document.getElementById('home-list-actions')); - e.html(html); - $compile(e)($scope); + var borderStyles; if (!$routeParams.login) { // If we're not logging in, start the Wait widget. Otherwise, it's already running. @@ -136,7 +104,7 @@ export function Home($scope, $compile, $routeParams, $rootScope, $location, $log } Home.$inject = ['$scope', '$compile', '$routeParams', '$rootScope', '$location', '$log','Wait', 'DashboardCounts', 'DashboardJobs', - 'ClearScope', 'Stream', 'Rest', 'GetBasePath', 'ProcessErrors', 'Button', '$window', 'graphData' + 'ClearScope', 'Stream', 'Rest', 'GetBasePath', 'ProcessErrors', '$window', 'graphData' ]; diff --git a/awx/ui/static/js/controllers/Portal.js b/awx/ui/static/js/controllers/Portal.js index 7fc9b4bb4e..3af4a2234d 100644 --- a/awx/ui/static/js/controllers/Portal.js +++ b/awx/ui/static/js/controllers/Portal.js @@ -25,47 +25,15 @@ * */ export function PortalController($scope, $compile, $routeParams, $rootScope, $location, $log, Wait, ClearScope, Stream, Rest, GetBasePath, ProcessErrors, - Button, PortalJobsWidget, GenerateList, PortalJobTemplateList, SearchInit, PaginateInit, PlaybookRun){ + PortalJobsWidget, GenerateList, PortalJobTemplateList, SearchInit, PaginateInit, PlaybookRun){ ClearScope('portal'); - var html, - e, - jobs_scope, + var jobs_scope, list = PortalJobTemplateList, view= GenerateList, defaultUrl = GetBasePath('job_templates'), - max_rows, - buttons = { - refresh: { - mode: 'all', - awToolTip: "Refresh the page", - ngClick: "refresh()", - ngShow:"socketStatus == 'error'" - } - // , - // stream: { - // ngClick: "showActivity()", - // awToolTip: "View Activity Stream", - // mode: 'all' - // } - }; - - html = Button({ - btn: buttons.refresh, - action: 'refresh', - toolbar: true - }); - - // html += Button({ - // btn: buttons.stream, - // action: 'stream', - // toolbar: true - // }); - - e = angular.element(document.getElementById('portal-list-actions')); - e.html(html); - $compile(e)($scope); + max_rows; if ($scope.removeLoadPortal) { $scope.removeLoadPortal(); @@ -176,5 +144,5 @@ export function PortalController($scope, $compile, $routeParams, $rootScope, $lo } PortalController.$inject = ['$scope', '$compile', '$routeParams', '$rootScope', '$location', '$log','Wait', 'ClearScope', 'Stream', 'Rest', 'GetBasePath', 'ProcessErrors', - 'Button', 'PortalJobsWidget', 'generateList' , 'PortalJobTemplateList', 'SearchInit', 'PaginateInit', 'PlaybookRun' + 'PortalJobsWidget', 'generateList' , 'PortalJobTemplateList', 'SearchInit', 'PaginateInit', 'PlaybookRun' ]; diff --git a/awx/ui/static/js/shared/directives.js b/awx/ui/static/js/shared/directives.js index 9fa121b43c..e751460fd6 100644 --- a/awx/ui/static/js/shared/directives.js +++ b/awx/ui/static/js/shared/directives.js @@ -404,6 +404,7 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Job */ .directive('awToolTip', ['$sce', function($sce) { return { + priority: 1000, link: function(scope, element, attrs) { var delay = (attrs.delay !== undefined && attrs.delay !== null) ? attrs.delay : ($AnsibleConfig) ? $AnsibleConfig.tooltip_delay : {show: 500, hide: 100}, placement; diff --git a/awx/ui/static/js/shared/form-generator.js b/awx/ui/static/js/shared/form-generator.js index 4d27d4c918..9affa6dcd8 100644 --- a/awx/ui/static/js/shared/form-generator.js +++ b/awx/ui/static/js/shared/form-generator.js @@ -139,9 +139,9 @@ export default angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerator.name]) .factory('GenerateForm', ['$rootScope', '$location', '$compile', 'generateList', 'SearchWidget', 'PaginateWidget', 'Attr', - 'Icon', 'Column', 'NavigationLink', 'HelpCollapse', 'Button', 'DropDown', 'Empty', 'SelectIcon', 'Store', + 'Icon', 'Column', 'NavigationLink', 'HelpCollapse', 'DropDown', 'Empty', 'SelectIcon', 'Store', function ($rootScope, $location, $compile, GenerateList, SearchWidget, PaginateWidget, Attr, Icon, Column, NavigationLink, - HelpCollapse, Button, DropDown, Empty, SelectIcon, Store) { + HelpCollapse, DropDown, Empty, SelectIcon, Store) { return { setForm: function (form) { this.form = form; }, @@ -553,7 +553,50 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat } }, - button: Button, + button: function(params) { + var tagName = "button"; + var options = params.btn; + var tagParts = + [ tagName, + "toolbar-button" + ]; + + var attrNames = _.keys(options); + + function isSupportedKey(keyName) { + if (keyName === 'icon') { + //TODO: Let's add a depecrated logger to our logging helper to output the below message + // + // The form action key "icon" is deprecated in favor of using the name of the field as the icon name or the iconClass option. + return false; + } + + return true; + } + + var attrs = attrNames + .filter(function(name) { + + return isSupportedKey(name) && + !_.isEmpty(options[name]); + + }).map(function(name) { + return Attr(options, name); + }); + + tagParts = + tagParts + .concat(attrs) + .concat( + Attr(params, 'iconName'), + Attr(params, 'toolbar') + ); + + var html = "<" + tagParts.join(" ") + ">"; + + return html; + + }, navigationLink: NavigationLink, @@ -1346,7 +1389,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat var html = "
\n", action; for (action in this.form.actions) { if (this.form.actions[action].mode === 'all' || this.form.actions[action].mode === options.mode) { - html += this.button({ btn: this.form.actions[action], action: action, toolbar: true }); + html += this.button({ btn: this.form.actions[action], iconName: action, toolbar: true }); } } html += "
\n"; @@ -1722,7 +1765,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat action = collection.actions[act]; html += this.button({ btn: action, - action: act, + iconName: act, toolbar: true }); } diff --git a/awx/ui/static/js/shared/generator-helpers.js b/awx/ui/static/js/shared/generator-helpers.js index 1c8f67c372..a68844e7a7 100644 --- a/awx/ui/static/js/shared/generator-helpers.js +++ b/awx/ui/static/js/shared/generator-helpers.js @@ -55,6 +55,12 @@ angular.module('GeneratorHelpers', [systemStatus.name]) case 'columnShow': result = "ng-show=\"" + value + "\" "; break; + case 'iconName': + result = "icon-name=\"" + value + "\" "; + break; + case 'iconSize': + result = "icon-size=\"" + value + "\" "; + break; case 'icon': // new method of constructing icon tag. Replaces Icon method. result = "" : ""; - - if (btn.iconClass) { - html += ""; - } - else { - html += SelectIcon({ - action: action, - size: btn.iconSize - }); - } - - html += (btn.label) ? " " + btn.label : ""; - html += " "; - - return html; - }; - } -]) - - .factory('NavigationLink', ['Attr', 'Icon', function (Attr, Icon) { return function (link) { diff --git a/awx/ui/static/js/shared/list-generator/list-actions.partial.html b/awx/ui/static/js/shared/list-generator/list-actions.partial.html new file mode 100644 index 0000000000..22982b8a60 --- /dev/null +++ b/awx/ui/static/js/shared/list-generator/list-actions.partial.html @@ -0,0 +1,29 @@ + + + + diff --git a/awx/ui/static/js/shared/list-generator/list-generator.factory.js b/awx/ui/static/js/shared/list-generator/list-generator.factory.js index 88852cb086..78856e4961 100644 --- a/awx/ui/static/js/shared/list-generator/list-generator.factory.js +++ b/awx/ui/static/js/shared/list-generator/list-generator.factory.js @@ -1,7 +1,7 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'PaginateWidget', 'Attr', 'Icon', - 'Column', 'DropDown', 'NavigationLink', 'Button', 'SelectIcon', 'Breadcrumbs', + 'Column', 'DropDown', 'NavigationLink', 'SelectIcon', 'Breadcrumbs', function ($location, $compile, $rootScope, SearchWidget, PaginateWidget, Attr, Icon, Column, DropDown, NavigationLink, - Button, SelectIcon, Breadcrumbs) { + SelectIcon, Breadcrumbs) { return { setList: function (list) { @@ -24,8 +24,6 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate $('#lookup-modal').modal('hide'); }, - button: Button, - buildHTML: function(list, options) { this.setList(list); return this.build(options); @@ -74,12 +72,11 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate this.scope.mode = options.mode; this.scope.performAction = function(action) { - console.log('performing:', action); this.scope.$eval(action); }.bind(this); this.scope.shouldHideAction = function(options) { - return _.tap(this.scope.$eval(options.ngHide), function(value) { console.log('shouldHide:', value, this.scope.selected_group_id, options); }.bind(this)); + return this.scope.$eval(options.ngHide); }.bind(this); this.scope.canShowAction = function(action) { var base = $location.path().replace(/^\//, '').split('/')[0]; @@ -92,12 +89,9 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate if (this.scope.shouldHideAction(action)) { return false; } else if (!scopeShow) { - console.log('scopeShow false', action.ngShow); return false; } else { - return _.tap(inActionMode && onScreenForAction, function(value) { - console.log('mode ', value, action); - }); + return inActionMode && onScreenForAction; } // return _.tap(scopeShow || , function(value) { @@ -154,7 +148,7 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate // var html = '', list = this.list, - base, size, action, btn, fld, cnt, field_action, fAction, itm; + base, size, action, fld, cnt, field_action, fAction, itm; if (options.activityStream) { // Breadcrumbs for activity stream widget @@ -254,32 +248,16 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate } html += "\">\n"; - html += "
\n"; - html += ''; - html += ''; - html += ''; - //select instructions - if (options.mode === 'select' && list.selectInstructions) { - btn = { - awPopOver: list.selectInstructions, - dataPlacement: 'left', - dataContainer: 'body', - 'class': 'btn-xs btn-help', - awToolTip: 'Click for help', - dataTitle: 'Help', - iconSize: 'fa-lg' - }; - //html += this.button(btn, 'select'); - html += this.button({ - btn: btn, - action: 'help', - toolbar: true - }); + html += "
\n"; + + for (action in list.actions) { + list.actions[action] = + _.defaults(list.actions[action], + { dataPlacement: "top" + }); } - - html += "
\n"; html += "
\n"; diff --git a/awx/ui/static/js/shared/list-generator/toolbar-button.directive.js b/awx/ui/static/js/shared/list-generator/toolbar-button.directive.js index 5b0e0288db..a997ab0776 100644 --- a/awx/ui/static/js/shared/list-generator/toolbar-button.directive.js +++ b/awx/ui/static/js/shared/list-generator/toolbar-button.directive.js @@ -1,39 +1,60 @@ -export default ['$compile', 'Button', function($compile, Button) { +export default ['$compile', 'Attr', 'SelectIcon', function($compile, Attr, SelectIcon) { return { - restrict: 'E', - scope: { - name: '=', - options: '=', - onSelected: '&' - }, + restrict: 'A', + scope: {}, link: function(scope, element, attrs) { - var html = ''; - // Save the ngClick property from - // legacy list actions - scope.action = scope.options.ngClick; + var toolbar = attrs.toolbar; + if (toolbar) { + //if this is a toolbar button, set some defaults + attrs.class = 'btn-xs btn-primary'; + attrs.iconSize = 'fa-lg'; + } - var btnOptions = _.clone(scope.options); - btnOptions.ngClick = "onSelected({ action: action })"; + element.addClass('btn'); - // These should be taken care of by - // using ng-show & ng-hide on this - // directive - delete btnOptions.ngHide; - delete btnOptions.ngShow; + // If no class specified, default + // to btn-sm + if (_.isEmpty(attrs.class)) { + element.addClass("btn-sm"); + } else { + element.addClass(attrs.class); + } - // console.log('options:', scope.options); + if (attrs.awPopOver) { + element.addClass("help-link-white"); + } - html += Button({ - btn: btnOptions, - action: scope.name, - toolbar: true - }); + if (attrs.iconName && _.isEmpty(attrs.id)) { + element.attr("id",attrs.iconName + "_btn"); + } - element.html(html); + if (!_.isEmpty(attrs.img)) { + $("") + .attr("src", $basePath + "img/" + attrs.img) + .css({ width: "12px", height: "12px" }) + .appendTo(element); + } + + if (!_.isEmpty(attrs.iconClass)) { + $("") + .addClass(attrs.iconClass) + .appendTo(element); + } + else { + var icon = SelectIcon({ + action: attrs.iconName, + size: attrs.iconSize + }); + + $(icon).appendTo(element); + } + + if (!toolbar && !_.isEmpty(attrs.label)) { + element.text(attrs.label); + } - $compile(element.contents())(scope); } }; }]; diff --git a/awx/ui/static/partials/home.html b/awx/ui/static/partials/home.html index dc70714683..421c2c2b6d 100644 --- a/awx/ui/static/partials/home.html +++ b/awx/ui/static/partials/home.html @@ -4,6 +4,24 @@
+ + +
diff --git a/awx/ui/static/partials/portal.html b/awx/ui/static/partials/portal.html index 604d36bacf..077eed49e3 100644 --- a/awx/ui/static/partials/portal.html +++ b/awx/ui/static/partials/portal.html @@ -3,6 +3,14 @@
+