diff options
author | Petr Vobornik <pvoborni@redhat.com> | 2014-04-16 12:04:59 +0200 |
---|---|---|
committer | Petr Vobornik <pvoborni@redhat.com> | 2014-06-10 10:23:26 +0200 |
commit | faf4fea30fd01ad5f5c372877d0e8fe20963dc91 (patch) | |
tree | 91674ecb80ed855dad1ed3e7e0a7991b58e05a79 | |
parent | 2f3dc7908d1c62b729ab38b6d684dc0e942c4528 (diff) | |
download | freeipa-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.less | 104 | ||||
-rw-r--r-- | install/ui/less/ipa.less | 1 | ||||
-rw-r--r-- | install/ui/src/freeipa/dialog.js | 72 | ||||
-rw-r--r-- | install/ui/test/all_tests.html | 1 | ||||
-rw-r--r-- | install/ui/test/ipa_tests.html | 1 | ||||
-rw-r--r-- | install/ui/test/ipa_tests.js | 21 | ||||
-rw-r--r-- | ipatests/test_webui/ui_driver.py | 11 |
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): """ |