/*jsl:import ipa.js */ /* Authors: * Endi Sukma Dewata * Petr Vobornik * * Copyright (C) 2010 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 . */ define(['./ipa', './jquery', './text', './field', './widget'], function(IPA, $, text) { IPA.opened_dialogs = { dialogs: [], top_dialog: function() { var top = null; if (this.dialogs.length) top = this.dialogs[this.dialogs.length - 1]; return top; }, 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(); } }, add_dialog: function(dialog) { this.dialogs.push(dialog); }, remove_dialog: function(dialog) { var index = this.dialogs.indexOf(dialog); if (index > -1) this.dialogs.splice(index, 1); } }; IPA.dialog_button = function(spec) { spec = spec || {}; var that = IPA.object(); that.name = spec.name; that.label = text.get(spec.label || spec.name); that.click = spec.click || click; that.visible = spec.visible !== undefined ? spec.visible : true; function click() { } that.set_enabled = function(enabled) { if (enabled) { that.element.removeClass('ui-state-disabled'); } else { that.element.addClass('ui-state-disabled'); } }; that.is_enabled = function() { return !that.element.hasClass('ui-state-disabled'); }; return that; }; /** * This is a base class for dialog boxes. */ IPA.dialog = function(spec) { spec = spec || {}; var that = IPA.object(); that.entity = IPA.get_entity(spec.entity); that.name = spec.name || 'dialog'; that.id = spec.id; that.title = text.get(spec.title); that.width = spec.width || 500; that.height = spec.height; 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. that.facet = spec.facet; that.widgets = IPA.widget_container(); that.fields = IPA.field_container({ container: that }); that.buttons = $.ordered_map(); that.policies = IPA.facet_policies({ container: that, policies: spec.policies }); that.create_button = function(spec) { var factory = spec.$factory || IPA.dialog_button; var button = factory(spec); that.add_button(button); return button; }; that.add_button = function(button) { that.buttons.put(button.name, button); }; that.get_button = function(name) { return that.buttons.get(name); }; that.field = function(field) { that.fields.add_field(field); return that; }; that.validate = function() { var valid = true; var fields = that.fields.get_fields(); for (var i=0; i', { style: 'display: none', 'class': 'dialog-message ui-state-highlight ui-corner-all' }).appendTo(that.container); var widgets = that.widgets.get_widgets(); for (var i=0; i', { name: widget.name, 'class': 'dialog-section' }).appendTo(that.container); widget.create(div); } that.policies.post_create(); }; that.show_message = function(message) { that.message_container.text(message); that.message_container.css('display', ''); }; that.hide_message = function() { that.message_container.css('display', 'none'); }; /** * Open dialog */ that.open = function(container) { that.container = $('
', { id : that.get_id(), 'data-name': that.name }); if (container) { container.append(that.container); } that.create(); 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(); } }); that.set_buttons(); that.register_listeners(); IPA.opened_dialogs.add_dialog(that); that.focus_first_element(); }; 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 // 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.option = function(name, value) { that.container.dialog('option', name, value); }; that.set_buttons = function() { // create a map of button labels and handlers var dialog_buttons = {}; for (var i=0; i -1; } that.set_buttons(); }; that.save = function(record) { var fields = that.fields.get_fields(); for (var i=0; i', { 'class': 'adder-dialog' }).appendTo(that.container); var top_panel = $('
', { 'class': 'adder-dialog-top' }).appendTo(container); $('', { type: 'text', name: 'filter', keyup: function(event) { if (event.keyCode === $.ui.keyCode.ENTER) { that.search(); return false; } } }).appendTo(top_panel); top_panel.append(' '); that.find_button = IPA.button({ name: 'find', label: '@i18n:buttons.find', click: function() { that.search(); return false; } }).appendTo(top_panel); top_panel.append(IPA.create_network_spinner()); var left_panel = $('
', { 'class': 'adder-dialog-left' }).appendTo(container); var available_panel = $('
', { name: 'available', 'class': 'adder-dialog-available' }).appendTo(left_panel); $('
', { html: text.get('@i18n:dialogs.available'), 'class': 'adder-dialog-header ui-widget-header' }).appendTo(available_panel); var available_content = $('
', { 'class': 'adder-dialog-content' }).appendTo(available_panel); that.available_table.create(available_content); var right_panel = $('
', { 'class': 'adder-dialog-right' }).appendTo(container); var selected_panel = $('
', { name: 'selected', 'class': 'adder-dialog-selected' }).appendTo(right_panel); $('
', { html: text.get('@i18n:dialogs.prospective'), 'class': 'adder-dialog-header ui-widget-header' }).appendTo(selected_panel); var selected_content = $('
', { 'class': 'adder-dialog-content' }).appendTo(selected_panel); that.selected_table.create(selected_content); var buttons_panel = $('
', { name: 'buttons', 'class': 'adder-dialog-buttons' }).appendTo(container); var div = $('
').appendTo(buttons_panel); IPA.button({ name: 'add', label: '>>', click: function() { that.add(); that.update_buttons(); return false; } }).appendTo(div); div = $('
').appendTo(buttons_panel); IPA.button({ name: 'remove', label: '<<', click: function() { that.remove(); that.update_buttons(); return false; } }).appendTo(div); that.filter_field = $('input[name=filter]', that.container); if (that.external) { container.addClass('adder-dialog-with-external'); var external_panel = $('
', { name: 'external', 'class': 'adder-dialog-external' }).appendTo(left_panel); $('
', { html: text.get('@i18n:objects.sudorule.external'), 'class': 'adder-dialog-header ui-widget-header' }).appendTo(external_panel); var external_content = $('
', { 'class': 'adder-dialog-content' }).appendTo(external_panel); that.external_field = $('', { type: 'text', name: 'external' }).appendTo(external_content); } that.search(); }; that.open = function(container) { var add_button = that.create_button({ name: 'add', label: '@i18n:buttons.add', click: function() { if (!add_button.is_enabled()) return; that.execute(); } }); that.create_button({ name: 'cancel', label: '@i18n:buttons.cancel', click: function() { that.close(); } }); that.dialog_open(container); that.update_buttons(); }; that.add = function() { var rows = that.available_table.remove_selected_rows(); that.selected_table.add_rows(rows); }; that.remove = function() { var rows = that.selected_table.remove_selected_rows(); that.available_table.add_rows(rows); }; that.update_buttons = function() { var values = that.selected_table.save(); var button = that.get_button('add'); button.set_enabled(values && values.length); }; that.get_filter = function() { return that.filter_field.val(); }; that.clear_available_values = function() { that.available_table.empty(); }; that.clear_selected_values = function() { that.selected_table.empty(); }; that.add_available_value = function(record) { that.available_table.add_record(record); }; that.get_selected_values = function() { return that.selected_table.save(); }; that.execute = function() { }; that.on_confirm = function() { var add_button = that.get_button('add'); if (add_button.is_enabled()) { that.execute(); } }; init(); that.adder_dialog_create = that.create; return that; }; /** * This dialog displays the values to be deleted. */ IPA.deleter_dialog = function (spec) { spec = spec || {}; spec.title = spec.title || '@i18n:buttons.remove'; spec.name = spec.name || 'deleter_dialog'; spec.message = spec.message || '@i18n:search.delete_confirm'; spec.ok_label = spec.ok_label || '@i18n:buttons.remove'; var that = IPA.confirm_dialog(spec); that.values = spec.values || []; that.on_ok = spec.on_ok || function() { that.execute(); }; that.add_value = function(value) { that.values.push(value); }; that.set_values = function(values) { that.values = values; }; that.create = function() { $('

', { 'text': that.message }).appendTo(that.container); var div = $('

', { style: 'overflow:auto; max-height: 100px' }).appendTo(that.container); var ul = $('
    '); ul.appendTo(div); for (var i=0; i',{ 'text': value }).appendTo(ul); } }; that.deleter_dialog_create = that.create; return that; }; IPA.message_dialog = function(spec) { spec = spec || {}; spec.name = spec.name || 'message_dialog'; var that = IPA.confirm_dialog(spec); that.open = function(container) { that.confirm_dialog_open(container); that.confirmed = true; // there are no options to confirm }; that.buttons.remove('cancel'); that.message_dialog_create = that.create; return that; }; IPA.confirm_dialog = function(spec) { spec = spec || {}; spec.name = spec.name || 'confirm_dialog'; spec.title = spec.title || '@i18n:dialogs.confirmation'; var that = IPA.dialog(spec); IPA.confirm_mixin().apply(that); that.message = text.get(spec.message); that.on_ok = spec.on_ok; that.on_cancel = spec.on_cancel; that.ok_label = text.get(spec.ok_label || '@i18n:buttons.ok'); that.cancel_label = text.get(spec.cancel_label || '@i18n:buttons.cancel'); that.confirmed = false; that.confirm_on_enter = spec.confirm_on_enter !== undefined ? spec.confirm_on_enter : true; that.create = function() { $('

    ', { 'text': that.message }).appendTo(that.container); }; that.close = function() { that.dialog_close(); if (that.confirmed) { if (that.on_ok) { that.on_ok(); } } else { if (that.on_cancel) { that.on_cancel(); } } }; that.open = function(container) { that.confirmed = false; that.dialog_open(container); }; that.on_confirm = function() { that.confirmed = true; that.close(); }; that.create_buttons = function() { that.create_button({ name: 'ok', label: that.ok_label, click: function() { that.confirmed = true; that.close(); } }); that.create_button({ name: 'cancel', label: that.cancel_label, click: function() { that.confirmed = false; that.close(); } }); }; that.create_buttons(); that.confirm_dialog_close = that.close; that.confirm_dialog_open = that.open; return that; }; IPA.confirm_mixin = function() { return { mixin: { ignore_enter_rules: { src_elements: ['a', 'button'], src_types: ['textarea', 'select-one'] }, test_ignore: function(event) { var ir = this.ignore_enter_rules, t = event.target, ignore = ir.src_elements.indexOf(t.tagName.toLowerCase()) > -1 || ir.src_types.indexOf(t.type) > -1; return ignore; }, 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'); dialog_container.bind('keyup', this._on_key_up_listener); }, remove_listeners: function() { var dialog_container = this.container.parent('.ui-dialog'); dialog_container.unbind('keyup', this._on_key_up_listener); }, on_key_up: function(event) { if (event.keyCode === $.ui.keyCode.ENTER && !this.test_ignore(event) && !!this.on_confirm) { event.preventDefault(); this.on_confirm(); } else if (event.keyCode === $.ui.keyCode.ESCAPE && !!this.on_cancel) { event.preventDefault(); this.on_cancel(); } } }, apply: function(obj) { $.extend(obj, this.mixin); } }; }; return {}; });