Merge "Actions directive for dynamic actions"
This commit is contained in:
commit
80fa84bcc9
@ -0,0 +1,3 @@
|
||||
<action action-classes="'btn btn-default btn-sm btn-create'">
|
||||
<span class="fa fa-user-plus">Create Image</span>
|
||||
</action>
|
@ -0,0 +1,3 @@
|
||||
<action action-classes="'text-danger'" item="image">
|
||||
<span class="fa fa-trash-o text-danger" translate>Delete Image</span>
|
||||
</action>
|
@ -0,0 +1,3 @@
|
||||
<action action-classes="'$action-classes$ btn btn-default btn-sm'">
|
||||
<span class="fa">$text$</span>
|
||||
</action>
|
@ -0,0 +1,3 @@
|
||||
<action action-classes="'btn btn-default btn-sm pull-right'">
|
||||
<span class="fa fa-user-plus">$text$</span>
|
||||
</action>
|
@ -0,0 +1,5 @@
|
||||
<action action-classes="'btn btn-default btn-sm btn-danger pull-right'"
|
||||
disabled="numSelected === 0"
|
||||
item="selected">
|
||||
<span class="fa fa-trash-o">$text$</span>
|
||||
</action>
|
@ -0,0 +1,3 @@
|
||||
<action action-classes="'text-danger'" item="$item$">
|
||||
<span class="fa fa-trash-o">$text$</span>
|
||||
</action>
|
@ -0,0 +1,3 @@
|
||||
<action action-classes="'$action-classes$'" item="$item$">
|
||||
<span class="fa">$text$</span>
|
||||
</action>
|
@ -0,0 +1,2 @@
|
||||
<actions allowed-actions="actions" action-list-type="batch">
|
||||
</actions>
|
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.framework.widgets.action-list')
|
||||
.directive('actions', actions);
|
||||
|
||||
actions.$inject = [
|
||||
'$parse',
|
||||
'horizon.framework.widgets.action-list.actions.service'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name horizon.framework.widgets.action-list.directive:actions
|
||||
* @element
|
||||
* @description
|
||||
* The `actions` directive represents the actions to be
|
||||
* displayed in a Bootstrap button group or button
|
||||
* dropdown.
|
||||
*
|
||||
*
|
||||
* Attributes:
|
||||
*
|
||||
* allowedActions: actions allowed that can be displayed
|
||||
* actionListType: allow the buttons to be shown as a list or doropdown
|
||||
*
|
||||
* `allowedActions` is a list of allowed actions on the service.
|
||||
* It's an array of objects of the form:
|
||||
* { template: {}, permissions: <promise to determine permissions>, callback: 'callback'}
|
||||
*
|
||||
* `template` is an object that can be
|
||||
*
|
||||
* {url: 'template.html'} the location of the template for the action button.
|
||||
* Use this for complete extensibility and control over what is rendered.
|
||||
* The template will be responsible for binding the callback and styling.
|
||||
*
|
||||
* {type: 'type', item: 'item'} use a known action button type.
|
||||
* Currently supported values are 'delete', 'delete-selected' and 'create'.
|
||||
* `item` is optional and if provided will be used in the callback.
|
||||
* The styling and binding of the callback is done by the template.
|
||||
*
|
||||
* {text: 'text', item: 'item'} use an unstyled button with given text.
|
||||
* `item` is optional and if provided will be used in the callback.
|
||||
* The styling of the button will vary per the `actionListType` chosen.
|
||||
* For custom styling of the button, `actionClasses` can be included in
|
||||
* the template.
|
||||
*
|
||||
* `permissions` is expected to be a promise that resolves
|
||||
* if permitted and is rejected if not.
|
||||
* `callback` is the method to call when the button is clicked.
|
||||
*
|
||||
* `actionListType` can be only be `row` or `batch`
|
||||
* `batch` is rendered as buttons, `row` is rendered as dropdown menu.
|
||||
*
|
||||
* @restrict E
|
||||
* @scope
|
||||
* @example
|
||||
*
|
||||
* $scope.actions = [{
|
||||
* template: {
|
||||
* text: gettext('Delete Image'),
|
||||
* type: 'delete',
|
||||
* item: 'image'
|
||||
* },
|
||||
* permissions: policy.ifAllowed({ rules: [['image', 'delete_image']] }),
|
||||
* callback: deleteModalService.open
|
||||
* }, {
|
||||
* template: {
|
||||
* text: gettext('Create Volume'),
|
||||
* item: 'image'
|
||||
* },
|
||||
* permissions: policy.ifAllowed({rules: [['volume', 'volume:create']]}),
|
||||
* callback: createVolumeModalService.open
|
||||
* }, {
|
||||
* template: {
|
||||
* url: basePath + 'actions/my-custom-action.html'
|
||||
* },
|
||||
* permissions: policy.ifAllowed({ rules: [['image', 'custom']] }),
|
||||
* callback: customModalService.open
|
||||
* }]
|
||||
*
|
||||
* ```
|
||||
* <actions allowed-actions="actions" action-list-type="row">
|
||||
* </actions>
|
||||
*
|
||||
* <actions allowed-actions="actions" action-list-type="batch">
|
||||
* </actions>
|
||||
* ```
|
||||
*/
|
||||
function actions(
|
||||
$parse,
|
||||
actionsService
|
||||
) {
|
||||
var directive = {
|
||||
link: link,
|
||||
restrict: 'E',
|
||||
template: ''
|
||||
};
|
||||
|
||||
return directive;
|
||||
|
||||
function link(scope, element, attrs) {
|
||||
var listType = attrs.actionListType;
|
||||
var allowedActions = $parse(attrs.allowedActions)(scope);
|
||||
|
||||
actionsService({scope: scope, element: element, listType: listType})
|
||||
.renderActions(allowedActions);
|
||||
}
|
||||
}
|
||||
})();
|
@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
describe('actions directive', function () {
|
||||
var $scope, $compile, $q, $templateCache, basePath;
|
||||
|
||||
beforeEach(module('templates'));
|
||||
beforeEach(module('horizon.framework'));
|
||||
|
||||
beforeEach(inject(function ($injector) {
|
||||
$compile = $injector.get('$compile');
|
||||
basePath = $injector.get('horizon.framework.widgets.basePath');
|
||||
$scope = $injector.get('$rootScope').$new();
|
||||
$q = $injector.get('$q');
|
||||
$templateCache = $injector.get('$templateCache');
|
||||
}));
|
||||
|
||||
it('should have no buttons if there are no actions', function () {
|
||||
var element = angular.element(getTemplate('actions.batch'));
|
||||
$scope.actions = [];
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
expect(element.children().length).toBe(0);
|
||||
});
|
||||
|
||||
it('should allow for specifying action text', function () {
|
||||
var element = angular.element(getTemplate('actions.batch'));
|
||||
$scope.actions = [permittedActionWithText('Create Image', 'image')];
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
|
||||
expect(element.children().length).toBe(1);
|
||||
var actionList = element.find('action-list');
|
||||
expect(actionList.length).toBe(1);
|
||||
expect(actionList.attr('class').indexOf('btn-addon')).toBeGreaterThan(-1);
|
||||
expect(actionList.find('button').attr('class')).toEqual('btn btn-default btn-sm');
|
||||
expect(actionList.find('button').attr('ng-click')).toEqual('disabled || callback(item)');
|
||||
expect(actionList.text().trim()).toEqual('Create Image');
|
||||
});
|
||||
|
||||
it('should allow for specifying by template for create', function () {
|
||||
var element = angular.element(getTemplate('actions.batch'));
|
||||
$scope.actions = [permittedActionWithType('create', 'Create Image')];
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
|
||||
expect(element.children().length).toBe(1);
|
||||
var actionList = element.find('action-list');
|
||||
expect(actionList.length).toBe(1);
|
||||
expect(actionList.attr('class').indexOf('btn-addon')).toBeGreaterThan(-1);
|
||||
expect(actionList.find('button').attr('class')).toEqual('btn btn-default btn-sm pull-right');
|
||||
expect(actionList.find('button').attr('ng-click')).toEqual('disabled || callback(item)');
|
||||
expect(actionList.text().trim()).toEqual('Create Image');
|
||||
});
|
||||
|
||||
it('should allow for specifying by template for delete-selected', function () {
|
||||
var element = angular.element(getTemplate('actions.batch'));
|
||||
$scope.actions = [permittedActionWithType('delete-selected', 'Delete Images')];
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
|
||||
expect(element.children().length).toBe(1);
|
||||
var actionList = element.find('action-list');
|
||||
expect(actionList.length).toBe(1);
|
||||
expect(actionList.attr('class').indexOf('btn-addon')).toBeGreaterThan(-1);
|
||||
expect(actionList.find('button').attr('class'))
|
||||
.toEqual('btn btn-default btn-sm btn-danger pull-right');
|
||||
expect(actionList.find('button').attr('ng-click')).toEqual('disabled || callback(item)');
|
||||
expect(actionList.text().trim()).toEqual('Delete Images');
|
||||
});
|
||||
|
||||
it('should allow for specifying by template for delete', function () {
|
||||
var element = angular.element(getTemplate('actions.row'));
|
||||
$scope.actions = [permittedActionWithType('delete', 'Delete Image')];
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
|
||||
expect(element.children().length).toBe(1);
|
||||
var actionList = element.find('action-list');
|
||||
expect(actionList.length).toBe(1);
|
||||
expect(actionList.attr('class').indexOf('btn-addon')).toBeGreaterThan(-1);
|
||||
expect(actionList.find('button').attr('class')).toEqual('text-danger');
|
||||
expect(actionList.find('button').attr('ng-click')).toEqual('disabled || callback(item)');
|
||||
expect(actionList.text().trim()).toEqual('Delete Image');
|
||||
});
|
||||
|
||||
it('should have one button if there is one action', function () {
|
||||
var action = getTemplatePath('action-create', getTemplate());
|
||||
|
||||
var element = angular.element(getTemplate('actions.batch'));
|
||||
$scope.actions = [permittedActionWithUrl(action)];
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
|
||||
expect(element.children().length).toBe(1);
|
||||
var actionList = element.find('action-list');
|
||||
expect(actionList.length).toBe(1);
|
||||
expect(actionList.attr('class').indexOf('btn-addon')).toBeGreaterThan(-1);
|
||||
expect(actionList.find('button').attr('class')).toEqual('btn btn-default btn-sm btn-create');
|
||||
expect(actionList.find('button').attr('ng-click')).toEqual('disabled || callback(item)');
|
||||
expect(actionList.text().trim()).toEqual('Create Image');
|
||||
});
|
||||
|
||||
it('should have no buttons if not permitted', function () {
|
||||
var element = angular.element(getTemplate('actions.batch'));
|
||||
$scope.actions = [notPermittedAction()];
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
|
||||
expect(element.children().length).toBe(0);
|
||||
});
|
||||
|
||||
it('should have multiple buttons for multiple actions as a list', function () {
|
||||
var action1 = getTemplatePath('action-create');
|
||||
var action2 = getTemplatePath('action-delete');
|
||||
|
||||
var element = angular.element(getTemplate('actions.batch'));
|
||||
$scope.actions = [permittedActionWithUrl(action1), permittedActionWithUrl(action2)];
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
|
||||
expect(element.children().length).toBe(2);
|
||||
var actionList = element.find('action-list');
|
||||
expect(actionList.length).toBe(2);
|
||||
expect(actionList.attr('class').indexOf('btn-addon')).toBeGreaterThan(-1);
|
||||
expect(actionList.find('button.btn-create').text().trim()).toEqual('Create Image');
|
||||
expect(actionList.find('button.text-danger').text().trim()).toEqual('Delete Image');
|
||||
});
|
||||
|
||||
it('should have as many buttons as permitted', function () {
|
||||
var actionTemplate1 = getTemplatePath('action-create');
|
||||
|
||||
var element = angular.element(getTemplate('actions.batch'));
|
||||
$scope.actions = [permittedActionWithUrl(actionTemplate1), notPermittedAction()];
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
|
||||
expect(element.children().length).toBe(1);
|
||||
var actionList = element.find('action-list');
|
||||
expect(actionList.length).toBe(1);
|
||||
expect(actionList.attr('class').indexOf('btn-addon')).toBeGreaterThan(-1);
|
||||
expect(actionList.find('button.btn-default').text().trim()).toEqual('Create Image');
|
||||
});
|
||||
|
||||
it('should have multiple buttons as a dropdown', function () {
|
||||
var action1 = getTemplatePath('action-create');
|
||||
var action2 = getTemplatePath('action-delete');
|
||||
|
||||
var element = angular.element(getTemplate('actions.row'));
|
||||
$scope.actions = [permittedActionWithUrl(action1), permittedActionWithUrl(action2)];
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
|
||||
expect(element.children().length).toBe(1);
|
||||
var actionList = element.find('action-list');
|
||||
expect(actionList.length).toBe(1);
|
||||
expect(actionList.attr('class').indexOf('btn-addon')).toEqual(-1);
|
||||
expect(actionList.find('button .fa-user-plus').text().trim()).toEqual('Create Image');
|
||||
expect(actionList.find('li a.text-danger').text().trim()).toEqual('Delete Image');
|
||||
});
|
||||
|
||||
it('should have multiple buttons as a dropdown for actions text', function () {
|
||||
var element = angular.element(getTemplate('actions.row'));
|
||||
$scope.actions = [
|
||||
permittedActionWithText('Create Image', 'image'),
|
||||
permittedActionWithText('Delete Image', 'image', 'text-danger')
|
||||
];
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
|
||||
expect(element.children().length).toBe(1);
|
||||
var actionList = element.find('action-list');
|
||||
expect(actionList.length).toBe(1);
|
||||
expect(actionList.attr('class').indexOf('btn-addon')).toEqual(-1);
|
||||
expect(actionList.find('button .fa').text().trim()).toEqual('Create Image');
|
||||
expect(actionList.find('li a.text-danger').text().trim()).toEqual('Delete Image');
|
||||
});
|
||||
|
||||
it('should have one button if only one permitted for dropdown', function () {
|
||||
var element = angular.element(getTemplate('actions.row'));
|
||||
$scope.actions = [
|
||||
permittedActionWithUrl(getTemplatePath('action-create')),
|
||||
notPermittedAction()
|
||||
];
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
|
||||
expect(element.children().length).toBe(1);
|
||||
var actionList = element.find('action-list');
|
||||
expect(actionList.length).toBe(1);
|
||||
expect(actionList.attr('class').indexOf('btn-addon')).toBeGreaterThan(-1);
|
||||
expect(actionList.find('button .fa-user-plus').text().trim()).toEqual('Create Image');
|
||||
});
|
||||
|
||||
function permittedActionWithUrl(templateUrl) {
|
||||
return {
|
||||
template: {url: templateUrl},
|
||||
permissions: getPermission(true),
|
||||
callback: 'callback'
|
||||
};
|
||||
}
|
||||
|
||||
function permittedActionWithText(text, item, actionClasses) {
|
||||
return {
|
||||
template: {
|
||||
text: text,
|
||||
item: item,
|
||||
actionClasses: actionClasses
|
||||
},
|
||||
permissions: getPermission(true),
|
||||
callback: 'callback'
|
||||
};
|
||||
}
|
||||
|
||||
function permittedActionWithType(templateType, text, item) {
|
||||
return {
|
||||
template: {
|
||||
type: templateType,
|
||||
text: text,
|
||||
item: item
|
||||
},
|
||||
permissions: getPermission(true),
|
||||
callback: 'callback'
|
||||
};
|
||||
}
|
||||
|
||||
function notPermittedAction() {
|
||||
return {template: 'dummy', permissions: getPermission(false), callback: 'callback'};
|
||||
}
|
||||
|
||||
function getTemplate(templateName) {
|
||||
return $templateCache.get(getTemplatePath(templateName));
|
||||
}
|
||||
|
||||
function getTemplatePath(templateName) {
|
||||
return basePath + 'action-list/' + templateName + '.mock.html';
|
||||
}
|
||||
|
||||
function getPermission(allowed) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
if (allowed) {
|
||||
deferred.resolve();
|
||||
} else {
|
||||
deferred.reject();
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
});
|
||||
})();
|
@ -0,0 +1,2 @@
|
||||
<actions allowed-actions="actions" action-list-type="row">
|
||||
</actions>
|
225
horizon/static/framework/widgets/action-list/actions.service.js
Normal file
225
horizon/static/framework/widgets/action-list/actions.service.js
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.framework.widgets.action-list')
|
||||
.factory('horizon.framework.widgets.action-list.actions.service', actionsService);
|
||||
|
||||
actionsService.$inject = [
|
||||
'$compile',
|
||||
'$http',
|
||||
'$q',
|
||||
'$templateCache',
|
||||
'horizon.framework.widgets.basePath'
|
||||
];
|
||||
|
||||
function actionsService($compile, $http, $q, $templateCache, basePath) {
|
||||
return function(spec) {
|
||||
return createService(spec.scope, spec.element, spec.listType);
|
||||
};
|
||||
|
||||
///////////////
|
||||
|
||||
function createService(scope, element, listType) {
|
||||
var service = {
|
||||
renderActions: renderActions
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
function renderActions(allowedActions) {
|
||||
getPermittedActions(allowedActions).then(renderPermittedActions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permitted actions from the list of allowed actions
|
||||
* by resolving the promises in the permissions object.
|
||||
*/
|
||||
function getPermittedActions(allowedActions) {
|
||||
var deferred = $q.defer();
|
||||
var permittedActions = [];
|
||||
var promises = allowedActions.map(actionPermitted);
|
||||
|
||||
$q.all(promises).then(onResolved);
|
||||
|
||||
return deferred.promise;
|
||||
|
||||
function actionPermitted(action) {
|
||||
var deferredInner = $q.defer();
|
||||
action.permissions.then(onSuccess, onError);
|
||||
return deferredInner.promise;
|
||||
|
||||
function onSuccess() {
|
||||
permittedActions.push(action);
|
||||
deferredInner.resolve();
|
||||
}
|
||||
|
||||
function onError() {
|
||||
deferredInner.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
function onResolved() {
|
||||
deferred.resolve(permittedActions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render permitted actions as per the list type
|
||||
*/
|
||||
function renderPermittedActions(permittedActions) {
|
||||
if (permittedActions.length > 0) {
|
||||
var templateFetch = $q.all(permittedActions.map(getTemplate));
|
||||
|
||||
if (listType === 'batch' || permittedActions.length === 1) {
|
||||
element.addClass('btn-addon');
|
||||
templateFetch.then(addButtons);
|
||||
} else {
|
||||
templateFetch.then(addDropdown);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all the buttons as a list of buttons
|
||||
*/
|
||||
function addButtons(templates) {
|
||||
templates.forEach(addTemplate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the button template as a button
|
||||
*/
|
||||
function addTemplate(template) {
|
||||
element.append(renderButton(template, scope));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all the buttons as a dropdown button group
|
||||
*/
|
||||
function addDropdown(templates) {
|
||||
var splitButton = getSplitButton(templates[0]);
|
||||
var actionList = [];
|
||||
|
||||
for (var iCnt = 1; iCnt < templates.length; iCnt++) {
|
||||
actionList.push(getMenuButton(templates[iCnt]));
|
||||
}
|
||||
|
||||
var actionListElem = renderList(actionList, splitButton, scope);
|
||||
element.append($compile(actionListElem)(scope));
|
||||
}
|
||||
|
||||
/**
|
||||
* Render buttons each inside the <action-list> element
|
||||
*/
|
||||
function renderButton(actionTemplate, scope) {
|
||||
var actionElement = angular.element(actionTemplate.template);
|
||||
actionElement.attr('callback', actionTemplate.callback);
|
||||
|
||||
var actionListElem = angular.element('<action-list>');
|
||||
actionListElem.addClass('btn-addon');
|
||||
actionListElem.append(actionElement);
|
||||
|
||||
return $compile(actionListElem)(scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render buttons inside a single <action-list> element
|
||||
* with the first being a `split-button` and the rest as
|
||||
* `menu-item` buttons
|
||||
*/
|
||||
function renderList(actionList, splitButton, scope) {
|
||||
var actionListElem = angular.element('<action-list>');
|
||||
actionListElem.attr('dropdown', 'true');
|
||||
actionListElem.append(splitButton);
|
||||
actionListElem.append(getMenu(actionList, scope));
|
||||
return actionListElem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTML for a `split-button`
|
||||
*/
|
||||
function getSplitButton(actionTemplate) {
|
||||
var actionElement = angular.element(actionTemplate.template);
|
||||
actionElement.attr('button-type', 'split-button');
|
||||
actionElement.attr('action-classes', '"btn btn-default"');
|
||||
actionElement.attr('callback', actionTemplate.callback);
|
||||
return actionElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTML for a `menu`
|
||||
*/
|
||||
function getMenu(actionList, scope) {
|
||||
var menuElem = angular.element('<menu>');
|
||||
menuElem.append(actionList);
|
||||
return menuElem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTML for a `menu-item` button
|
||||
*/
|
||||
function getMenuButton(actionTemplate) {
|
||||
var actionElement = angular.element(actionTemplate.template);
|
||||
actionElement.attr('button-type', 'menu-item');
|
||||
actionElement.attr('callback', actionTemplate.callback);
|
||||
return actionElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the HTML Template for the Action
|
||||
*/
|
||||
function getTemplate(action) {
|
||||
var defered = $q.defer();
|
||||
$http.get(getTemplateUrl(action), {cache: $templateCache}).then(onTemplateGet);
|
||||
return defered.promise;
|
||||
|
||||
function onTemplateGet(response) {
|
||||
var template = response.data
|
||||
.replace('$action-classes$', action.template.actionClasses || '')
|
||||
.replace('$text$', action.template.text)
|
||||
.replace('$item$', action.template.item);
|
||||
defered.resolve({template: template, callback: action.callback});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Template URL for the Action
|
||||
* The template can be
|
||||
* 1. Explicit URL
|
||||
* 2. Based of a list of known templates
|
||||
* 3. Based of the type of List
|
||||
*
|
||||
* Uses the `listType` which can either be `row` or `batch`.
|
||||
*/
|
||||
function getTemplateUrl(action) {
|
||||
if (angular.isDefined(action.template.url)) {
|
||||
// use the given URL
|
||||
return action.template.url;
|
||||
} else if (angular.isDefined(action.template.type)) {
|
||||
// determine the template by the given type
|
||||
return basePath + 'action-list/actions-' + action.template.type + '.template.html';
|
||||
} else {
|
||||
// determine the template by `listType` which can be row or batch
|
||||
return basePath + 'action-list/actions-' + listType + '.template.html';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // end of service
|
||||
})(); // end of IIFE
|
Loading…
Reference in New Issue
Block a user