Extract toolbar button into directive

This commit is contained in:
Joe Fiorini 2015-03-13 11:48:41 -04:00
parent 9aed0ad63a
commit ef422d33b1
10 changed files with 176 additions and 215 deletions

View File

@ -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'
];

View File

@ -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'
];

View File

@ -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;

View File

@ -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(" ") + "></" + tagName + ">";
return html;
},
navigationLink: NavigationLink,
@ -1346,7 +1389,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
var html = "<div class=\"list-actions\">\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 += "</div>\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
});
}

View File

@ -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 <i> icon tag. Replaces Icon method.
result = "<i class=\"fa fa-" + value;
@ -175,85 +181,6 @@ angular.module('GeneratorHelpers', [systemStatus.name])
])
.factory('Button', ['Attr', 'SelectIcon',
function (Attr, SelectIcon) {
return function (params) {
// pass in button object, get back html
var btn = params.btn,
action = params.action, // label used to select the icon
toolbar = params.toolbar,
html = '';
if (toolbar) {
//if this is a toolbar button, set some defaults
console.log('toolbar button');
btn.class = 'btn-xs btn-primary';
btn.iconSize = 'fa-lg';
delete btn.label;
} else {
console.log('NOT A TOOLBAR BUTTON');
}
html += "<button type=\"button\" ";
html += "class=\"btn";
if (btn['class']) {
html += ' ' + btn['class'];
} else {
html += " btn-sm";
}
console.log('btn:', btn);
html += (btn.awPopOver) ? " help-link-white" : "";
html += "\" ";
html += (btn.ngClick) ? Attr(btn, 'ngClick') : "";
if (btn.id) {
html += "id=\"" + btn.id + "\" ";
} else {
if (action) {
html += "id=\"" + action + "_btn\" ";
}
}
html += (btn.ngHide) ? Attr(btn, 'ngHide') : "";
html += (btn.awToolTip) ? Attr(btn, 'awToolTip') : "";
html += (btn.awToolTip && btn.dataPlacement === undefined) ? "data-placement=\"top\" " : "";
html += (btn.dataTipWatch) ? "data-tip-watch=\"" + btn.dataTipWatch + "\" " : "";
html += (btn.awPopOver) ? "aw-pop-over=\"" +
btn.awPopOver.replace(/[\'\"]/g, '&quot;') + "\" " : "";
html += (btn.dataPlacement) ? Attr(btn, 'dataPlacement') : "";
html += (btn.dataContainer) ? Attr(btn, 'dataContainer') : "";
html += (btn.dataTitle) ? Attr(btn, 'dataTitle') : "";
html += (btn.ngShow) ? Attr(btn, 'ngShow') : "";
html += (btn.ngHide) ? Attr(btn, 'ngHide') : "";
html += (btn.ngDisabled) ? Attr(btn, 'ngDisabled') : "";
html += (btn.ngClass) ? Attr(btn, 'ngClass') : "";
html += (btn.awTipPlacement) ? Attr(btn, 'awTipPlacement') : "";
html += " >";
html += (btn.img) ? "<img src=\"" + $basePath + "img/" + btn.img + "\" style=\"width: 12px; height: 12px;\" >" : "";
if (btn.iconClass) {
html += "<i class=\"" + btn.iconClass + "\"></i>";
}
else {
html += SelectIcon({
action: action,
size: btn.iconSize
});
}
html += (btn.label) ? " " + btn.label : "";
html += "</button> ";
return html;
};
}
])
.factory('NavigationLink', ['Attr', 'Icon',
function (Attr, Icon) {
return function (link) {

View File

@ -0,0 +1,29 @@
<span ng-repeat="(name, options) in list.actions">
<button
toolbar-button
mode="options.mode"
icon-name="{{name}}"
aw-tool-tip="{{options.awToolTip}}"
data-placement="{{options.dataPlacement}}"
data-container="{{options.dataContainer}}"
class="options.class"
data-title="{{options.dataTitle}}"
icon-size="{{options.iconSize}}"
ng-click="performAction(options.ngClick)"
ng-show="canShowAction(options)"
toolbar="true">
</button>
</span>
<button
toolbar-button
icon-name="help"
aw-pop-over="{{list.selectInstructions}}"
data-placement="left"
data-container="body"
class="btn-xs btn-help"
aw-tool-tip="Click for help"
data-title="Help"
icon-size="fa-lg"
toolbar="true"
ng-if="mode === 'select' && list.selectInstructions">
</button>

View File

@ -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 += "<div class=\"list-actions\">\n";
html += '<span ng-repeat="(name, options) in list.actions">';
html += '<toolbar-button name="name" options="options" on-selected="performAction(action)" ng-show="canShowAction(options)"></toolbar-button>';
html += '</span>';
//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 += "<div class=\"list-actions\" ng-include=\"'/static/js/shared/list-generator/list-actions.partial.html'\">\n";
for (action in list.actions) {
list.actions[action] =
_.defaults(list.actions[action],
{ dataPlacement: "top"
});
}
html += "</div><!-- list-acitons -->\n";
html += "</div><!-- list-actions-column -->\n";

View File

@ -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)) {
$("<img>")
.attr("src", $basePath + "img/" + attrs.img)
.css({ width: "12px", height: "12px" })
.appendTo(element);
}
if (!_.isEmpty(attrs.iconClass)) {
$("<i>")
.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);
}
};
}];

View File

@ -4,6 +4,24 @@
<div id="refresh-row" class="row">
<div class="col-lg-12">
<div id="home-list-actions" class="list-actions pull-right">
<button
toolbar-button
mode="all"
aw-tool-tip="Refresh the page"
ng-click="refresh()"
ng-show="socketStatus == 'error'"
icon-name="refresh"
toolbar="true">
</button>
<button
toolbar-button
mode="all"
ng-click="showActivity()"
aw-tool-tip="View Activity Stream"
icon-name="stream"
toolbar="true">
</button>
<!-- <button type="button" class="btn btn-xs btn-primary ng-hide" ng-click="refreshJobs()" id="refresh_btn" aw-tool-tip="Refresh the page" data-placement="top" ng-show="socketStatus == 'error'" data-original-title="" title=""><i class="fa fa-refresh fa-lg"></i> </button></div> -->
</div>
</div>

View File

@ -3,6 +3,14 @@
<div id="refresh-row" class="row">
<div class="col-lg-12">
<div id="portal-list-actions" class="list-actions pull-right">
<button
toolbar-button
icon-name="refresh"
ng-click="refresh()"
ng-show="socketStatus == 'error'"
aw-tool-tip="Refresh the page"
toolbar="true">
</button>
</div>
</div>
</div>