summaryrefslogtreecommitdiffstats
path: root/install/ui/src/freeipa/dialog.js
diff options
context:
space:
mode:
authorPetr Vobornik <pvoborni@redhat.com>2013-09-06 15:27:06 +0200
committerPetr Vobornik <pvoborni@redhat.com>2013-10-16 18:08:17 +0200
commitefafd7fe871bc368b91db78bb132abb027141a24 (patch)
treef6d71bae937e31c7090828382af8b404b1ce7e1f /install/ui/src/freeipa/dialog.js
parent3fa304d95ec59efe0eb1cb8241d88a173802b172 (diff)
downloadfreeipa.git-efafd7fe871bc368b91db78bb132abb027141a24.tar.gz
freeipa.git-efafd7fe871bc368b91db78bb132abb027141a24.tar.xz
freeipa.git-efafd7fe871bc368b91db78bb132abb027141a24.zip
Web UI source code annotation
Part of ongoing Web UI documentation effort. Source code is annotated in a way that it can be processed by documentation generator.
Diffstat (limited to 'install/ui/src/freeipa/dialog.js')
-rw-r--r--install/ui/src/freeipa/dialog.js306
1 files changed, 303 insertions, 3 deletions
diff --git a/install/ui/src/freeipa/dialog.js b/install/ui/src/freeipa/dialog.js
index d1428fec..a31c9f45 100644
--- a/install/ui/src/freeipa/dialog.js
+++ b/install/ui/src/freeipa/dialog.js
@@ -22,16 +22,25 @@
define(['./ipa', './jquery', './text', './field', './widget'], function(IPA, $, text) {
+/**
+ * Opened dialogs
+ *
+ * @class
+ * @singleton
+ */
IPA.opened_dialogs = {
+ /** Opened dialogs */
dialogs: [],
+ /** Get top dialog */
top_dialog: function() {
var top = null;
if (this.dialogs.length) top = this.dialogs[this.dialogs.length - 1];
return top;
},
+ /** Focus to dialog */
focus_top: function() {
var top = this.top_dialog();
if (top) {
@@ -40,30 +49,44 @@ IPA.opened_dialogs = {
}
},
+ /** Add dialog */
add_dialog: function(dialog) {
this.dialogs.push(dialog);
},
+ /** Remove dialog */
remove_dialog: function(dialog) {
var index = this.dialogs.indexOf(dialog);
if (index > -1) this.dialogs.splice(index, 1);
}
};
+/**
+ * Dialog button
+ * @class
+ */
IPA.dialog_button = function(spec) {
spec = spec || {};
var that = IPA.object();
+ /** @property {string} name Name */
that.name = spec.name;
+ /** @property {string} label Label */
that.label = text.get(spec.label || spec.name);
+ /** @property {Function} click Click handler */
that.click = spec.click || click;
+ /** @property {boolean} visible=true Button should be visible */
that.visible = spec.visible !== undefined ? spec.visible : true;
function click() {
}
+ /**
+ * Enabled setter
+ * @param {boolean} enabled
+ */
that.set_enabled = function(enabled) {
if (enabled) {
that.element.removeClass('ui-state-disabled');
@@ -72,6 +95,10 @@ IPA.dialog_button = function(spec) {
}
};
+ /**
+ * Enabled getter
+ * @return {boolean}
+ */
that.is_enabled = function() {
return !that.element.hasClass('ui-state-disabled');
};
@@ -81,6 +108,7 @@ IPA.dialog_button = function(spec) {
/**
* This is a base class for dialog boxes.
+ * @class
*/
IPA.dialog = function(spec) {
@@ -88,28 +116,48 @@ IPA.dialog = function(spec) {
var that = IPA.object();
+ /** @property {entity.entity} entity Entity */
that.entity = IPA.get_entity(spec.entity);
+ /** @property {string} name="dialog" Name */
that.name = spec.name || 'dialog';
+ /** @property {string} id ID */
that.id = spec.id;
+ /** @property {string} title Dialog title */
that.title = text.get(spec.title);
+ /** @property {number} width=500 Dialog width */
that.width = spec.width || 500;
+ /** @property {number} height Dialog height */
that.height = spec.height;
+
+ /**
+ * Close dialog on Escape key press
+ * @property {boolean} close_on_escape=true
+ */
that.close_on_escape = spec.close_on_escape !== undefined ?
spec.close_on_escape : true;
// FIXME: remove facet reference
// Purpose of facet reference is to obtain pkeys or ability to reload
// facet. Such usage makes the code more spaghetti. It should be replaced.
+ /**
+ * Facet
+ * @property {facet.facet}
+ */
that.facet = spec.facet;
+ /** @property {IPA.widget_container} widgets Widgets */
that.widgets = IPA.widget_container();
+ /** @property {IPA.field_container} fields Fields */
that.fields = IPA.field_container({ container: that });
+ /** @property {ordered_map} buttons Buttons */
that.buttons = $.ordered_map();
+ /** @property {details.facet_policies} policies Policies */
that.policies = IPA.facet_policies({
container: that,
policies: spec.policies
});
+ /** Create and add button */
that.create_button = function(spec) {
var factory = spec.$factory || IPA.dialog_button;
var button = factory(spec);
@@ -117,19 +165,32 @@ IPA.dialog = function(spec) {
return button;
};
+ /**
+ * Add button
+ * @param {IPA.dialog_button} button
+ */
that.add_button = function(button) {
that.buttons.put(button.name, button);
};
+ /**
+ * Get button
+ * @param {string} name
+ */
that.get_button = function(name) {
return that.buttons.get(name);
};
+ /**
+ * Add field
+ * @param {IPA.field} field
+ */
that.field = function(field) {
that.fields.add_field(field);
return that;
};
+ /** Validate dialog fields */
that.validate = function() {
var valid = true;
var fields = that.fields.get_fields();
@@ -140,6 +201,7 @@ IPA.dialog = function(spec) {
return valid;
};
+ /** Get ID */
that.get_id = function() {
if (that.id) return that.id;
if (that.name) return that.name;
@@ -172,17 +234,23 @@ IPA.dialog = function(spec) {
that.policies.post_create();
};
+ /**
+ * Show message in dialog's message container
+ * @param {string} message
+ */
that.show_message = function(message) {
that.message_container.text(message);
that.message_container.css('display', '');
};
+ /** Hide dialog message */
that.hide_message = function() {
that.message_container.css('display', 'none');
};
/**
* Open dialog
+ * @param {jQuery} container
*/
that.open = function(container) {
@@ -217,9 +285,11 @@ IPA.dialog = function(spec) {
that.focus_first_element();
};
+ /**
+ * Set focus to the first tabbable element in the content area or the first button.
+ * If there are no tabbable elements, set focus on the dialog itself.
+ */
that.focus_first_element = function() {
- // set focus to the first tabbable element in the content area or the first button
- // if there are no tabbable elements, set focus on the dialog itself
var element = that.container;
var ui_dialog = that.container.parent('.ui-dialog'); // jq dialog div
@@ -230,10 +300,20 @@ IPA.dialog = function(spec) {
ui_dialog.get()))).eq(0).focus();
};
+ /**
+ * Set jQuery dialog option
+ * @protected
+ * @param {string} name
+ * @param {Mixed} value
+ */
that.option = function(name, value) {
that.container.dialog('option', name, value);
};
+ /**
+ * Set dialog buttons as jQuery dialog buttons
+ * @protected
+ */
that.set_buttons = function() {
// create a map of button labels and handlers
@@ -258,6 +338,10 @@ IPA.dialog = function(spec) {
});
};
+ /**
+ * Make buttons visible
+ * @param {string[]} names button names
+ */
that.display_buttons = function(names) {
for (var i=0; i<that.buttons.values.length; i++) {
@@ -268,6 +352,10 @@ IPA.dialog = function(spec) {
that.set_buttons();
};
+ /**
+ * Save fields' values into record object
+ * @param {Object} record
+ */
that.save = function(record) {
var fields = that.fields.get_fields();
for (var i=0; i<fields.length; i++) {
@@ -276,6 +364,9 @@ IPA.dialog = function(spec) {
}
};
+ /**
+ * Close dialog
+ */
that.close = function() {
that.container.dialog('destroy');
that.container.remove();
@@ -284,6 +375,9 @@ IPA.dialog = function(spec) {
IPA.opened_dialogs.focus_top();
};
+ /**
+ * Reset dialog's fields
+ */
that.reset = function() {
var fields = that.fields.get_fields();
for (var i=0; i<fields.length; i++) {
@@ -291,9 +385,27 @@ IPA.dialog = function(spec) {
}
};
+ /**
+ * Called when dialog is opened.
+ *
+ * - override point
+ * @protected
+ */
that.register_listeners = function() {};
+
+ /**
+ * Called when dialog is closed.
+ *
+ * - override point
+ * @protected
+ */
that.remove_listeners = function() {};
+ /**
+ * Create builder(s) which should build dialog's content (fields,
+ * widgets...)
+ * @protected
+ */
that.create_builder = function() {
var widget_builder = IPA.widget_builder({
@@ -324,6 +436,10 @@ IPA.dialog = function(spec) {
});
};
+ /**
+ * Initializes dialog object
+ * @protected
+ */
that.init = function() {
that.create_builder();
@@ -345,8 +461,18 @@ IPA.dialog = function(spec) {
};
/**
+ * Adder dialog
* This dialog provides an interface for searching and selecting
* values from the available results.
+ *
+ * It has two tables:
+ *
+ * - available, contains values to choose from
+ * - selected, contains chosen values
+ *
+ * @class
+ * @extends IPA.dialog
+ * @mixins IPA.confirm_mixin
*/
IPA.adder_dialog = function(spec) {
@@ -358,8 +484,17 @@ IPA.adder_dialog = function(spec) {
IPA.confirm_mixin().apply(that);
+ /**
+ * External value can be added.
+ *
+ * In general external member doesn't represent any entity.
+ * @property {boolean} external=undefined
+ */
that.external = spec.external;
+
+ /** @property {number} width=600 Width */
that.width = spec.width || 600;
+ /** @property {number} height=300 Height */
that.height = spec.height || 360;
if (!that.entity) {
@@ -390,19 +525,32 @@ IPA.adder_dialog = function(spec) {
}
};
+ /**
+ * Get column
+ * @param {string} name
+ */
that.get_column = function(name) {
return that.available_table.get_column(name);
};
+ /** Get all columns */
that.get_columns = function() {
return that.available_table.get_columns();
};
+ /**
+ * Add column to both tables.
+ * @param {IPA.column} column
+ */
that.add_column = function(column) {
that.available_table.add_column(column);
that.selected_table.add_column(column);
};
+ /**
+ * Replace columns in both tables
+ * @param {IPA.column[]} columns New columns
+ */
that.set_columns = function(columns) {
that.clear_columns();
for (var i=0; i<columns.length; i++) {
@@ -410,11 +558,19 @@ IPA.adder_dialog = function(spec) {
}
};
+ /**
+ * Clear all columns in both tables.
+ */
that.clear_columns = function() {
that.available_table.clear_columns();
that.selected_table.clear_columns();
};
+ /**
+ * Create column from spec
+ * @param {Object} spec
+ * @return {IPA.column}
+ */
that.create_column = function(spec) {
spec.entity = that.entity;
var column = IPA.column(spec);
@@ -422,6 +578,9 @@ IPA.adder_dialog = function(spec) {
return column;
};
+ /**
+ * @inheritDoc
+ */
that.create = function() {
// do not call that.dialog_create();
@@ -555,6 +714,7 @@ IPA.adder_dialog = function(spec) {
that.search();
};
+ /** @inheritDoc */
that.open = function(container) {
var add_button = that.create_button({
@@ -579,16 +739,26 @@ IPA.adder_dialog = function(spec) {
that.update_buttons();
};
+ /**
+ * Move selected values in 'available' table to 'selected' table
+ */
that.add = function() {
var rows = that.available_table.remove_selected_rows();
that.selected_table.add_rows(rows);
};
+ /**
+ * Move selected values in 'selected' table to 'available' table
+ */
that.remove = function() {
var rows = that.selected_table.remove_selected_rows();
that.available_table.add_rows(rows);
};
+ /**
+ * Update button state based on selection
+ * @protected
+ */
that.update_buttons = function() {
var values = that.selected_table.save();
@@ -597,29 +767,55 @@ IPA.adder_dialog = function(spec) {
button.set_enabled(values && values.length);
};
+ /**
+ * Get value of 'available' filter
+ * @return {string}
+ */
that.get_filter = function() {
return that.filter_field.val();
};
+ /**
+ * Clear rows in available table
+ */
that.clear_available_values = function() {
that.available_table.empty();
};
+ /**
+ * Clear rows in selected table
+ */
that.clear_selected_values = function() {
that.selected_table.empty();
};
+ /**
+ * Add record to available table
+ * @param {Object} record
+ */
that.add_available_value = function(record) {
that.available_table.add_record(record);
};
+ /**
+ * Get values in 'selected' table
+ */
that.get_selected_values = function() {
return that.selected_table.save();
};
+ /**
+ * Operation which has to be executed after selection confirmation
+ *
+ * - override point
+ */
that.execute = function() {
};
+ /**
+ * Confirm handler
+ * @protected
+ */
that.on_confirm = function() {
var add_button = that.get_button('add');
@@ -636,7 +832,12 @@ IPA.adder_dialog = function(spec) {
};
/**
- * This dialog displays the values to be deleted.
+ * Deletion confirmation dialog
+ *
+ * - displays the values to be deleted.
+ * @class
+ * @extends IPA.dialog
+ * @mixins IPA.confirm_mixin
*/
IPA.deleter_dialog = function (spec) {
@@ -648,19 +849,35 @@ IPA.deleter_dialog = function (spec) {
spec.ok_label = spec.ok_label || '@i18n:buttons.remove';
var that = IPA.confirm_dialog(spec);
+
+ /**
+ * Values to be deleted
+ * @property {string[]} values
+ */
that.values = spec.values || [];
+
+ /** Positive confirmation handler */
that.on_ok = spec.on_ok || function() {
that.execute();
};
+ /**
+ * Add value
+ * @param {string} value
+ */
that.add_value = function(value) {
that.values.push(value);
};
+ /**
+ * Replace values
+ * @param {string[]} values
+ */
that.set_values = function(values) {
that.values = values;
};
+ /** @inheritDoc */
that.create = function() {
$('<p/>', {
@@ -702,6 +919,13 @@ IPA.deleter_dialog = function (spec) {
return that;
};
+/**
+ * Message dialog
+ *
+ * Displays a message.
+ * @class
+ * @extends IPA.confirm_dialog
+ */
IPA.message_dialog = function(spec) {
spec = spec || {};
@@ -710,6 +934,7 @@ IPA.message_dialog = function(spec) {
var that = IPA.confirm_dialog(spec);
+ /** @inheritDoc */
that.open = function(container) {
that.confirm_dialog_open(container);
@@ -723,6 +948,19 @@ IPA.message_dialog = function(spec) {
return that;
};
+/**
+ * Confirmation dialog
+ *
+ * Presents user a proposal(message). User then decides whether he would accept or
+ * decline the proposal.
+ *
+ * Acceptation is done by clicking on 'OK' button or hitting 'ENTER' key,
+ * refusal by clicking on 'Cancel' button or hitting 'ESCAPE' key.
+ *
+ * @class
+ * @extends IPA.dialog
+ * @mixins IPA.confirm_mixin
+ */
IPA.confirm_dialog = function(spec) {
spec = spec || {};
@@ -732,20 +970,42 @@ IPA.confirm_dialog = function(spec) {
var that = IPA.dialog(spec);
IPA.confirm_mixin().apply(that);
+ /** @property {string} message Confirmation message */
that.message = text.get(spec.message);
+
+ /** @property {Function} on_ok OK handler */
that.on_ok = spec.on_ok;
+
+ /** @property {Function} on_cancel Cancel handler */
that.on_cancel = spec.on_cancel;
+
+ /** @property {Function} ok_label OK button label */
that.ok_label = text.get(spec.ok_label || '@i18n:buttons.ok');
+
+ /** @property {Function} cancel_label Cancel button label */
that.cancel_label = text.get(spec.cancel_label || '@i18n:buttons.cancel');
+
+ /**
+ * Dialog is confirmed
+ * @protected
+ * @property {boolean}
+ */
that.confirmed = false;
+
+ /**
+ * Dialog can be confirmed by hitting 'ENTER' key
+ * @property {boolean} confirm_on_enter=true
+ */
that.confirm_on_enter = spec.confirm_on_enter !== undefined ? spec.confirm_on_enter : true;
+ /** @inheritDoc */
that.create = function() {
$('<p/>', {
'text': that.message
}).appendTo(that.container);
};
+ /** @inheritDoc */
that.close = function() {
that.dialog_close();
@@ -761,17 +1021,22 @@ IPA.confirm_dialog = function(spec) {
}
};
+ /** @inheritDoc */
that.open = function(container) {
that.confirmed = false;
that.dialog_open(container);
};
+ /**
+ * Confirm handler
+ */
that.on_confirm = function() {
that.confirmed = true;
that.close();
};
+ /** Create buttons */
that.create_buttons = function() {
that.create_button({
@@ -801,16 +1066,40 @@ IPA.confirm_dialog = function(spec) {
return that;
};
+/**
+ * Confirm mixin
+ *
+ * Can extend a dialog by confirmation by keyboard functionality. When applied
+ * dialog can be:
+ *
+ * - confirmed by 'ENTER' key
+ * - declined by 'ESCAPE' key
+ *
+ * To apply:
+ *
+ * IPA.confirm_mixin().apply(dialog);
+ *
+ * @class
+ */
IPA.confirm_mixin = function() {
return {
mixin: {
+ /**
+ * Elements (tag names) or node types which should be ignored as
+ * confirmation event sources.
+ */
ignore_enter_rules: {
src_elements: ['a', 'button'],
src_types: ['textarea', 'select-one']
},
+ /**
+ * Test if event is confirmation event
+ * @param {Event} event
+ * @return {boolean}
+ */
test_ignore: function(event) {
var ir = this.ignore_enter_rules,
@@ -822,6 +1111,9 @@ IPA.confirm_mixin = function() {
return ignore;
},
+ /**
+ * Registration of keyboard event handlers
+ */
register_listeners: function() {
var self = this;
this._on_key_up_listener = function(e) { self.on_key_up(e); };
@@ -829,11 +1121,19 @@ IPA.confirm_mixin = function() {
dialog_container.bind('keyup', this._on_key_up_listener);
},
+ /**
+ * Removal of registered event handlers
+ */
remove_listeners: function() {
var dialog_container = this.container.parent('.ui-dialog');
dialog_container.unbind('keyup', this._on_key_up_listener);
},
+ /**
+ * Test if confirmation happened
+ * If so call dialog's `on_confirm` or `on_cancel` method.
+ * @param {Event} event
+ */
on_key_up: function(event) {
if (event.keyCode === $.ui.keyCode.ENTER &&
!this.test_ignore(event) &&