summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Vobornik <pvoborni@redhat.com>2013-10-18 12:14:25 +0200
committerMartin Kosek <mkosek@redhat.com>2014-01-21 12:04:02 +0100
commit23c042775c0b6d918e7f05229a834622382e66fb (patch)
treec87de1fbe11ff84a99f33f527245e6bac0f51164
parentd4a6f20e65d8ba526e346eb134bb9b467fcbabad (diff)
downloadfreeipa-23c042775c0b6d918e7f05229a834622382e66fb.tar.gz
freeipa-23c042775c0b6d918e7f05229a834622382e66fb.tar.xz
freeipa-23c042775c0b6d918e7f05229a834622382e66fb.zip
RCUE dialog implementation
https://fedorahosted.org/freeipa/ticket/3904
-rw-r--r--install/ui/less/dialog.less96
-rw-r--r--install/ui/less/rcue.less1
-rw-r--r--install/ui/src/freeipa/add.js6
-rw-r--r--install/ui/src/freeipa/automount.js4
-rwxr-xr-xinstall/ui/src/freeipa/certificate.js8
-rw-r--r--install/ui/src/freeipa/dialog.js236
-rw-r--r--install/ui/src/freeipa/dns.js8
-rw-r--r--install/ui/src/freeipa/hbactest.js4
-rw-r--r--install/ui/src/freeipa/host.js10
-rw-r--r--install/ui/src/freeipa/ipa.js6
-rw-r--r--install/ui/src/freeipa/service.js2
-rw-r--r--install/ui/src/freeipa/widget.js2
-rw-r--r--ipatests/test_webui/ui_driver.py8
13 files changed, 288 insertions, 103 deletions
diff --git a/install/ui/less/dialog.less b/install/ui/less/dialog.less
new file mode 100644
index 000000000..00bbde5a8
--- /dev/null
+++ b/install/ui/less/dialog.less
@@ -0,0 +1,96 @@
+/**
+ * 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;
+ }
+
+ a {
+ float: right;
+ }
+
+ .rcue-button-close {
+ background-image: url("../img/dialog-button-close.png");
+ width: 25px;
+ height: 25px;
+ background-repeat: no-repeat;
+ background-position: center;
+ display: inline-block;
+ margin-top: -4px;
+ margin-right: -6px;
+ position: absolute;
+ top: 15px;
+ right: 19px;
+ }
+ }
+
+ .rcue-dialog-body {
+ position: relative;
+ top: 0;
+ bottom: 60px;
+ clear: both;
+ padding: 0 15px 10px;
+ }
+
+ footer {
+ clear: both;
+ padding-left: 22px;
+ min-height: 25px;
+
+ button {
+ float: right;
+ margin: 0px 5px 5px;
+ }
+
+ .clear {
+ clear: both;
+ }
+ }
+ }
+}
diff --git a/install/ui/less/rcue.less b/install/ui/less/rcue.less
index fc8f51484..6b27259d6 100644
--- a/install/ui/less/rcue.less
+++ b/install/ui/less/rcue.less
@@ -4,5 +4,6 @@
@import "rcue/navbar";
@import "rcue/buttons";
@import "rcue/forms";
+@import "dialog";
@import "brand";
@import "forms-override.less";
diff --git a/install/ui/src/freeipa/add.js b/install/ui/src/freeipa/add.js
index 00d499da5..23eac54d6 100644
--- a/install/ui/src/freeipa/add.js
+++ b/install/ui/src/freeipa/add.js
@@ -232,8 +232,8 @@ IPA.entity_adder_dialog = function(spec) {
};
/** @inheritDoc */
- that.create = function() {
- that.dialog_create();
+ that.create_content = function() {
+ that.dialog_create_content();
var div = $('<div/>', {
}).appendTo(that.container);
@@ -251,7 +251,7 @@ IPA.entity_adder_dialog = function(spec) {
};
// methods that should be invoked by subclasses
- that.entity_adder_dialog_create = that.create;
+ that.entity_adder_dialog_create_content = that.create_content;
that.entity_adder_dialog_create_add_command = that.create_add_command;
that.entity_adder_dialog_get_success_message = that.get_success_message;
diff --git a/install/ui/src/freeipa/automount.js b/install/ui/src/freeipa/automount.js
index eae6a4653..fca476fd0 100644
--- a/install/ui/src/freeipa/automount.js
+++ b/install/ui/src/freeipa/automount.js
@@ -283,8 +283,8 @@ IPA.automountmap_adder_dialog = function(spec) {
var that = IPA.entity_adder_dialog(spec);
- that.create = function() {
- that.entity_adder_dialog_create();
+ that.create_content = function() {
+ that.entity_adder_dialog_create_content();
var method_widget = that.widgets.get_widget('general.method');
var indirect_section = that.widgets.get_widget('indirect');
diff --git a/install/ui/src/freeipa/certificate.js b/install/ui/src/freeipa/certificate.js
index 2fab64b7f..5da1de813 100755
--- a/install/ui/src/freeipa/certificate.js
+++ b/install/ui/src/freeipa/certificate.js
@@ -197,7 +197,7 @@ IPA.cert.download_dialog = function(spec) {
}
});
- that.create = function() {
+ that.create_content = function() {
var textarea = $('<textarea/>', {
'class': 'certificate',
readonly: 'yes'
@@ -227,7 +227,7 @@ IPA.cert.revoke_dialog = function(spec) {
return that.select.val();
};
- that.create = function() {
+ that.create_content = function() {
var table = $('<table/>').appendTo(that.container);
@@ -286,7 +286,7 @@ IPA.cert.view_dialog = function(spec) {
}
});
- that.create = function() {
+ that.create_content = function() {
var table = $('<table/>').appendTo(that.container);
@@ -424,7 +424,7 @@ IPA.cert.request_dialog = function(spec) {
}
});
- that.create = function() {
+ that.create_content = function() {
that.container.append(that.message);
that.textarea = $('<textarea/>', {
diff --git a/install/ui/src/freeipa/dialog.js b/install/ui/src/freeipa/dialog.js
index a289e52f7..29f480c55 100644
--- a/install/ui/src/freeipa/dialog.js
+++ b/install/ui/src/freeipa/dialog.js
@@ -44,7 +44,6 @@ IPA.opened_dialogs = {
focus_top: function() {
var top = this.top_dialog();
if (top) {
- top.container.dialog('moveToTop'); //make sure the last dialog is top dialog
top.focus_first_element();
}
},
@@ -79,6 +78,10 @@ IPA.dialog_button = function(spec) {
that.click = spec.click || click;
/** @property {boolean} visible=true Button should be visible */
that.visible = spec.visible !== undefined ? spec.visible : true;
+ /** @property {boolean} enabled=true Button is enabled */
+ that.enabled = spec.enabled !== undefined ? spec.enabled : true;
+ /** @property {jQuery} element Button element */
+ that.element = null;
function click() {
}
@@ -88,10 +91,11 @@ IPA.dialog_button = function(spec) {
* @param {boolean} enabled
*/
that.set_enabled = function(enabled) {
- if (enabled) {
- that.element.removeClass('ui-state-disabled');
- } else {
- that.element.addClass('ui-state-disabled');
+
+ that.enabled = enabled;
+
+ if (that.element) {
+ that.element.prop('disabled', !enabled);
}
};
@@ -100,7 +104,7 @@ IPA.dialog_button = function(spec) {
* @return {boolean}
*/
that.is_enabled = function() {
- return !that.element.hasClass('ui-state-disabled');
+ return that.enabled;
};
return that;
@@ -208,16 +212,92 @@ IPA.dialog = function(spec) {
return null;
};
+ /**
+ * Create
+ * @protected
+ * @return {jQuery} dom_node
+ */
+ that.create_dialog = function() {
+
+ if (that.dom_node) {
+ that.dom_node.empty();
+ }
+
+ that.dom_node = $('<div/>', {
+ 'class': 'rcue-dialog-background'
+ });
+
+ var container_node = $('<div/>', {
+ 'class': 'rcue-dialog-container'
+ }).appendTo(that.dom_node);
+
+ that.dialog_node = $('<div/>', {
+ 'class': 'rcue-dialog',
+ id: that.get_id(),
+ 'data-name' : that.name,
+ role: 'dialog',
+ tabIndex: -1 // make the div focusable
+ }).appendTo(container_node);
+
+ that.header_node = $('<header/>');
+ that.create_header();
+ that.header_node.appendTo(that.dialog_node);
+
+ that.body_node = $('<div/>', {
+ 'class': 'rcue-dialog-body'
+ });
+ // for backwards compatibility
+ that.container = that.body_node;
+ that.create_content();
+ that.body_node.appendTo(that.dialog_node);
+
+ that.footer_node = $('<footer/>');
+ that.create_footer();
+ that.footer_node.appendTo(that.dialog_node);
+
+ that.policies.post_create();
+ return that.dom_node;
+ };
/**
- * Create content layout
+ * Create header
+ * @protected
+ * @return {jQuery} header_node
*/
- that.create = function() {
+ 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',
+ click: function() {
+ that.close();
+ }
+ }).appendTo(that.header_node);
+
+ return that.header_node;
+ };
+
+ /**
+ * Create content
+ *
+ * - custom dialogs should override this method
+ *
+ * @protected
+ * @deprecated
+ * @return {jQuery} footer_node
+ */
+ that.create_content = function() {
+
+ that.body_node.empty();
that.message_container = $('<div/>', {
style: 'display: none',
'class': 'dialog-message ui-state-highlight ui-corner-all'
- }).appendTo(that.container);
+ }).appendTo(that.body_node);
var widgets = that.widgets.get_widgets();
for (var i=0; i<widgets.length; i++) {
@@ -226,12 +306,59 @@ IPA.dialog = function(spec) {
var div = $('<div/>', {
name: widget.name,
'class': 'dialog-section'
- }).appendTo(that.container);
+ }).appendTo(that.body_node);
widget.create(div);
}
- that.policies.post_create();
+ return that.body_node;
+ };
+
+ /**
+ * Create footer
+ * @protected
+ * @return {jQuery} footer_node
+ */
+ that.create_footer = function() {
+
+ that.footer_node.empty();
+
+ that.buttons_node = $('<div/>', {
+ 'class': 'rcue-dialog-buttons'
+ }).appendTo(that.footer_node);
+
+ $("<div/>", { 'class': 'clear'}).appendTo(that.footer_node);
+
+ that.create_button_nodes();
+
+ return that.footer_node;
+ };
+
+ /**
+ * Create buttons HTML inside `buttons_node`
+ * @protected
+ * @return {jQuery} buttons_node
+ */
+ that.create_button_nodes = function() {
+
+ if (!that.buttons_node) return null;
+
+ that.buttons_node.empty();
+
+ for (var i=0; i<that.buttons.values.length; i++) {
+
+ var button = that.buttons.values[i];
+ if (!button.visible) continue;
+ var ui_button = IPA.button({
+ name: button.name,
+ label: button.label,
+ disabled: !button.enabled,
+ click: button.click
+ });
+ ui_button.appendTo(that.buttons_node);
+ button.element = ui_button;
+ }
+ return that.buttons_node;
};
/**
@@ -254,32 +381,12 @@ IPA.dialog = function(spec) {
*/
that.open = function(container) {
- that.container = $('<div/>', {
- id : that.get_id(),
- 'data-name': that.name
- });
-
- if (container) {
- container.append(that.container);
- }
-
- that.create();
+ that.create_dialog();
that.reset();
- that.container.dialog({
- title: that.title,
- modal: true,
- closeOnEscape: that.close_on_escape,
- width: that.width,
- minWidth: that.width,
- height: that.height,
- minHeight: that.height,
- close: function(event, ui) {
- that.close();
- }
- });
+ container = container || document.body;
+ that.dom_node.appendTo(container);
- that.set_buttons();
that.register_listeners();
IPA.opened_dialogs.add_dialog(that);
that.focus_first_element();
@@ -291,18 +398,15 @@ IPA.dialog = function(spec) {
*/
that.focus_first_element = function() {
- var element = that.container;
- var ui_dialog = that.container.parent('.ui-dialog'); // jq dialog div
-
- // code taken from jquery dialog source code
- $(element.find(':tabbable').get().concat(
- ui_dialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
- ui_dialog.get()))).eq(0).focus();
+ $(that.body_node.find(':tabbable').get().concat(
+ that.buttons_node.find(':tabbable').get().concat(
+ that.dom_node.get()))).eq(0).focus();
};
/**
* Set jQuery dialog option
* @protected
+ * @deprecated
* @param {string} name
* @param {Mixed} value
*/
@@ -311,31 +415,12 @@ IPA.dialog = function(spec) {
};
/**
- * Set dialog buttons as jQuery dialog buttons
+ * Update UI of buttons
* @protected
*/
that.set_buttons = function() {
- // create a map of button labels and handlers
- var dialog_buttons = {};
- for (var i=0; i<that.buttons.values.length; i++) {
- var button = that.buttons.values[i];
- if (!button.visible) continue;
- dialog_buttons[button.label] = button.click;
- }
-
- //set buttons to dialog
- that.option('buttons', dialog_buttons);
-
- // find button elements
- var parent = that.container.parent();
- var buttons = $('.ui-dialog-buttonpane .ui-dialog-buttonset button', parent);
-
- buttons.each(function(index, ui_button) {
- var button = that.buttons.values[index];
- $(ui_button).prop('name', button.name);
- button.element = $(this);
- });
+ that.create_button_nodes();
};
/**
@@ -368,9 +453,12 @@ IPA.dialog = function(spec) {
* Close dialog
*/
that.close = function() {
- that.container.dialog('destroy');
- that.container.remove();
+
that.remove_listeners();
+
+ that.dom_node.remove();
+ that.dom_node = null;
+
IPA.opened_dialogs.remove_dialog(that);
IPA.opened_dialogs.focus_top();
};
@@ -450,7 +538,7 @@ IPA.dialog = function(spec) {
that.init();
- that.dialog_create = that.create;
+ that.dialog_create_content = that.create_content;
that.dialog_open = that.open;
that.dialog_close = that.close;
that.dialog_save = that.save;
@@ -581,9 +669,9 @@ IPA.adder_dialog = function(spec) {
/**
* @inheritDoc
*/
- that.create = function() {
+ that.create_content = function() {
- // do not call that.dialog_create();
+ // do not call that.dialog_create_content();
var container = $('<div/>', {
'class': 'adder-dialog'
@@ -826,7 +914,7 @@ IPA.adder_dialog = function(spec) {
init();
- that.adder_dialog_create = that.create;
+ that.adder_dialog_create_content = that.create_content;
return that;
};
@@ -878,7 +966,7 @@ IPA.deleter_dialog = function (spec) {
};
/** @inheritDoc */
- that.create = function() {
+ that.create_content = function() {
$('<p/>', {
'text': that.message
@@ -914,7 +1002,7 @@ IPA.deleter_dialog = function (spec) {
}
};
- that.deleter_dialog_create = that.create;
+ that.deleter_dialog_create_content = that.create_content;
return that;
};
@@ -943,7 +1031,7 @@ IPA.message_dialog = function(spec) {
that.buttons.remove('cancel');
- that.message_dialog_create = that.create;
+ that.message_dialog_create_content = that.create_content;
return that;
};
@@ -999,7 +1087,7 @@ IPA.confirm_dialog = function(spec) {
that.confirm_on_enter = spec.confirm_on_enter !== undefined ? spec.confirm_on_enter : true;
/** @inheritDoc */
- that.create = function() {
+ that.create_content = function() {
$('<p/>', {
'text': that.message
}).appendTo(that.container);
@@ -1117,7 +1205,7 @@ IPA.confirm_mixin = function() {
register_listeners: function() {
var self = this;
this._on_key_up_listener = function(e) { self.on_key_up(e); };
- var dialog_container = this.container.parent('.ui-dialog');
+ var dialog_container = this.dom_node;
dialog_container.bind('keyup', this._on_key_up_listener);
},
@@ -1125,7 +1213,7 @@ IPA.confirm_mixin = function() {
* Removal of registered event handlers
*/
remove_listeners: function() {
- var dialog_container = this.container.parent('.ui-dialog');
+ var dialog_container = this.dom_node;
dialog_container.unbind('keyup', this._on_key_up_listener);
},
diff --git a/install/ui/src/freeipa/dns.js b/install/ui/src/freeipa/dns.js
index 347461584..1d740aaa4 100644
--- a/install/ui/src/freeipa/dns.js
+++ b/install/ui/src/freeipa/dns.js
@@ -633,8 +633,8 @@ IPA.dnszone_adder_dialog = function(spec) {
}
};
- that.create = function() {
- that.entity_adder_dialog_create();
+ that.create_content = function() {
+ that.entity_adder_dialog_create_content();
that.container.addClass('dnszone-adder-dialog');
};
@@ -1305,7 +1305,7 @@ IPA.dnsrecord_redirection_dialog = function(spec) {
var that = IPA.message_dialog(spec);
- that.create = function() {
+ that.create_content = function() {
$('<p/>', {
'text': text.get('@i18n:objects.dnsrecord.deleted_no_data')
}).appendTo(that.container);
@@ -2231,7 +2231,7 @@ IPA.dns.ptr_redirection_dialog = function(spec) {
that.address = spec.address;
- that.create = function() {
+ that.create_content = function() {
that.status_div = $('<div />', {
'class': 'redirection-status'
diff --git a/install/ui/src/freeipa/hbactest.js b/install/ui/src/freeipa/hbactest.js
index c5189f9b3..386013066 100644
--- a/install/ui/src/freeipa/hbactest.js
+++ b/install/ui/src/freeipa/hbactest.js
@@ -773,10 +773,10 @@ IPA.hbac.validation_dialog = function(spec) {
that.validation_results = spec.validation_results;
- that.create = function() {
+ that.create_content = function() {
if (that.message) {
- that.message_dialog_create();
+ that.message_dialog_create_content();
}
if (that.validation_results && that.validation_results.invalid_facets) {
diff --git a/install/ui/src/freeipa/host.js b/install/ui/src/freeipa/host.js
index ef9687faf..1c7528bac 100644
--- a/install/ui/src/freeipa/host.js
+++ b/install/ui/src/freeipa/host.js
@@ -464,8 +464,8 @@ IPA.host_adder_dialog = function(spec) {
var that = IPA.entity_adder_dialog(spec);
- that.create = function() {
- that.entity_adder_dialog_create();
+ that.create_content = function() {
+ that.entity_adder_dialog_create_content();
that.container.addClass('host-adder-dialog');
};
@@ -480,9 +480,9 @@ IPA.host_deleter_dialog = function(spec) {
var that = IPA.search_deleter_dialog(spec);
- that.create = function() {
+ that.create_content = function() {
- that.deleter_dialog_create();
+ that.deleter_dialog_create_content();
var metadata = IPA.get_command_option('host_del', 'updatedns');
@@ -647,7 +647,7 @@ IPA.host_unprovision_dialog = function(spec) {
that.title = that.title.replace('${entity}', that.entity.metadata.label_singular);
- that.create = function() {
+ that.create_content = function() {
that.container.append(text.get('@i18n:objects.host.unprovision_confirmation'));
};
diff --git a/install/ui/src/freeipa/ipa.js b/install/ui/src/freeipa/ipa.js
index fc04c56e6..b708ed004 100644
--- a/install/ui/src/freeipa/ipa.js
+++ b/install/ui/src/freeipa/ipa.js
@@ -1576,7 +1576,7 @@ IPA.dirty_dialog = function(spec) {
that.message = text.get(spec.message || '@i18n:dialogs.dirty_message');
/** @inheritDoc */
- that.create = function() {
+ that.create_content = function() {
that.container.append(that.message);
};
@@ -1680,7 +1680,7 @@ IPA.error_dialog = function(spec) {
};
/** @inheritDoc */
- that.create = function() {
+ that.create_content = function() {
if (that.error_thrown.url) {
$('<p/>', {
text: text.get('@i18n:errors.url', 'URL')+': '+that.error_thrown.url
@@ -2013,7 +2013,7 @@ IPA.unauthorized_dialog = function(spec) {
that.denied = "Sorry you are not allowed to access this service.";
/** @inheritDoc */
- that.create = function() {
+ that.create_content = function() {
that.session_expired_form();
that.create_reset_form();
diff --git a/install/ui/src/freeipa/service.js b/install/ui/src/freeipa/service.js
index 4d135ea23..cc26e3b56 100644
--- a/install/ui/src/freeipa/service.js
+++ b/install/ui/src/freeipa/service.js
@@ -385,7 +385,7 @@ IPA.service.unprovision_dialog = function(spec) {
var entity_singular = that.entity.metadata.label_singular;
that.title = that.title.replace('${entity}', entity_singular);
- that.create = function() {
+ that.create_content = function() {
that.container.append(text.get('@i18n:objects.service.unprovision_confirmation'));
};
diff --git a/install/ui/src/freeipa/widget.js b/install/ui/src/freeipa/widget.js
index a90c7cc74..dc1d0f27b 100644
--- a/install/ui/src/freeipa/widget.js
+++ b/install/ui/src/freeipa/widget.js
@@ -4687,7 +4687,7 @@ IPA.sshkey_widget = function(spec) {
}
});
- dialog.create = function() {
+ dialog.create_content = function() {
dialog.container.append(dialog.message);
diff --git a/ipatests/test_webui/ui_driver.py b/ipatests/test_webui/ui_driver.py
index b4f02ab0f..8ffb1e9b3 100644
--- a/ipatests/test_webui/ui_driver.py
+++ b/ipatests/test_webui/ui_driver.py
@@ -504,10 +504,10 @@ class UI_driver(object):
info = None
if dialog:
- content = self.find('div.ui-dialog-content', By.CSS_SELECTOR, dialog, strict=True)
+ body = self.find('.rcue-dialog-body', By.CSS_SELECTOR, dialog, strict=True)
info = {
- 'name': content.get_attribute('data-name'),
- 'text': content.text,
+ 'name': dialog.get_attribute('data-name'),
+ 'text': body.text,
}
return info
@@ -563,7 +563,7 @@ class UI_driver(object):
if not dialog:
dialog = self.get_dialog(strict=True)
- s = "div.ui-dialog-buttonset button[name=%s]" % name
+ s = ".rcue-dialog-buttons button[name=%s]" % name
self._button_click(s, dialog, name)
def action_button_click(self, name, parent):