summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Vobornik <pvoborni@redhat.com>2014-04-16 12:04:59 +0200
committerPetr Vobornik <pvoborni@redhat.com>2014-06-10 10:23:26 +0200
commitfaf4fea30fd01ad5f5c372877d0e8fe20963dc91 (patch)
tree91674ecb80ed855dad1ed3e7e0a7991b58e05a79
parent2f3dc7908d1c62b729ab38b6d684dc0e942c4528 (diff)
downloadfreeipa-faf4fea30fd01ad5f5c372877d0e8fe20963dc91.tar.gz
freeipa-faf4fea30fd01ad5f5c372877d0e8fe20963dc91.tar.xz
freeipa-faf4fea30fd01ad5f5c372877d0e8fe20963dc91.zip
webui: patternFly dialog
Reviewed-By: Endi Sukma Dewata <edewata@redhat.com>
-rw-r--r--install/ui/less/dialog.less104
-rw-r--r--install/ui/less/ipa.less1
-rw-r--r--install/ui/src/freeipa/dialog.js72
-rw-r--r--install/ui/test/all_tests.html1
-rw-r--r--install/ui/test/ipa_tests.html1
-rw-r--r--install/ui/test/ipa_tests.js21
-rw-r--r--ipatests/test_webui/ui_driver.py11
7 files changed, 68 insertions, 143 deletions
diff --git a/install/ui/less/dialog.less b/install/ui/less/dialog.less
deleted file mode 100644
index fda2b0a2b..000000000
--- a/install/ui/less/dialog.less
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * Authors:
- * UXD team
- * Petr Vobornik <pvoborni@redhat.com>
- *
- * Copyright (C) 2013 Red Hat
- * see file 'COPYING' for use and warranty information
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-.rcue-dialog-background {
- z-index: 1049;
- background-color: rgba(0,0,0, 0.39);
- width: 100%;
- height: 100%;
- position: fixed;
- top: 0;
- left: 0;
- overflow: auto;
-
- .rcue-dialog-container {
- padding: 30px;
- }
-
- .rcue-dialog {
- position: relative;
- padding: 16px 22px;
- max-width: 600px;
- border: 1px solid #6e6d6d;
- box-shadow: rgba(0,0,0, 0.39) 0 0 2px;
- background-color: #fff;
- margin: auto;
-
- header {
- margin-bottom: 48px;
-
- h1 {
- float: left;
- margin: 0;
- text-transform: none;
- }
-
- a {
- float: right;
- }
-
- .rcue-button-close {
-
- position: absolute;
- top: 15px;
- right: 19px;
- display: inline-block;
-
- .fa;
-
- &:before {
- content: @fa-var-times;
- }
-
- &:hover {
- text-decoration: none;
- }
- }
- }
-
- .rcue-dialog-body {
- position: relative;
- top: 0;
- bottom: 60px;
- clear: both;
- }
-
- footer {
- clear: both;
- padding-left: 22px;
- min-height: 25px;
-
- button {
- float: right;
- margin: 0px 5px 5px;
- }
-
- .clear {
- clear: both;
- }
- }
-
- code {
- white-space: normal;
- }
- }
-}
diff --git a/install/ui/less/ipa.less b/install/ui/less/ipa.less
index e87c15885..57c249fb7 100644
--- a/install/ui/less/ipa.less
+++ b/install/ui/less/ipa.less
@@ -6,7 +6,6 @@
@import "variables";
@import "mixins";
-@import "dialog";
@import "brand";
@import "forms-override";
@import "alerts";
diff --git a/install/ui/src/freeipa/dialog.js b/install/ui/src/freeipa/dialog.js
index 228bc218d..dc6eb41c9 100644
--- a/install/ui/src/freeipa/dialog.js
+++ b/install/ui/src/freeipa/dialog.js
@@ -243,37 +243,39 @@ IPA.dialog = function(spec) {
}
that.dom_node = $('<div/>', {
- 'class': 'rcue-dialog-background',
- keydown: that.on_key_down
+ 'class': 'modal fade',
+ keydown: that.on_key_down,
+ tabindex: '-1',
+ 'role': 'dialog',
+ 'aria-labelledby': 'myLargeModalLabel',
+ 'aria-hidden': 'true'
});
- var container_node = $('<div/>', {
- 'class': 'rcue-dialog-container'
- }).appendTo(that.dom_node);
-
that.dialog_node = $('<div/>', {
- 'class': 'rcue-dialog row',
+ 'class': 'modal-dialog',
id: that.get_id(),
'data-name' : that.name,
role: 'dialog',
tabIndex: -1 // make the div focusable
- }).appendTo(container_node);
+ }).appendTo(that.dom_node);
- that.header_node = $('<header/>');
+ that.content_node = $('<div/>', { 'class': 'modal-content' }).
+ appendTo(that.dialog_node);
+ that.header_node = $('<div/>', { 'class': 'modal-header' });
that.create_header();
- that.header_node.appendTo(that.dialog_node);
+ that.header_node.appendTo(that.content_node);
that.body_node = $('<div/>', {
- 'class': 'rcue-dialog-body row'
+ 'class': 'modal-body'
});
// for backwards compatibility
that.container = that.body_node;
that.create_content();
- that.body_node.appendTo(that.dialog_node);
+ that.body_node.appendTo(that.content_node);
- that.footer_node = $('<footer/>');
+ that.footer_node = $('<div/>', { 'class': 'modal-footer' });
that.create_footer();
- that.footer_node.appendTo(that.dialog_node);
+ that.footer_node.appendTo(that.content_node);
that.policies.post_create();
return that.dom_node;
@@ -287,17 +289,22 @@ IPA.dialog = function(spec) {
that.create_header = function() {
that.header_node.empty();
- that.title_node = $('<h1/>', {
- text: that.title
- }).appendTo(that.header_node);
- that.title_close_button = $('<a/>', {
- href: '#',
- 'class': 'rcue-button-close',
+
+ that.title_close_button = $('<button/>', {
+ 'class': 'close',
+ 'aria-hidden': 'true',
click: function() {
that.close();
}
}).appendTo(that.header_node);
+ $('<span/>', { 'class': 'fa fa-times' }).appendTo(that.title_close_button);
+
+ that.title_node = $('<h4/>', {
+ 'class': 'modal-title',
+ text: that.title
+ }).appendTo(that.header_node);
+
return that.header_node;
};
@@ -441,7 +448,15 @@ IPA.dialog = function(spec) {
that.register_listeners();
IPA.opened_dialogs.add_dialog(that);
- that.focus_first_element();
+
+ this.dom_node.one('shown.bs.modal', function() {
+ that.focus_first_element();
+ });
+
+ this.dom_node.modal({
+ backdrop: 'static',
+ keyboard: 'false'
+ });
};
/**
@@ -508,11 +523,18 @@ IPA.dialog = function(spec) {
that.remove_listeners();
- that.dom_node.remove();
- that.dom_node = null;
+ if (!that.dom_node) return;
+
+ var dom_node = that.dom_node;
+
+ that.dom_node.one('hidden.bs.modal', function() {
+ dom_node.remove();
+ that.dom_node = null;
+ IPA.opened_dialogs.remove_dialog(that);
+ IPA.opened_dialogs.focus_top();
+ });
- IPA.opened_dialogs.remove_dialog(that);
- IPA.opened_dialogs.focus_top();
+ that.dom_node.modal('hide');
};
/**
diff --git a/install/ui/test/all_tests.html b/install/ui/test/all_tests.html
index 28ab2dbc8..65c54078f 100644
--- a/install/ui/test/all_tests.html
+++ b/install/ui/test/all_tests.html
@@ -6,6 +6,7 @@
<script type="text/javascript" src="qunit.js"></script>
<script type="text/javascript" src="../js/libs/jquery.js"></script>
<script type="text/javascript" src="../js/libs/jquery.ordered-map.js"></script>
+ <script type="text/javascript" src="../js/libs/bootstrap.js"></script>
<script type="text/javascript" src="config.js"></script>
<script type="text/javascript" src="../js/dojo/dojo.js"></script>
diff --git a/install/ui/test/ipa_tests.html b/install/ui/test/ipa_tests.html
index cfe779a84..1178e9874 100644
--- a/install/ui/test/ipa_tests.html
+++ b/install/ui/test/ipa_tests.html
@@ -6,6 +6,7 @@
<script type="text/javascript" src="qunit.js"></script>
<script type="text/javascript" src="../js/libs/jquery.js"></script>
<script type="text/javascript" src="../js/libs/jquery.ordered-map.js"></script>
+ <script type="text/javascript" src="../js/libs/bootstrap.js"></script>
<script type="text/javascript" src="config.js"></script>
<script type="text/javascript" src="../js/dojo/dojo.js"></script>
diff --git a/install/ui/test/ipa_tests.js b/install/ui/test/ipa_tests.js
index 52110c481..e3bb65eb8 100644
--- a/install/ui/test/ipa_tests.js
+++ b/install/ui/test/ipa_tests.js
@@ -24,7 +24,8 @@ define([
'freeipa/rpc',
'freeipa/dialog',
'freeipa/widget',
- 'freeipa/details'],
+ 'freeipa/details',
+ 'freeipa/entity'],
function(IPA, $, rpc) {
return function() {
@@ -157,7 +158,7 @@ test("Testing successful rpc.command().", function() {
ajax_counter, 1,
"Checking ajax invocation counter");
- var dialog = $('#error_dialog');
+ var dialog = $('[data-name=error_dialog]');
ok(
dialog.length === 0,
@@ -183,6 +184,7 @@ test("Testing unsuccessful rpc.command().", function() {
var success_handler_counter = 0;
var error_handler_counter = 0;
+ var dialog_selector = '[data-name=error_dialog]';
function success_handler(data, status, xhr) {
success_handler_counter++;
@@ -225,12 +227,12 @@ test("Testing unsuccessful rpc.command().", function() {
}).execute();
function click_button(name) {
- var dialog = $('#error_dialog');
+ var dialog = $(dialog_selector);
var btn = $('button[name='+name+']', dialog).first();
btn.trigger('click');
}
- var dialog = $('#error_dialog');
+ var dialog = $(dialog_selector);
equals(
ajax_counter, 1,
@@ -267,14 +269,15 @@ test("Testing unsuccessful rpc.command().", function() {
equals(ajax_counter, 3,
"Checking ajax invocation counter");
- dialog = $('#error_dialog');
-
- ok(dialog.length === 0,
- "After cancel, the dialog box is closed.");
-
ok(success_handler_counter === 0 && error_handler_counter === 1,
"Only the error handler is called.");
+ // cleanup - qunit doesn't really play well with asynchronous opening and
+ // closing of dialogs
+ // opening and closing may be rewritten as asynchronous test
+ $('.modal').remove();
+ $('.modal-backdrop').remove();
+
$.ajax = orig;
});
diff --git a/ipatests/test_webui/ui_driver.py b/ipatests/test_webui/ui_driver.py
index b57acab1f..4b3069640 100644
--- a/ipatests/test_webui/ui_driver.py
+++ b/ipatests/test_webui/ui_driver.py
@@ -504,9 +504,9 @@ class UI_driver(object):
"""
Get all dialogs in DOM
"""
- s = 'div[role=dialog]'
+ s = '.modal-dialog'
if name:
- s += " div[data-name='%s'" % name
+ s += "[data-name='%s']" % name
dialogs = self.find(s, By.CSS_SELECTOR, many=True)
if strict:
assert dialogs, "No dialogs found"
@@ -526,7 +526,7 @@ class UI_driver(object):
"""
Get last opened error dialog or None.
"""
- s = "div[role=dialog] div[data-name='%s']" % dialog_name
+ s = ".modal-dialog[data-name='%s']" % dialog_name
dialogs = self.find(s, By.CSS_SELECTOR, many=True)
dialog = None
if dialogs:
@@ -542,7 +542,7 @@ class UI_driver(object):
info = None
if dialog:
- body = self.find('.rcue-dialog-body', By.CSS_SELECTOR, dialog, strict=True)
+ body = self.find('.modal-body', By.CSS_SELECTOR, dialog, strict=True)
info = {
'name': dialog.get_attribute('data-name'),
'text': body.text,
@@ -644,6 +644,9 @@ class UI_driver(object):
s = "[name=profile-menu] a[href='#%s']" % name
btn = self.find(s, By.CSS_SELECTOR, strict=True)
btn.click()
+ # action is usually followed by opening a dialog, add wait to compensate
+ # possible dialog transition effect
+ self.wait(0.5)
def get_form(self):
"""