Angular Confirmation Modal
We need a simple dialog for confirming dangerous actions such as delete. This patch introduces a simple wrapper that allows user to pass in: 1. Title - title of the dialog 2. Body - simple text or html (not a template!) 3. Submit label 4. Cancel label Change-Id: Ibe019bf8a2d08c6323ebb6e39bfac7dcac8852c6 Partially-Implements: blueprint angularize-identity-tables
This commit is contained in:
parent
0a85d5ebb0
commit
7cb9efa4fd
95
horizon/static/angular/modal/modal.js
vendored
Normal file
95
horizon/static/angular/modal/modal.js
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @name hz.widget.modal
|
||||
*
|
||||
* # hz.widget.modal
|
||||
*
|
||||
* The `hz.widget.modal` provides modal services.
|
||||
*
|
||||
* Requires {@link http://angular-ui.github.io/bootstrap/ `Angular-bootstrap`}
|
||||
*
|
||||
* | Components |
|
||||
* |--------------------------------------------------------------------------|
|
||||
* | {@link hz.widget.modal.controller:simpleModalCtrl `simpleModalCtrl`} |
|
||||
* | {@link hz.widget.modal.factory:simpleModalService `simpleModalService`} |
|
||||
*
|
||||
*/
|
||||
angular.module('hz.widget.modal', ['ui.bootstrap'])
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name simpleModalCtrl
|
||||
*
|
||||
* @param(object) scope of the controller
|
||||
* @param(object) modal instance from angular-bootstrap
|
||||
* @param(object) context object provided by the user
|
||||
*
|
||||
* @description
|
||||
* Horizon's controller for confirmation dialog.
|
||||
* Passes context along to the template.
|
||||
* If user presses cancel button or closes dialog, modal gets dismissed.
|
||||
* If user presses submit button, modal gets closed.
|
||||
* This controller is automatically included in modalService.
|
||||
*/
|
||||
.controller('simpleModalCtrl', [ '$scope', '$modalInstance', 'context',
|
||||
function($scope, $modalInstance, context) {
|
||||
$scope.context = context;
|
||||
$scope.submit = function(){ $modalInstance.close(); };
|
||||
$scope.cancel = function(){ $modalInstance.dismiss('cancel'); };
|
||||
} // end of function
|
||||
]) // end of controller
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name simpleModalService
|
||||
*
|
||||
* @description
|
||||
* Horizon's wrapper for angular-bootstrap modal service.
|
||||
* It should only be use for small confirmation dialogs.
|
||||
* @param {object} the object containing title, body, submit, and cancel labels
|
||||
* @param {object} the object returned from angular-bootstrap $modal
|
||||
*
|
||||
* @example:
|
||||
* angular.controller('modalExampleCtrl', [ '$scope', 'simpleModalService',
|
||||
* function($scope, simpleModalService){
|
||||
* var options = {
|
||||
* title: 'Confirm Delete',
|
||||
* body: 'Are you sure you want to delete this item?',
|
||||
* submit: 'Yes',
|
||||
* cancel: 'No',
|
||||
* };
|
||||
* simpleModalService(options).result.then(function(){
|
||||
* // user clicked on submit button
|
||||
* // do something useful here
|
||||
* });
|
||||
* }
|
||||
* ]);
|
||||
*/
|
||||
.factory('simpleModalService', ['$modal', 'basePath',
|
||||
function($modal, path) {
|
||||
return function(params) {
|
||||
if (params && params.title && params.body){
|
||||
var options = {
|
||||
controller: 'simpleModalCtrl',
|
||||
templateUrl: path + 'modal/simple-modal.html',
|
||||
resolve: {
|
||||
context: function() {
|
||||
return {
|
||||
title: params.title? params.title: '',
|
||||
body: params.body? params.body: '',
|
||||
submit: params.submit? params.submit: gettext('Submit'),
|
||||
cancel: gettext('Cancel')
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
return $modal.open(options);
|
||||
}
|
||||
}; // end of return
|
||||
} // end of function
|
||||
]); // end of factory
|
||||
|
||||
})();
|
18
horizon/static/angular/modal/simple-modal.html
Normal file
18
horizon/static/angular/modal/simple-modal.html
Normal file
@ -0,0 +1,18 @@
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">
|
||||
<span ng-bind="::context.title"></span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="modal-body clearfix">
|
||||
<p ng-bind="::context.body"></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-default secondary"
|
||||
type="button" ng-click="cancel()">
|
||||
<span ng-bind="::context.cancel"></span>
|
||||
</button>
|
||||
<button class="btn btn-primary"
|
||||
type="button" ng-click="submit()">
|
||||
<span ng-bind="::context.submit"></span>
|
||||
</button>
|
||||
</div>
|
55
horizon/static/angular/modal/simple-modal.spec.js
Normal file
55
horizon/static/angular/modal/simple-modal.spec.js
Normal file
@ -0,0 +1,55 @@
|
||||
'use strict';
|
||||
|
||||
describe('hz.widget.modal module', function(){
|
||||
it('should have been defined', function(){
|
||||
expect(angular.module('hz.widget.modal')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('modal factory', function(){
|
||||
|
||||
var modal;
|
||||
var modalData = {
|
||||
title: 'Confirm deletion',
|
||||
body: 'Are you sure?',
|
||||
submit: 'Yes',
|
||||
cancel: 'No'
|
||||
};
|
||||
|
||||
beforeEach(module('ui.bootstrap'));
|
||||
beforeEach(module('hz'));
|
||||
beforeEach(module('hz.widgets'));
|
||||
beforeEach(module('hz.widget.modal'));
|
||||
beforeEach(inject(function($injector, simpleModalService){
|
||||
modal = simpleModalService;
|
||||
}));
|
||||
|
||||
it('should fail without any params', function(){
|
||||
expect(modal()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should fail without a title', function(){
|
||||
var data = angular.copy(modalData);
|
||||
delete data.title;
|
||||
expect(modal(data)).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should fail without a body', function(){
|
||||
var data = angular.copy(modalData);
|
||||
delete data.body;
|
||||
expect(modal(data)).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should have default submit and cancel labels', function(){
|
||||
var data = angular.copy(modalData);
|
||||
delete data.submit;
|
||||
delete data.cancel;
|
||||
expect(modal(data)).toBeDefined();
|
||||
});
|
||||
|
||||
it('should work when all params are supplied', function(){
|
||||
var data = angular.copy(modalData);
|
||||
expect(modal(data)).toBeDefined();
|
||||
});
|
||||
|
||||
});
|
@ -4,7 +4,8 @@
|
||||
angular.module('hz.widgets', [
|
||||
'hz.widget.help-panel',
|
||||
'hz.widget.wizard',
|
||||
'hz.widget.table'
|
||||
'hz.widget.table',
|
||||
'hz.widget.modal'
|
||||
])
|
||||
.constant('basePath', '/static/angular/');
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
<script src='{{ STATIC_URL }}angular/help-panel/help-panel.js'></script>
|
||||
<script src='{{ STATIC_URL }}angular/wizard/wizard.js'></script>
|
||||
<script src='{{ STATIC_URL }}angular/table/table.js'></script>
|
||||
<script src='{{ STATIC_URL }}angular/modal/modal.js'></script>
|
||||
|
||||
<script src='{{ STATIC_URL }}horizon/lib/jquery/jquery.quicksearch.js' type='text/javascript' charset="utf-8"></script>
|
||||
<script src="{{ STATIC_URL }}horizon/lib/jquery/jquery.tablesorter.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
@ -29,6 +29,7 @@ class ServicesTests(test.JasmineTests):
|
||||
'angular/help-panel/help-panel.js',
|
||||
'angular/wizard/wizard.js',
|
||||
'angular/table/table.js',
|
||||
'angular/modal/modal.js',
|
||||
]
|
||||
specs = [
|
||||
'horizon/tests/jasmine/utilsSpec.js',
|
||||
@ -37,8 +38,9 @@ class ServicesTests(test.JasmineTests):
|
||||
'angular/help-panel/help-panel.spec.js',
|
||||
'angular/wizard/wizard.spec.js',
|
||||
'angular/table/table.spec.js',
|
||||
'angular/modal/simple-modal.spec.js',
|
||||
]
|
||||
externalTemplates = [
|
||||
'angular/help-panel/help-panel.html',
|
||||
'angular/wizard/wizard.html',
|
||||
'angular/wizard/wizard.html'
|
||||
]
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
<div class="switcher_bar">
|
||||
<div class="dropdown context-selection">
|
||||
<button class="btn btn-default btn-topnav dropdown-toggle" data-toggle="dropdown">
|
||||
<button class="btn btn-default btn-topnav dropdown-toggle">
|
||||
{% show_overview %}
|
||||
</button>
|
||||
<div class="dropdown-menu topbar-dropdown-menu">
|
||||
@ -27,7 +27,7 @@
|
||||
|
||||
<div id="user_info" class="pull-right">
|
||||
<div id="profile_editor_switcher" class="dropdown switcher_bar" tabindex='1'>
|
||||
<button class="btn btn-default btn-topnav dropdown-toggle" data-toggle="dropdown">
|
||||
<button class="btn btn-default btn-topnav dropdown-toggle">
|
||||
<span class="fa fa-user"></span>
|
||||
{{ request.user.username }}
|
||||
<span class="caret"></span>
|
||||
|
Loading…
Reference in New Issue
Block a user