From 1f56c4e5bb816ca5e952b326917c02984d69b88a Mon Sep 17 00:00:00 2001 From: Petr Vobornik Date: Tue, 17 Apr 2012 16:10:22 +0200 Subject: [PATCH] Control buttons Control buttons is a widget which contains action buttons. It is located in facet header and are supposed to replace old action buttons created by IPA.action_button(spec) call. The benefit is that now it is possible to define new buttons declaratively in spec definition without a need of inheriting facet and overriding create method. Action buttons are an entry poing for execution facet-wide action so they are tightly bound to facet. Action button options: name: string label: string, human readable label tooltip: string, human readable tooltip href: string, optional icon: string, icon class needs_confirm: boolean, default false confirm_msg: string, human readable confirmation message confirm_dialog: confirmation dialog, optional, custom confirmation dialog action: action, action which will be executed enabled: boolean, optional, default true Control buttons are define in facet spec in control_buttons property. Its a spec object with following attributes: all attributes which normal widget can have buttons: array of action_button specs state_listeners: array of state listener specs In init phase control_buttons_widget should assign a action_button a facet. control_buttons_widget are resposible for evaluation of action_button disable/enable state because they contain state_listeners which creates the state upon the enabled/disabled state is evaluated. State listeners are similar to state_evaluators. The differce is that the state is not evaluated from record set but from facet itself. The execution of evaluation is bound to a facet event. https://fedorahosted.org/freeipa/ticket/2247 --- install/ui/facet.js | 276 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 275 insertions(+), 1 deletion(-) diff --git a/install/ui/facet.js b/install/ui/facet.js index 5e78d57f6..80e977b41 100644 --- a/install/ui/facet.js +++ b/install/ui/facet.js @@ -25,7 +25,7 @@ /* REQUIRES: ipa.js, details.js, search.js, add.js */ -IPA.facet = function(spec) { +IPA.facet = function(spec, no_init) { spec = spec || {}; @@ -104,6 +104,13 @@ IPA.facet = function(spec) { that.create_content = function(container) { }; + that.create_control_buttons = function(container) { + + if (that.control_buttons) { + that.control_buttons.create(container); + } + }; + that.set_title = function(container, title) { var element = $('h1', that.title_container); element.html(title); @@ -289,6 +296,23 @@ IPA.facet = function(spec) { } }; + that.init_facet = function() { + + var buttons_spec = { + factory: IPA.control_buttons_widget, + name: 'control-buttons', + 'class': 'control-buttons' + }; + + if (spec.control_buttons) { + $.extend(buttons_spec, spec.control_buttons); + } + + that.control_buttons = IPA.build(buttons_spec); + that.control_buttons.init(that); + }; + + if (!no_init) that.init_facet(); // methods that should be invoked by subclasses that.facet_create = that.create; @@ -1226,6 +1250,256 @@ IPA.state_evaluator = function(spec) { return that; }; +IPA.state_listener = function(spec) { + + spec = spec || {}; + + var that = {}; + + that.event_name = spec.event; + that.state_changed = IPA.observer(); + that.state = []; + + that.init = function(facet) { + + if (that.event_name && facet[that.event_name]) { + facet[that.event_name].attach(that.on_event); + } + }; + + that.on_event = function() { + that.state_changed.notify(); + }; + + that.get_description = function() { + return that.description || ''; + }; + + return that; +}; + +IPA.state_listener_builder = function(spec) { + + spec = spec || {}; + spec.factory = spec.factory || IPA.state_listener; + var that = IPA.builder(spec); + return that; +}; + +IPA.dirty_state_listener = function(spec) { + + spec = spec || {}; + + spec.event = spec.event || 'dirty_changed'; + + var that = IPA.state_listener(spec); + + that.on_event = function(dirty) { + that.state = []; + + if (dirty) { + that.state.push('dirty'); + } + + that.state_changed.notify(); + }; + + return that; +}; + +IPA.action_button_widget = function(spec) { + + spec = spec || {}; + + var that = IPA.widget(spec); + + that.name = spec.name; + that.label = spec.label; + that.tooltip = spec.tooltip; + that.href = spec.href || that.name; + that.icon = spec.icon; + + that.needs_confirm = spec.needs_confirm !== undefined ? spec.needs_confirm : false; + that.confirm_msg = spec.confirm_msg || IPA.messages.actions.confirm; + that.confirm_dialog = spec.confirm_dialog; + + that.action = IPA.build(spec.action, IPA.action_builder); + that.enabled = spec.enabled !== undefined ? spec.enabled : true; + + that.create = function(container) { + + that.widget_create(container); + + that.button_element = IPA.action_button({ + name: that.name, + href: that.href, + label: that.label, + icon: that.icon, + click: function() { + that.on_click(); + return false; + } + }).appendTo(container); + + that.set_enabled(that.enabled); + }; + + that.on_click = function() { + + if (!that.enabled) return; + + if (that.needs_confirm) { + + var confirmed = false; + + if (that.confirm_dialog) { + + var dialog = IPA.build(that.confirm_dialog); + confirmed = dialog.confirm(that.facet); + } else { + var msg = that.get_confirm_message(); + confirmed = IPA.confirm(msg); + } + + if (!confirmed) return; + } + + that.execute_action(); + }; + + that.get_confirm_message = function() { + return that.confirm_msg; + }; + + that.execute_action = function() { + + if (that.action) { + that.action.execute(that.facet); + } + }; + + that.set_enabled = function(enabled) { + that.enabled = enabled; + + if (that.button_element) { + if (enabled) { + that.button_element.removeClass('action-button-disabled'); + } else { + that.button_element.addClass('action-button-disabled'); + } + } + }; + + return that; +}; + +IPA.action_button_widget_builder = function(spec) { + + spec = spec || {}; + spec.factory = spec.factory || IPA.action_button_widget; + var that = IPA.builder(spec); + return that; +}; + +IPA.control_buttons_widget = function(spec) { + + + spec = spec || {}; + + var that = IPA.widget(spec); + + that.buttons = IPA.build(spec.buttons, IPA.action_button_widget_builder) || []; + that.state_listeners = IPA.build(spec.state_listeners, IPA.state_listener_builder) || []; + that.state = []; + + that.init = function(facet) { + + var i; + + for (i=0; i', { + 'class': that['class'] + }).appendTo(container); + + for (var i=0; i -1) { + return false; + } + } + } + + if (action.enable_cond) { + for (i=0; i